├── .gitignore └── rtl ├── myCPU ├── alu_op.h ├── README.txt ├── rf.v ├── interlayer_cpu_mem.v ├── IF.v ├── alu.v ├── forward.v ├── exception.v ├── WB.v ├── EX.v ├── DE.v ├── MA.v ├── mul_div.v ├── cache.v ├── decoder.v ├── mycpu_top.v ├── icache.v └── dcache.v └── xilinx_ip └── ctrlBlk └── ctrlBlk.xci /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | Note.txt 3 | -------------------------------------------------------------------------------- /rtl/myCPU/alu_op.h: -------------------------------------------------------------------------------- 1 | `define OP_NUM 11 2 | 3 | `define OP_ADD 11'b00000000001 4 | `define OP_SUB 11'b00000000010 5 | `define OP_AND 11'b00000000100 6 | `define OP_OR 11'b00000001000 7 | `define OP_XOR 11'b00000010000 8 | `define OP_NOR 11'b00000100000 9 | `define OP_SLTS 11'b00001000000 10 | `define OP_SLTU 11'b00010000000 11 | //for operations below, the 1-st operand of shift operation is B, A is the 2-nd 12 | `define OP_SLL 11'b00100000000 13 | `define OP_SRL 11'b01000000000 14 | `define OP_SRA 11'b10000000000 15 | -------------------------------------------------------------------------------- /rtl/myCPU/README.txt: -------------------------------------------------------------------------------- 1 | mycpu_top.v:实例化并连接各模块 2 | |--cpu_axi_interface:将类sram信号转换为axi信号 3 | |--IF.v:IF级,发出取指请求,管理 PC寄存器 4 | |--DE.v:DE级,接受指令,管理 IR寄存器,对指令进行译码,完成分支指令对 PC的修改 5 | |--decoder.v:译码模块,将指令译码成控制信号 6 | |--EX.v:EX级,进行 alu 的运算,发出乘除法请求 7 | |--alu.v:算数逻辑单元,进行算术逻辑运算 8 | |--MA.v:MA级,接受乘除法结果,管理 HI和 LO寄存器,发出内存读写请求 9 | |--WB.v:WB级,接受读内存的结果,发出写寄存器堆请求 10 | |--interlayer_cpu_mem.v:将sram信号转换为类sram信号 11 | |--forward.v:解决数据相关 12 | |--rf.v:寄存器堆 13 | |--mul_div.v:乘除法模块,进行乘除法运算 14 | |--exception.v: 异常处理模块,完成异常提交时的处理 -------------------------------------------------------------------------------- /rtl/myCPU/rf.v: -------------------------------------------------------------------------------- 1 | module rf # 2 | ( 3 | parameter DATA_WIDTH = 32, 4 | parameter ADDR_WIDTH = 5, 5 | parameter NUM_REG = 32 6 | ) 7 | ( 8 | input clk, 9 | input rst_p, 10 | input [ADDR_WIDTH - 1 : 0] raddr1, 11 | input [ADDR_WIDTH - 1 : 0] raddr2, 12 | output [DATA_WIDTH - 1 : 0] rdata1, 13 | output [DATA_WIDTH - 1 : 0] rdata2, 14 | input wen, 15 | input [ADDR_WIDTH - 1 : 0] waddr, 16 | input [DATA_WIDTH - 1 : 0] wdata 17 | ); 18 | 19 | reg [DATA_WIDTH - 1 : 0] data [NUM_REG - 1 : 0]; 20 | 21 | assign rdata1 = data[raddr1]; 22 | assign rdata2 = data[raddr2]; 23 | 24 | always @(posedge clk) 25 | begin 26 | if(rst_p) 27 | data[0] <= 0; 28 | else ; 29 | 30 | if( (!rst_p && wen) && waddr ) 31 | data[waddr] <= wdata; 32 | else ; 33 | end 34 | 35 | endmodule 36 | -------------------------------------------------------------------------------- /rtl/myCPU/interlayer_cpu_mem.v: -------------------------------------------------------------------------------- 1 | module interlayer( 2 | input clk, 3 | input rst_p, 4 | 5 | //IF 6 | input IF_enable, 7 | input IF_skip, 8 | output interlayer_IF_ready, 9 | input [31 : 0] IF_mem_addr, 10 | output [31 : 0] IF_mem_rdata, 11 | 12 | //inst sram_like 13 | output inst_req, 14 | output [31 : 0] inst_addr, 15 | input [31 : 0] inst_rdata, 16 | input inst_addr_ok, 17 | input inst_data_ok, 18 | 19 | //WB 20 | input MA_mem_read, 21 | input MA_mem_write, 22 | output interlayer_MA_ready, 23 | output interlayer_WB_ready, 24 | input [ 3 : 0] MA_mem_wstrb, 25 | input [31 : 0] MA_mem_addr, 26 | input [ 2 : 0] MA_mem_size, 27 | input [31 : 0] MA_mem_wdata, 28 | output [31 : 0] WB_mem_rdata, 29 | 30 | //data sram_like 31 | output data_req, 32 | output data_wr, 33 | output [31 : 0] data_addr, 34 | output [ 2 : 0] data_size, 35 | output [ 3 : 0] data_wstrb, 36 | output [31 : 0] data_wdata, 37 | input [31 : 0] data_rdata, 38 | input data_data_ok, 39 | input data_write_ok 40 | ); 41 | 42 | reg inst_undone; 43 | always @(posedge clk) 44 | begin 45 | if(rst_p) inst_undone <= 1'd0; 46 | else inst_undone <= inst_undone + inst_addr_ok - inst_data_ok; 47 | end 48 | 49 | reg skip_state; 50 | always @(posedge clk) 51 | begin 52 | if(rst_p) skip_state <= 1'd0; 53 | else if(IF_skip && inst_undone) skip_state <= 1'd1; 54 | else if(inst_addr_ok) skip_state <= 1'd0; 55 | else ; 56 | end 57 | 58 | assign interlayer_IF_ready = inst_data_ok && !skip_state && !IF_skip; 59 | assign IF_mem_rdata = inst_rdata; 60 | 61 | assign inst_req = IF_enable; 62 | assign inst_addr = IF_mem_addr; 63 | 64 | assign interlayer_MA_ready = data_write_ok; 65 | assign interlayer_WB_ready = data_data_ok; 66 | assign WB_mem_rdata = data_rdata; 67 | 68 | assign data_req = MA_mem_read || MA_mem_write; 69 | assign data_wr = MA_mem_write; 70 | assign data_addr = MA_mem_addr; 71 | assign data_size = MA_mem_size; 72 | assign data_wstrb = MA_mem_wstrb; 73 | assign data_wdata = MA_mem_wdata; 74 | 75 | endmodule 76 | -------------------------------------------------------------------------------- /rtl/myCPU/IF.v: -------------------------------------------------------------------------------- 1 | module IF( 2 | input clk, 3 | input rst_p, 4 | input empty, 5 | 6 | //pipeline signals 7 | input interlayer_ready, 8 | output IF_enable, 9 | output IF_ready, 10 | input DE_enable, 11 | 12 | //memory access signals 13 | output IF_skip, 14 | output [31 : 0] IF_mem_addr, 15 | input [31 : 0] IF_mem_rdata, 16 | 17 | //interact with DE 18 | input eret, 19 | input PC_modified, 20 | input [31 : 0] PC_modified_data, 21 | output [31 : 0] IF_PC, 22 | output [31 : 0] inst_out, 23 | 24 | output [4 : 0] exccode_out, 25 | 26 | //interact with exception 27 | input exception, 28 | input [31 : 0] exception_handler_entry, 29 | input [31 : 0] epc 30 | ); 31 | 32 | reg valid; 33 | 34 | always @(posedge clk) 35 | begin 36 | if(rst_p) valid <= 1'd1; 37 | else ; 38 | end 39 | 40 | assign IF_enable = (valid && DE_enable) || exception; 41 | assign IF_ready = valid && interlayer_ready; 42 | 43 | reg [31 : 0] PC; 44 | 45 | always @(posedge clk) 46 | begin 47 | if(rst_p) PC <= 32'hbfc0_0000; 48 | else if(exception) PC <= exception_handler_entry; 49 | else if(eret) PC <= epc; 50 | else if(interlayer_ready) PC <= PC_modified ? PC_modified_data + 32'd4 : 51 | PC_modified_r ? PC_modified_data_r : 52 | PC + 32'd4 ; 53 | else ; 54 | end 55 | 56 | reg PC_modified_r; 57 | reg [31 : 0] PC_modified_data_r; 58 | 59 | always @(posedge clk) 60 | begin 61 | if(rst_p || empty) 62 | PC_modified_r <= 1'd0; 63 | else if(PC_modified && !interlayer_ready) 64 | PC_modified_r <= 1'd1; 65 | else if(interlayer_ready || exception) 66 | PC_modified_r <= 1'd0; 67 | else ; 68 | 69 | if(PC_modified) 70 | PC_modified_data_r <= PC_modified_data; 71 | else ; 72 | end 73 | 74 | assign IF_skip = exception || empty; 75 | assign IF_mem_addr = exception ? exception_handler_entry : 76 | eret ? epc : 77 | interlayer_ready && PC_modified ? PC_modified_data : 78 | PC ; 79 | assign inst_out = IF_mem_rdata; 80 | 81 | assign IF_PC = interlayer_ready && PC_modified ? PC_modified_data : PC; 82 | assign exccode_out = (IF_PC[1:0] != 2'd0) ? 5'h04 : 5'h00; //AdEL 83 | 84 | endmodule 85 | -------------------------------------------------------------------------------- /rtl/myCPU/alu.v: -------------------------------------------------------------------------------- 1 | `include "alu_op.h" 2 | 3 | module alu # 4 | ( 5 | parameter DATA_WIDTH = 32 6 | ) 7 | ( 8 | input [DATA_WIDTH - 1 : 0] A, 9 | input [DATA_WIDTH - 1 : 0] B, 10 | input [`OP_NUM - 1 : 0] operation, 11 | output zero, 12 | output overflow, 13 | output [DATA_WIDTH - 1 : 0] result 14 | ); 15 | 16 | wire op_add = operation[0]; 17 | wire op_sub = operation[1]; 18 | wire op_and = operation[2]; 19 | wire op_or = operation[3]; 20 | wire op_xor = operation[4]; 21 | wire op_nor = operation[5]; 22 | wire op_slts = operation[6]; 23 | wire op_sltu = operation[7]; 24 | wire op_sll = operation[8]; 25 | wire op_srl = operation[9]; 26 | wire op_sra = operation[10]; 27 | 28 | wire [DATA_WIDTH - 1 : 0] and_result = A & B; 29 | wire [DATA_WIDTH - 1 : 0] or_result = A | B; 30 | wire [DATA_WIDTH - 1 : 0] xor_result = A ^ B; 31 | wire [DATA_WIDTH - 1 : 0] nor_result = ~or_result; 32 | 33 | wire subtract_flag = op_sub | op_slts | op_sltu; 34 | wire [DATA_WIDTH - 1 : 0] adder_A = A; 35 | wire [DATA_WIDTH - 1 : 0] adder_B = subtract_flag ? ~B : B; 36 | wire adder_cin = subtract_flag; 37 | wire adder_cout; 38 | wire [DATA_WIDTH - 1 : 0] adder_result; 39 | 40 | assign {adder_cout, adder_result} = adder_A + adder_B + adder_cin; 41 | 42 | wire different_signal = A[DATA_WIDTH - 1] ^ B[DATA_WIDTH - 1]; 43 | wire slts_result_1 = different_signal ? A[DATA_WIDTH - 1] : adder_result[DATA_WIDTH - 1]; 44 | wire [DATA_WIDTH - 1 : 0] slts_result = { {(DATA_WIDTH-1) {1'b0}}, slts_result_1 }; 45 | wire sltu_result_1 = subtract_flag ? ~adder_cout : adder_cout; 46 | wire [DATA_WIDTH - 1 : 0] sltu_result = { {(DATA_WIDTH-1) {1'b0}}, sltu_result_1 }; 47 | 48 | //operation below have inverse operand 49 | wire [DATA_WIDTH - 1 : 0] sll_result = B << A[4 : 0]; 50 | wire [DATA_WIDTH - 1 : 0] srl_result = B >> A[4 : 0]; 51 | wire [DATA_WIDTH - 1 : 0] sra_result = { {DATA_WIDTH{B[DATA_WIDTH - 1]}}, B } >> A[4:0]; 52 | 53 | assign result = ( {DATA_WIDTH {op_and }} & and_result ) | 54 | ( {DATA_WIDTH {op_or }} & or_result ) | 55 | ( {DATA_WIDTH {op_add }} & adder_result ) | 56 | ( {DATA_WIDTH {op_sub }} & adder_result ) | 57 | ( {DATA_WIDTH {op_slts}} & slts_result ) | 58 | ( {DATA_WIDTH {op_sltu}} & sltu_result ) | 59 | ( {DATA_WIDTH {op_nor }} & nor_result ) | 60 | ( {DATA_WIDTH {op_xor }} & xor_result ) | 61 | ( {DATA_WIDTH {op_sll }} & sll_result ) | 62 | ( {DATA_WIDTH {op_srl }} & srl_result ) | 63 | ( {DATA_WIDTH {op_sra }} & sra_result ) ; 64 | 65 | assign zero = (result == 32'd0); 66 | assign overflow = (different_signal ? op_sub : op_add) & 67 | (adder_result[DATA_WIDTH - 1] ^ A[DATA_WIDTH - 1]); 68 | 69 | endmodule 70 | -------------------------------------------------------------------------------- /rtl/myCPU/forward.v: -------------------------------------------------------------------------------- 1 | module forward( 2 | input clk, 3 | input rst_p, 4 | input empty, 5 | 6 | input [4 : 0] EX_rf_waddr, 7 | input [4 : 0] MA_rf_waddr, 8 | input [4 : 0] WB_rf_waddr, 9 | 10 | input EX_rf_wen, 11 | input MA_rf_wen, 12 | input WB_rf_wen, 13 | 14 | input EX_valid, 15 | input MA_valid, 16 | input WB_valid, 17 | 18 | input MA_leaving, 19 | input WB_leaving, 20 | 21 | input EX_mem_read, 22 | input MA_mem_read, 23 | input EX_mf, 24 | 25 | input [31 : 0] EX_alu_res, 26 | input [31 : 0] MA_alu_res, 27 | input [31 : 0] WB_rf_wdata, 28 | 29 | output [ 4 : 0] rf_raddr1, 30 | output [ 4 : 0] rf_raddr2, 31 | input [31 : 0] rf_rdata1, 32 | input [31 : 0] rf_rdata2, 33 | 34 | input [ 4 : 0] raddr1, 35 | input [ 4 : 0] raddr2, 36 | output [31 : 0] rdata1, 37 | output [31 : 0] rdata2, 38 | 39 | output waiting, 40 | input isbr 41 | ); 42 | 43 | assign rf_raddr1 = raddr1; 44 | assign rf_raddr2 = raddr2; 45 | 46 | wire [2 : 0]clash_EX; 47 | wire [2 : 0]clash_MA; 48 | wire [2 : 0]clash_WB; 49 | 50 | assign clash_EX[1] = EX_valid && EX_rf_wen && (raddr1 != 5'd0) && (raddr1 == EX_rf_waddr); 51 | assign clash_EX[2] = EX_valid && EX_rf_wen && (raddr2 != 5'd0) && (raddr2 == EX_rf_waddr); 52 | assign clash_EX[0] = clash_EX[1] || clash_EX[2]; 53 | 54 | assign clash_MA[1] = MA_valid && MA_rf_wen && (raddr1 != 5'd0) && (raddr1 == MA_rf_waddr); 55 | assign clash_MA[2] = MA_valid && MA_rf_wen && (raddr2 != 5'd0) && (raddr2 == MA_rf_waddr); 56 | assign clash_MA[0] = clash_MA[1] || clash_MA[2]; 57 | 58 | assign clash_WB[1] = WB_valid && WB_rf_wen && (raddr1 != 5'd0) && (raddr1 == WB_rf_waddr); 59 | assign clash_WB[2] = WB_valid && WB_rf_wen && (raddr2 != 5'd0) && (raddr2 == WB_rf_waddr); 60 | assign clash_WB[0] = clash_WB[1] || clash_WB[2]; 61 | 62 | wire waiting_br = (clash_EX[0] || clash_MA[0] || clash_WB[0]) && isbr; 63 | wire waiting_EX_load = EX_mem_read && clash_EX[0]; //2 cycles, fetch from WB_wf_wdata 64 | wire waiting_MA_load = MA_mem_read && clash_MA[0]; //1 cycle, fetch from WB_wf_wdata 65 | wire waiting_EX_mf = EX_mf && clash_EX[0]; //1 cycle, fetch from MA_alu_res 66 | wire waiting_WB = !WB_leaving && clash_WB[0]; 67 | reg [1 : 0] wait_cycle; //not clock cycle, but pipeline cycle 68 | 69 | always @(posedge clk) 70 | begin 71 | if(rst_p || empty) wait_cycle <= 2'd0; 72 | else if(wait_cycle == 2'd0) 73 | begin 74 | if(waiting_MA_load && !MA_leaving) 75 | wait_cycle <= 2'd1; 76 | else if(waiting_EX_mf && !MA_leaving && MA_valid) 77 | wait_cycle <= 2'd1; 78 | else if(waiting_EX_load) 79 | wait_cycle <= (MA_leaving || !MA_valid) ? 2'd1 : 2'd2; 80 | else ; 81 | end 82 | else wait_cycle <= wait_cycle - {1'b0, MA_leaving}; 83 | end 84 | 85 | assign waiting = !empty && (waiting_br || waiting_EX_load || waiting_MA_load || waiting_EX_mf || (wait_cycle != 2'd0) || waiting_WB); 86 | 87 | assign rdata1 = clash_EX[1] ? EX_alu_res : 88 | clash_MA[1] ? MA_alu_res : 89 | clash_WB[1] ? WB_rf_wdata : 90 | rf_rdata1 ; 91 | 92 | assign rdata2 = clash_EX[2] ? EX_alu_res : 93 | clash_MA[2] ? MA_alu_res : 94 | clash_WB[2] ? WB_rf_wdata : 95 | rf_rdata2 ; 96 | 97 | endmodule 98 | -------------------------------------------------------------------------------- /rtl/myCPU/exception.v: -------------------------------------------------------------------------------- 1 | `define CP0_BADVADDR 8 2 | `define CP0_COUNT 9 3 | `define CP0_COMPARE 11 4 | `define CP0_STATUS 12 5 | `define CP0_CAUSE 13 6 | `define CP0_EPC 14 7 | 8 | module exception( 9 | input clk, 10 | input rst_p, 11 | 12 | input [5 : 0] hw_int, 13 | 14 | input MA_leaving, 15 | input MA_valid, 16 | input [6 : 2] MA_exccode, 17 | input MA_eret, 18 | input [31 : 0] MA_PC, 19 | input [31 : 0] MA_alu_res, 20 | 21 | input WB_enable, 22 | 23 | output exception, 24 | output [31 : 0] exception_handler_entry, 25 | output [31 : 0] epc_out, 26 | 27 | input in_delay_slot, 28 | input address_error_IF, 29 | 30 | input [4 : 0] cp0_raddr, 31 | output [31 : 0] cp0_rdata, 32 | 33 | input cp0_wen, 34 | input [4 : 0] cp0_waddr, 35 | input [31 : 0] cp0_wdata 36 | ); 37 | 38 | //-----CP0_REGS----- 39 | reg [31 : 0] badvaddr; 40 | reg [31 : 0] count; 41 | reg [31 : 0] compare; 42 | reg [31 : 0] epc; 43 | 44 | wire [22 : 22] status_bev = 1'b1; 45 | reg [15 : 8] status_im; 46 | reg [ 1 : 1] status_exl; 47 | reg [ 0 : 0] status_ie; 48 | 49 | wire [31 : 0] status = {9'd0, status_bev, 6'd0, status_im, 6'd0, status_exl, status_ie}; 50 | 51 | reg [31 : 31] cause_bd; 52 | reg [30 : 30] cause_ti; 53 | reg [15 : 8] cause_ip; 54 | reg [ 6 : 2] cause_exccode; 55 | 56 | wire [31 : 0] cause = {cause_bd, cause_ti, 14'd0, cause_ip, 1'd0, cause_exccode, 2'd0}; 57 | //-----CP0_REGS----- 58 | 59 | assign epc_out = epc; 60 | 61 | wire int_taken = !status_exl && status_ie && 62 | ( ({hw_int[5] | cause_ti, hw_int[4:0], cause_ip[9:8]} & status_im) != 8'd0 ); 63 | assign exception = WB_enable && MA_valid && (int_taken || (MA_exccode != 5'd0)); 64 | 65 | assign exception_handler_entry = 32'hbfc0_0380; 66 | 67 | assign cp0_rdata = ( {32{( cp0_raddr == `CP0_BADVADDR )}} & badvaddr ) | 68 | ( {32{( cp0_raddr == `CP0_COUNT )}} & count ) | 69 | ( {32{( cp0_raddr == `CP0_COMPARE )}} & compare ) | 70 | ( {32{( cp0_raddr == `CP0_STATUS )}} & status ) | 71 | ( {32{( cp0_raddr == `CP0_CAUSE )}} & cause ) | 72 | ( {32{( cp0_raddr == `CP0_EPC )}} & epc ) ; 73 | 74 | //todo : if-else 75 | always @(posedge clk) 76 | begin 77 | if(rst_p) 78 | begin 79 | status_im <= 8'd0; 80 | status_exl <= 1'd0; 81 | status_ie <= 1'd0; 82 | cause_bd <= 1'd0; 83 | cause_ip <= 8'd0; 84 | end 85 | else if(exception) 86 | begin 87 | cause_bd <= in_delay_slot; 88 | cause_exccode <= int_taken ? 5'd0 : MA_exccode; 89 | status_exl <= 1'd1; 90 | epc <= in_delay_slot ? MA_PC - 32'd4 : MA_PC; 91 | cause_ip[15:10] <= {hw_int[5] | cause_ti, hw_int[4:0]}; 92 | if(MA_exccode == 5'h04 || MA_exccode == 5'h05) 93 | badvaddr <= address_error_IF ? MA_PC : MA_alu_res; 94 | else ; 95 | end 96 | else if(MA_eret && MA_leaving) 97 | begin 98 | status_exl <= 1'b0; 99 | end 100 | else if(cp0_wen && MA_leaving) 101 | begin 102 | if(cp0_waddr == `CP0_COMPARE) 103 | compare <= cp0_wdata; 104 | else if(cp0_waddr == `CP0_STATUS) 105 | begin 106 | status_im <= cp0_wdata[15:8]; 107 | status_exl <= cp0_wdata[1]; 108 | status_ie <= cp0_wdata[0]; 109 | end 110 | else if(cp0_waddr == `CP0_CAUSE) 111 | cause_ip[9:8] <= cp0_wdata[9:8]; 112 | else if(cp0_waddr == `CP0_EPC) 113 | epc <= cp0_wdata; 114 | else ; 115 | end 116 | else ; 117 | 118 | if(rst_p) 119 | cause_ti <= 1'd0; 120 | else if(cp0_wen && MA_leaving && cp0_waddr == `CP0_COMPARE) 121 | cause_ti <= 1'd0; 122 | else if(count == compare) 123 | cause_ti <= 1'd1; 124 | else ; 125 | end 126 | 127 | reg count_add_flag; 128 | 129 | always @(posedge clk) 130 | begin 131 | if(rst_p) 132 | count_add_flag <= 1'd0; 133 | else if(cp0_wen && MA_leaving && cp0_waddr == `CP0_COUNT) 134 | count_add_flag <= 1'd0; 135 | else 136 | count_add_flag <= !count_add_flag; 137 | end 138 | 139 | always @(posedge clk) 140 | begin 141 | if(cp0_wen && MA_leaving && cp0_waddr == `CP0_COUNT) 142 | count <= cp0_wdata; 143 | else 144 | count <= count + {31'd0, count_add_flag}; 145 | end 146 | 147 | endmodule 148 | -------------------------------------------------------------------------------- /rtl/myCPU/WB.v: -------------------------------------------------------------------------------- 1 | module WB( 2 | input clk, 3 | input rst_p, 4 | input empty, 5 | 6 | //pipeline signals 7 | input MA_ready, 8 | output WB_enable, 9 | 10 | //interact with MA 11 | input [31 : 0] rf_B_in, 12 | input [ 4 : 0] rf_waddr_in, 13 | input [ 2 : 0] rf_wdata_src_in, 14 | input rf_wen_in, 15 | input [31 : 0] alu_res_in, 16 | input mem_read_in, 17 | input [6 : 0] align_load_in, 18 | 19 | input [31 : 0] MA_PC, 20 | 21 | //interact with interlayer 22 | input interlayer_ready, 23 | input [31 : 0] mem_data, 24 | 25 | //interact with rf 26 | output [ 4 : 0] rf_waddr_out, 27 | output [31 : 0] rf_wdata_out, 28 | output rf_wen_leaving, 29 | 30 | //interact with debug 31 | output [31 : 0] debug_PC, 32 | output [ 3 : 0] debug_wb_rf_wen, 33 | output [ 4 : 0] debug_wb_rf_waddr, 34 | output [31 : 0] debug_wb_rf_wdata, 35 | 36 | //interact with forward 37 | output rf_wen_out, 38 | output leaving_out, 39 | output valid_out 40 | ); 41 | 42 | reg valid; 43 | assign valid_out = valid; 44 | 45 | reg [31 : 0] rf_B; 46 | reg [ 4 : 0] rf_waddr; 47 | reg [ 2 : 0] rf_wdata_src; 48 | reg rf_wen; 49 | reg [31 : 0] alu_res; 50 | reg mem_read; 51 | reg [6 : 0] align_load; 52 | reg [31 : 0] WB_PC; 53 | 54 | reg [31 : 0] mem_data_reg; 55 | reg interlayer_ready_reg; 56 | 57 | always @(posedge clk) 58 | begin 59 | if(rst_p) interlayer_ready_reg <= 1'd0; 60 | else interlayer_ready_reg <= interlayer_ready; 61 | 62 | if(mem_read && interlayer_ready) 63 | mem_data_reg <= mem_data; 64 | end 65 | 66 | wire comming = WB_enable && MA_ready; 67 | wire leaving = valid && (mem_read ? interlayer_ready_reg : 1'd1); 68 | 69 | assign leaving_out = leaving; 70 | 71 | always @(posedge clk) 72 | begin 73 | if(rst_p) valid <= 1'd0; 74 | else if(comming) valid <= 1'd1; 75 | else if(leaving) valid <= 1'd0; 76 | else ; 77 | end 78 | 79 | assign WB_enable = !valid || leaving; 80 | 81 | always @(posedge clk) 82 | begin 83 | if(comming) 84 | begin 85 | rf_B <= rf_B_in; 86 | 87 | rf_waddr <= rf_waddr_in; 88 | rf_wdata_src <= rf_wdata_src_in; 89 | rf_wen <= rf_wen_in; 90 | 91 | alu_res <= alu_res_in; 92 | 93 | mem_read <= mem_read_in; 94 | align_load <= align_load_in; 95 | 96 | WB_PC <= MA_PC; 97 | end 98 | else ; 99 | end 100 | 101 | assign rf_wen_out = rf_wen; 102 | 103 | wire [3 : 0] alu_res_align = {alu_res[1:0] == 2'b11, alu_res[1:0] == 2'b10, 104 | alu_res[1:0] == 2'b01, alu_res[1:0] == 2'b00}; 105 | wire [31 : 0] rf_lw_data = mem_data_reg; 106 | wire [31 : 0] rf_lb_data = ( {32{alu_res_align[2'b00]}} & { {24{mem_data_reg[ 7]}}, mem_data_reg[ 7 : 0] } ) | 107 | ( {32{alu_res_align[2'b01]}} & { {24{mem_data_reg[15]}}, mem_data_reg[15 : 8] } ) | 108 | ( {32{alu_res_align[2'b10]}} & { {24{mem_data_reg[23]}}, mem_data_reg[23 : 16] } ) | 109 | ( {32{alu_res_align[2'b11]}} & { {24{mem_data_reg[31]}}, mem_data_reg[31 : 24] } ) ; 110 | wire [31 : 0] rf_lbu_data = ( {32{alu_res_align[2'b00]}} & { 24'd0, mem_data_reg[ 7 : 0] } ) | 111 | ( {32{alu_res_align[2'b01]}} & { 24'd0, mem_data_reg[15 : 8] } ) | 112 | ( {32{alu_res_align[2'b10]}} & { 24'd0, mem_data_reg[23 : 16] } ) | 113 | ( {32{alu_res_align[2'b11]}} & { 24'd0, mem_data_reg[31 : 24] } ) ; 114 | wire [31 : 0] rf_lh_data = ( {32{~alu_res[1]}} & { {16{mem_data_reg[15]}}, mem_data_reg[15 : 0] } ) | 115 | ( {32{ alu_res[1]}} & { {16{mem_data_reg[31]}}, mem_data_reg[31 : 16] } ) ; 116 | wire [31 : 0] rf_lhu_data = ( {32{~alu_res[1]}} & { 16'd0, mem_data_reg[15 : 0] } ) | 117 | ( {32{ alu_res[1]}} & { 16'd0, mem_data_reg[31 : 16] } ) ; 118 | wire [31 : 0] rf_lwl_data = ( {32{alu_res_align[2'b00]}} & { mem_data_reg[ 7 : 0], rf_B[23 : 0] } ) | 119 | ( {32{alu_res_align[2'b01]}} & { mem_data_reg[15 : 0], rf_B[15 : 0] } ) | 120 | ( {32{alu_res_align[2'b10]}} & { mem_data_reg[23 : 0], rf_B[ 7 : 0] } ) | 121 | ( {32{alu_res_align[2'b11]}} & mem_data_reg) ; 122 | wire [31 : 0] rf_lwr_data = ( {32{alu_res_align[2'b00]}} & mem_data_reg) | 123 | ( {32{alu_res_align[2'b01]}} & { rf_B[31 : 24], mem_data_reg[31 : 8] } ) | 124 | ( {32{alu_res_align[2'b10]}} & { rf_B[31 : 16], mem_data_reg[31 : 16] } ) | 125 | ( {32{alu_res_align[2'b11]}} & { rf_B[31 : 8], mem_data_reg[31 : 24] } ) ; 126 | wire [31 : 0] rf_mem_data = ( {32{align_load[6]}} & rf_lw_data ) | 127 | ( {32{align_load[5]}} & rf_lb_data ) | 128 | ( {32{align_load[4]}} & rf_lbu_data ) | 129 | ( {32{align_load[3]}} & rf_lh_data ) | 130 | ( {32{align_load[2]}} & rf_lhu_data ) | 131 | ( {32{align_load[1]}} & rf_lwl_data ) | 132 | ( {32{align_load[0]}} & rf_lwr_data ) ; 133 | 134 | assign rf_wen_leaving = rf_wen && leaving; 135 | assign rf_waddr_out = rf_waddr; 136 | assign rf_wdata_out = ( {32{rf_wdata_src[0]}} & alu_res ) | 137 | ( {32{rf_wdata_src[1]}} & alu_res ) | 138 | ( {32{rf_wdata_src[2]}} & rf_mem_data ) ; 139 | 140 | assign debug_PC = WB_PC; 141 | assign debug_wb_rf_wen = {4{rf_wen_leaving}}; 142 | assign debug_wb_rf_waddr = rf_waddr; 143 | assign debug_wb_rf_wdata = rf_wdata_out; 144 | 145 | endmodule 146 | -------------------------------------------------------------------------------- /rtl/myCPU/EX.v: -------------------------------------------------------------------------------- 1 | `include "alu_op.h" 2 | 3 | module EX( 4 | input clk, 5 | input rst_p, 6 | input empty, 7 | 8 | //pipeline signals 9 | input DE_ready, 10 | output EX_enable, 11 | output EX_ready, 12 | input MA_enable, 13 | 14 | //interact with DE 15 | input [4 : 0] rf_waddr_in, 16 | input [2 : 0] rf_wdata_src_in, 17 | input rf_wen_in, 18 | 19 | input [2 : 0] alu_src1_in, 20 | input [2 : 0] alu_src2_in, 21 | input [`OP_NUM - 1 : 0] alu_op_in, 22 | input [1 : 0] mf_hi_lo_in, 23 | input [1 : 0] mt_hi_lo_in, 24 | input [2 : 0] mul_div_in, 25 | 26 | input mem_read_in, 27 | input mem_write_in, 28 | input [6 : 0] align_load_in, 29 | input [4 : 0] align_store_in, 30 | 31 | input eret_in, 32 | input mfc0_in, 33 | input mtc0_in, 34 | 35 | input [15 : 0] imm_16_in, 36 | 37 | input [31 : 0] rf_A_in, 38 | input [31 : 0] rf_B_in, 39 | 40 | input [31 : 0] DE_PC, 41 | 42 | input in_delay_slot_in, 43 | input address_error_IF_in, 44 | input overflow_exception_in, 45 | input [4 : 0] exccode_in, 46 | 47 | //interact with MA && mul_div 48 | output [4 : 0] inst_rd_out, 49 | 50 | output [31 : 0] rf_A_out, 51 | output [31 : 0] rf_B_out, 52 | 53 | output [4 : 0] rf_waddr_out, 54 | output [2 : 0] rf_wdata_src_out, 55 | output rf_wen_out, 56 | 57 | output [1 : 0] mf_hi_lo_out, 58 | output [1 : 0] mt_hi_lo_out, 59 | output [2 : 0] mul_div_out, 60 | 61 | output mem_read_out, 62 | output mem_write_out, 63 | output [6 : 0] align_load_out, 64 | output [4 : 0] align_store_out, 65 | 66 | output eret_out, 67 | output mfc0_out, 68 | output mtc0_out, 69 | 70 | output [31 : 0] alu_res_out, 71 | 72 | output reg [31 : 0] EX_PC, 73 | 74 | output in_delay_slot_out, 75 | output address_error_IF_out, 76 | output [4 : 0] exccode_out, 77 | 78 | //interact with forward 79 | output valid_out 80 | ); 81 | 82 | reg valid; 83 | assign valid_out = valid; 84 | 85 | wire comming = EX_enable && DE_ready; 86 | wire leaving = MA_enable && EX_ready; 87 | 88 | always @(posedge clk) 89 | begin 90 | if(rst_p || empty) valid <= 1'd0; 91 | else if(comming) valid <= 1'd1; 92 | else if(leaving) valid <= 1'd0; 93 | else ; 94 | end 95 | 96 | assign EX_enable = !valid || leaving; 97 | assign EX_ready = valid && ~empty; 98 | 99 | reg [4 : 0] rf_waddr; 100 | reg [2 : 0] rf_wdata_src; 101 | reg rf_wen; 102 | 103 | reg [2 : 0] alu_src1; 104 | reg [2 : 0] alu_src2; 105 | reg [`OP_NUM - 1 : 0] alu_op; 106 | reg [1 : 0] mf_hi_lo; 107 | reg [1 : 0] mt_hi_lo; 108 | reg [2 : 0] mul_div; 109 | 110 | reg mem_read; 111 | reg mem_write; 112 | reg [6 : 0] align_load; 113 | reg [4 : 0] align_store; 114 | 115 | reg [15 : 0] imm_16; 116 | 117 | reg [31 : 0] rf_A; 118 | reg [31 : 0] rf_B; 119 | 120 | reg eret; 121 | reg mfc0; 122 | reg mtc0; 123 | 124 | reg in_delay_slot; 125 | reg address_error_IF; 126 | reg overflow_exception; 127 | reg [4 : 0] exccode; 128 | 129 | always @(posedge clk) 130 | begin 131 | if(comming) 132 | begin 133 | rf_waddr <= rf_waddr_in; 134 | rf_wdata_src <= rf_wdata_src_in; 135 | rf_wen <= rf_wen_in; 136 | 137 | alu_src1 <= alu_src1_in; 138 | alu_src2 <= alu_src2_in; 139 | alu_op <= alu_op_in; 140 | mt_hi_lo <= mt_hi_lo_in; 141 | mf_hi_lo <= mf_hi_lo_in; 142 | mul_div <= mul_div_in; 143 | 144 | mem_read <= mem_read_in; 145 | mem_write <= mem_write_in; 146 | align_load <= align_load_in; 147 | align_store <= align_store_in; 148 | 149 | eret <= eret_in; 150 | mfc0 <= mfc0_in; 151 | mtc0 <= mtc0_in; 152 | 153 | imm_16 <= imm_16_in; 154 | 155 | rf_A <= rf_A_in; 156 | rf_B <= rf_B_in; 157 | 158 | in_delay_slot <= in_delay_slot_in; 159 | address_error_IF <= address_error_IF_in; 160 | overflow_exception <= overflow_exception_in; 161 | exccode <= exccode_in; 162 | end 163 | else ; 164 | end 165 | 166 | assign inst_rd_out = imm_16[15 : 11]; 167 | wire [ 4 : 0] shamt = imm_16[10 : 6]; 168 | wire [31 : 0] alu_A = ( {32{alu_src1[0]}} & rf_A ) | 169 | ( {32{alu_src1[1]}} & {27'd0, shamt} ) | 170 | ( {32{alu_src1[2]}} & 32'd16 ) ; 171 | wire [31 : 0] imm_16_se = { {16{imm_16[15]}}, imm_16 }; 172 | wire [31 : 0] imm_16_ze = {16'd0, imm_16}; 173 | wire [31 : 0] alu_B = ( {32{alu_src2[0]}} & rf_B ) | 174 | ( {32{alu_src2[1]}} & imm_16_se ) | 175 | ( {32{alu_src2[2]}} & imm_16_ze ) ; 176 | wire overflow; 177 | wire [31 : 0] alu_res; 178 | 179 | alu alu( 180 | .A (alu_A), 181 | .B (alu_B), 182 | .operation (alu_op), 183 | .zero (), 184 | .overflow (overflow), 185 | .result (alu_res) 186 | ); 187 | 188 | assign rf_A_out = rf_A; 189 | assign rf_B_out = rf_B; 190 | 191 | assign rf_waddr_out = rf_waddr; 192 | assign rf_wdata_src_out = rf_wdata_src; 193 | assign rf_wen_out = rf_wen; 194 | 195 | assign mem_read_out = mem_read; 196 | assign mem_write_out = mem_write; 197 | assign align_load_out = align_load; 198 | assign align_store_out = align_store; 199 | 200 | assign eret_out = eret; 201 | assign mfc0_out = mfc0; 202 | assign mtc0_out = mtc0; 203 | 204 | assign alu_res_out = rf_wdata_src_out[1] ? (EX_PC + 32'd8) : alu_res; 205 | assign mf_hi_lo_out = mf_hi_lo; 206 | assign mt_hi_lo_out = mt_hi_lo; 207 | assign mul_div_out = mul_div & {3{leaving}}; 208 | 209 | wire overflow_exception_taken = overflow_exception && overflow; 210 | wire address_error_load = (align_load[6] && (alu_res[1:0] != 2'd0)) || //lw 211 | ((align_load[3] || align_load[2]) && (alu_res[0] != 1'd0)); //lh, lhu 212 | wire address_error_store = (align_store[4] && (alu_res[1:0] != 2'd0)) || //sw 213 | (align_store[2] && (alu_res[0] != 1'd0)) ; //sh 214 | 215 | assign in_delay_slot_out = in_delay_slot; 216 | assign address_error_IF_out = address_error_IF; 217 | assign exccode_out = (exccode != 5'h00) ? exccode : //AdEL(IF), RI, Sys, Bp 218 | (overflow_exception_taken) ? 5'h0c : //Ov 219 | (address_error_load) ? 5'h04 : //AdEL 220 | (address_error_store) ? 5'h05 : //AdES 221 | 5'h00 ; 222 | 223 | always @(posedge clk) 224 | begin 225 | if(comming) EX_PC <= DE_PC; 226 | else ; 227 | end 228 | 229 | endmodule 230 | -------------------------------------------------------------------------------- /rtl/myCPU/DE.v: -------------------------------------------------------------------------------- 1 | `include "alu_op.h" 2 | 3 | module DE( 4 | input clk, 5 | input rst_p, 6 | input empty, 7 | 8 | //pipeline signals 9 | input IF_ready, 10 | output DE_enable, 11 | output DE_ready, 12 | input EX_enable, 13 | 14 | //interact with IF 15 | input [31 : 0] inst_in, 16 | input [31 : 0] IF_PC, 17 | output PC_modified, 18 | output [31 : 0] PC_modified_data, 19 | input [4 : 0] exccode_in, 20 | 21 | //interact with forward 22 | input waiting, 23 | output isbr, 24 | output [ 4 : 0] rf_raddr1, 25 | output [ 4 : 0] rf_raddr2, 26 | input [31 : 0] rf_rdata1, 27 | input [31 : 0] rf_rdata2, 28 | input [31 : 0] drf_rdata1, 29 | input [31 : 0] drf_rdata2, 30 | 31 | //interact with EX 32 | output [4 : 0] rf_waddr_out, 33 | output [2 : 0] rf_wdata_src_out, 34 | output rf_wen_out, 35 | 36 | output [2 : 0] alu_src1_out, 37 | output [2 : 0] alu_src2_out, 38 | output [`OP_NUM - 1 : 0] alu_op_out, 39 | output [1 : 0] mf_hi_lo_out, 40 | output [1 : 0] mt_hi_lo_out, 41 | output [2 : 0] mul_div_out, 42 | 43 | output mem_read_out, 44 | output mem_write_out, 45 | output [6 : 0] align_load_out, 46 | output [4 : 0] align_store_out, 47 | 48 | output eret_out, 49 | output mfc0_out, 50 | output mtc0_out, 51 | 52 | output [15 : 0] imm_16_out, 53 | 54 | output [31 : 0] rf_A_out, 55 | output [31 : 0] rf_B_out, 56 | 57 | output reg [31 : 0] DE_PC, 58 | 59 | output in_delay_slot_out, 60 | output address_error_IF_out, 61 | output overflow_exception_out, 62 | output [4 : 0] exccode_out 63 | ); 64 | 65 | reg valid; 66 | 67 | wire comming = DE_enable && IF_ready; 68 | wire leaving = EX_enable && DE_ready; 69 | 70 | always @(posedge clk) 71 | begin 72 | if(rst_p || empty) valid <= 1'd0; 73 | else if(comming) valid <= 1'd1; 74 | else if(leaving) valid <= 1'd0; 75 | else ; 76 | end 77 | 78 | assign DE_enable = !valid || leaving; 79 | assign DE_ready = valid && !waiting && ~empty; 80 | 81 | reg [31 : 0] IR; 82 | 83 | always @(posedge clk) 84 | begin 85 | if(comming) IR <= inst_in; 86 | else ; 87 | end 88 | 89 | wire [31 : 0] inst = IR; 90 | wire [31 : 26] inst_opcode = inst[31 : 26]; 91 | wire [ 5 : 0] inst_func = inst[ 5 : 0]; 92 | wire [25 : 21] inst_rs = inst[25 : 21]; 93 | wire [20 : 16] inst_rt = inst[20 : 16]; 94 | wire [15 : 11] inst_rd = inst[15 : 11]; 95 | wire [15 : 0] inst_imm_16 = inst[15 : 0]; 96 | wire [25 : 0] inst_imm_26 = inst[25 : 0]; 97 | 98 | wire jump_reg_in; 99 | wire jump_imm_in; 100 | wire [4 : 0] branch_in; 101 | wire [2 : 0] rf_waddr_src_in; 102 | wire [2 : 0] rf_wdata_src_in; 103 | wire rf_wen_in; 104 | wire [2 : 0] alu_src1_in; 105 | wire [2 : 0] alu_src2_in; 106 | wire [`OP_NUM - 1 : 0] alu_op_in; 107 | wire [1 : 0] mf_hi_lo_in; 108 | wire [1 : 0] mt_hi_lo_in; 109 | wire [2 : 0] mul_div_in; 110 | wire mem_read_in; 111 | wire mem_write_in; 112 | wire [6 : 0] align_load_in; 113 | wire [4 : 0] align_store_in; 114 | wire eret_in; 115 | wire mfc0_in; 116 | wire mtc0_in; 117 | wire [1 : 0] trap_in; 118 | wire overflow_exception_in; 119 | wire reserved_inst_in; 120 | 121 | decoder decoder( 122 | .inst (inst), 123 | 124 | .jump_reg (jump_reg_in), 125 | .jump_imm (jump_imm_in), 126 | 127 | .branch (branch_in), 128 | 129 | .rf_waddr_src (rf_waddr_src_in), 130 | .rf_wdata_src (rf_wdata_src_in), 131 | .rf_wen (rf_wen_in), 132 | 133 | .alu_src1 (alu_src1_in), 134 | .alu_src2 (alu_src2_in), 135 | .alu_op (alu_op_in), 136 | .mf_hi_lo (mf_hi_lo_in), 137 | .mt_hi_lo (mt_hi_lo_in), 138 | .mul_div (mul_div_in), 139 | 140 | .mem_read (mem_read_in), 141 | .mem_write (mem_write_in), 142 | .align_store (align_store_in), 143 | .align_load (align_load_in), 144 | 145 | .eret (eret_in), 146 | .mfc0 (mfc0_in), 147 | .mtc0 (mtc0_in), 148 | .trap (trap_in), 149 | 150 | .overflow_exception (overflow_exception_in), 151 | 152 | .reserved_inst (reserved_inst_in) 153 | ); 154 | 155 | assign rf_raddr1 = inst_rs; 156 | assign rf_raddr2 = inst_rt; 157 | 158 | assign rf_waddr_out = ( {5{rf_waddr_src_in[0]}} & inst_rt ) | 159 | ( {5{rf_waddr_src_in[1]}} & inst_rd ) | 160 | ( {5{rf_waddr_src_in[2]}} & 5'd31 ) ; 161 | assign rf_wdata_src_out = rf_wdata_src_in; 162 | assign rf_wen_out = rf_wen_in; 163 | 164 | assign alu_src1_out = alu_src1_in; 165 | assign alu_src2_out = alu_src2_in; 166 | assign alu_op_out = alu_op_in; 167 | assign mf_hi_lo_out = mf_hi_lo_in; 168 | assign mt_hi_lo_out = mt_hi_lo_in; 169 | assign mul_div_out = mul_div_in; 170 | 171 | assign mem_read_out = mem_read_in; 172 | assign mem_write_out = mem_write_in; 173 | assign align_load_out = align_load_in; 174 | assign align_store_out = align_store_in; 175 | 176 | assign eret_out = eret_in && leaving; //impact on IF 177 | assign mfc0_out = mfc0_in; 178 | assign mtc0_out = mtc0_in; 179 | 180 | assign overflow_exception_out = overflow_exception_in; 181 | 182 | assign imm_16_out = inst_imm_16; 183 | assign rf_A_out = rf_rdata1; 184 | assign rf_B_out = rf_rdata2; 185 | 186 | assign isbr = jump_reg_in || jump_imm_in || |branch_in; 187 | 188 | wire rf_equal = (drf_rdata1 == drf_rdata2); 189 | wire rf_rdata1_ez = (drf_rdata1 == 32'd0); 190 | wire rf_rdata1_gtz = ~drf_rdata1[31] & ~rf_rdata1_ez; 191 | wire rf_rdata1_gez = ~drf_rdata1[31]; 192 | wire rf_rdata1_ltz = drf_rdata1[31]; 193 | wire rf_rdata1_lez = drf_rdata1[31] | rf_rdata1_ez; 194 | wire branch_taken = (branch_in[0] & (inst_opcode[26] ^ rf_equal)) | 195 | (branch_in[1] & rf_rdata1_gtz) | 196 | (branch_in[2] & rf_rdata1_gez) | 197 | (branch_in[3] & rf_rdata1_ltz) | 198 | (branch_in[4] & rf_rdata1_lez) ; 199 | assign PC_modified = (jump_reg_in || jump_imm_in || branch_taken) && leaving; 200 | 201 | wire [31 : 0] DE_PC_inc = DE_PC + 32'd4; 202 | wire [31 : 0] PC_jump_reg = drf_rdata1[31 : 0]; 203 | wire [31 : 0] PC_jump_imm = { DE_PC_inc[31 : 28], inst_imm_26, 2'd0 }; 204 | wire [31 : 0] PC_branch = ( DE_PC_inc + { {14{inst_imm_16[15]}}, inst_imm_16, 2'd0 } ); 205 | assign PC_modified_data = ( {32{jump_reg_in} } & PC_jump_reg) | 206 | ( {32{jump_imm_in} } & PC_jump_imm) | 207 | ( {32{branch_taken}} & PC_branch ) ; 208 | 209 | always @(posedge clk) 210 | begin 211 | if(comming) DE_PC <= IF_PC; 212 | else ; 213 | end 214 | 215 | reg [4 : 0] exccode; 216 | 217 | assign address_error_IF_out = (exccode != 5'd0); 218 | 219 | reg in_delay_slot; 220 | 221 | always @(posedge clk) 222 | begin 223 | if(rst_p) in_delay_slot <= 1'd0; 224 | else if(leaving) in_delay_slot <= jump_reg_in || jump_imm_in || (branch_in != 5'd0); 225 | else ; 226 | end 227 | 228 | assign in_delay_slot_out = in_delay_slot; 229 | 230 | always @(posedge clk) 231 | begin 232 | if(comming) exccode <= exccode_in; 233 | else ; 234 | end 235 | 236 | assign exccode_out = (exccode != 5'h00) ? exccode : //AdEL(IF) 237 | (reserved_inst_in) ? 5'h0a : //RI 238 | (trap_in[0]) ? 5'h08 : //Sys 239 | (trap_in[1]) ? 5'h09 : //Bp 240 | 5'h00 ; 241 | 242 | endmodule 243 | -------------------------------------------------------------------------------- /rtl/myCPU/MA.v: -------------------------------------------------------------------------------- 1 | module MA( 2 | input clk, 3 | input rst_p, 4 | input empty, 5 | 6 | //pipeline signals 7 | input EX_ready, 8 | output MA_enable, 9 | output MA_ready, 10 | input WB_enable, 11 | 12 | //memory access signals 13 | input interlayer_ready, 14 | output MA_mem_read, 15 | output MA_mem_write, 16 | output [ 3 : 0] MA_mem_wstrb, 17 | output [31 : 0] MA_mem_addr, 18 | output [ 2 : 0] MA_mem_size, 19 | output [31 : 0] MA_mem_wdata, 20 | input mem_busy, 21 | 22 | //interact with EX 23 | input [4 : 0] inst_rd_in, 24 | 25 | input [31 : 0] rf_A_in, 26 | input [31 : 0] rf_B_in, 27 | 28 | input [4 : 0] rf_waddr_in, 29 | input [2 : 0] rf_wdata_src_in, 30 | input rf_wen_in, 31 | 32 | input [1 : 0] mf_hi_lo_in, 33 | input [1 : 0] mt_hi_lo_in, 34 | input [2 : 0] mul_div_in, 35 | 36 | input mem_read_in, 37 | input mem_write_in, 38 | input [6 : 0] align_load_in, 39 | input [4 : 0] align_store_in, 40 | 41 | input eret_in, 42 | input mfc0_in, 43 | input mtc0_in, 44 | 45 | input [31 : 0] alu_res_in, 46 | 47 | input [31 : 0] EX_PC, 48 | 49 | input in_delay_slot_in, 50 | input address_error_IF_in, 51 | input [4 : 0] exccode_in, 52 | 53 | //interact with WB 54 | output [31 : 0] rf_B_out, 55 | output [ 4 : 0] rf_waddr_out, 56 | output [ 2 : 0] rf_wdata_src_out, 57 | output rf_wen_out, 58 | output [31 : 0] alu_res_out, 59 | output mem_read_out, 60 | output [6 : 0] align_load_out, 61 | 62 | output reg [31 : 0] MA_PC, 63 | 64 | //interact with mul_div 65 | input mul_div_done_in, 66 | input [63 : 0] mul_div_res_in, 67 | 68 | //interact with forward 69 | output valid_out, 70 | output leaving_out, 71 | 72 | //interract with excption 73 | output address_error_IF_out, 74 | output in_delay_slot_out, 75 | output [ 4 : 0] cp0_addr, 76 | input [31 : 0] cp0_rdata, 77 | output [31 : 0] cp0_wdata, 78 | output mtc0_out, 79 | output eret_out, 80 | output [4 : 0] exccode_out 81 | ); 82 | 83 | reg valid; 84 | assign valid_out = valid; 85 | 86 | wire comming = MA_enable && EX_ready; 87 | wire leaving = WB_enable && MA_ready; 88 | 89 | reg [4 : 0] inst_rd; 90 | reg [31 : 0] rf_A; 91 | reg [31 : 0] rf_B; 92 | reg [4 : 0] rf_waddr; 93 | reg [2 : 0] rf_wdata_src; 94 | reg rf_wen; 95 | reg [1 : 0] mf_hi_lo; 96 | reg [1 : 0] mt_hi_lo; 97 | reg [1 : 0] mul_div; 98 | reg mem_read; 99 | reg mem_write; 100 | reg [6 : 0] align_load; 101 | reg [4 : 0] align_store; 102 | reg eret; 103 | reg mfc0; 104 | reg mtc0; 105 | 106 | wire doing; 107 | assign leaving_out = WB_enable && valid && !doing && !(exccode == 5'd0 && mem_write && !interlayer_ready) && !(exccode == 5'd0 && mem_read && mem_busy); //to avoid leaving-empty combinational loop 108 | 109 | always @(posedge clk) 110 | begin 111 | if(rst_p || empty) valid <= 1'd0; 112 | else if(comming) valid <= 1'd1; 113 | else if(leaving) valid <= 1'd0; 114 | else ; 115 | end 116 | 117 | assign MA_enable = !valid || leaving; 118 | assign MA_ready = valid && !doing && !empty && !(exccode == 5'd0 && mem_write && !interlayer_ready) && !(exccode == 5'd0 && mem_read && mem_busy); 119 | 120 | reg [31 : 0] alu_res; 121 | reg [31 : 0] HI; 122 | reg [31 : 0] LO; 123 | reg in_delay_slot; 124 | reg address_error_IF; 125 | reg [4 : 0] exccode; 126 | 127 | always @(posedge clk) 128 | begin 129 | if(comming) 130 | begin 131 | inst_rd <= inst_rd_in; 132 | 133 | rf_A <= rf_A_in; 134 | rf_B <= rf_B_in; 135 | 136 | rf_waddr <= rf_waddr_in; 137 | rf_wdata_src <= rf_wdata_src_in; 138 | rf_wen <= rf_wen_in; 139 | 140 | mf_hi_lo <= mf_hi_lo_in; 141 | mt_hi_lo <= mt_hi_lo_in; 142 | mul_div <= mul_div_in[1:0]; //don't mind signed or unsigned now 143 | 144 | mem_read <= mem_read_in; 145 | mem_write <= mem_write_in; 146 | align_load <= align_load_in; 147 | align_store <= align_store_in; 148 | 149 | eret <= eret_in; 150 | mfc0 <= mfc0_in; 151 | mtc0 <= mtc0_in; 152 | 153 | alu_res <= alu_res_in; 154 | 155 | in_delay_slot <= in_delay_slot_in; 156 | address_error_IF <= address_error_IF_in; 157 | exccode <= exccode_in; 158 | end 159 | else ; 160 | end 161 | 162 | assign rf_waddr_out = rf_waddr; 163 | assign rf_wdata_src_out = rf_wdata_src; 164 | assign rf_wen_out = rf_wen; 165 | 166 | assign alu_res_out = mf_hi_lo[0] ? LO : 167 | mf_hi_lo[1] ? HI : 168 | mfc0 ? cp0_rdata : alu_res; 169 | 170 | assign mem_read_out = mem_read; 171 | assign align_load_out = align_load; 172 | 173 | assign rf_B_out = rf_B; 174 | 175 | assign in_delay_slot_out = in_delay_slot; 176 | assign address_error_IF_out = address_error_IF; 177 | assign cp0_addr = inst_rd; 178 | assign cp0_wdata = rf_B; 179 | assign mtc0_out = mtc0; 180 | assign eret_out = eret; 181 | assign exccode_out = exccode; 182 | 183 | assign doing = valid && (mul_div[0] || mul_div[1]) && !mul_div_done_in; 184 | 185 | wire [3 : 0] alu_res_align = {alu_res[1:0] == 2'b11, alu_res[1:0] == 2'b10, 186 | alu_res[1:0] == 2'b01, alu_res[1:0] == 2'b00}; 187 | wire [31 : 0] mem_sw_data = rf_B; 188 | wire [31 : 0] mem_sb_data = ( {32{alu_res_align[2'b00]}} & {24'd0, rf_B[7 : 0] } ) | 189 | ( {32{alu_res_align[2'b01]}} & {16'd0, rf_B[7 : 0], 8'd0} ) | 190 | ( {32{alu_res_align[2'b10]}} & { 8'd0, rf_B[7 : 0], 16'd0} ) | 191 | ( {32{alu_res_align[2'b11]}} & { rf_B[7 : 0], 24'd0} ) ; 192 | wire [31 : 0] mem_sh_data = ( {32{~alu_res[1]}} & {16'd0, rf_B[15 : 0]} ) | 193 | ( {32{ alu_res[1]}} & {rf_B[15 : 0], 16'd0} ) ; 194 | wire [31 : 0] mem_swl_data = ( {32{alu_res_align[2'b00]}} & {24'd0, rf_B[31 : 24]} ) | 195 | ( {32{alu_res_align[2'b01]}} & {16'd0, rf_B[31 : 16]} ) | 196 | ( {32{alu_res_align[2'b10]}} & { 8'd0, rf_B[31 : 8]} ) | 197 | ( {32{alu_res_align[2'b11]}} & rf_B ) ; 198 | wire [31 : 0] mem_swr_data = ( {32{alu_res_align[2'b00]}} & rf_B ) | 199 | ( {32{alu_res_align[2'b01]}} & {rf_B[23 : 0], 8'd0} ) | 200 | ( {32{alu_res_align[2'b10]}} & {rf_B[15 : 0], 16'd0} ) | 201 | ( {32{alu_res_align[2'b11]}} & {rf_B[ 7 : 0], 24'd0} ) ; 202 | wire [ 3 : 0] mem_sw_strb = 4'b1111; 203 | wire [ 3 : 0] mem_sb_strb = {alu_res_align[2'b11], alu_res_align[2'b10], 204 | alu_res_align[2'b01], alu_res_align[2'b00]}; 205 | wire [ 3 : 0] mem_sh_strb = {alu_res[1], alu_res[1], ~alu_res[1], ~alu_res[1]}; 206 | wire [ 3 : 0] mem_swl_strb = {alu_res[1] & alu_res[0], alu_res[1], alu_res[1] | alu_res[0], 1'b1}; 207 | wire [ 3 : 0] mem_swr_strb = {1'b1, ~(alu_res[1] & alu_res[0]), ~alu_res[1], ~(alu_res[1] | alu_res[0])}; 208 | 209 | assign MA_mem_read = mem_read && leaving && exccode == 5'd0; 210 | assign MA_mem_write = mem_write && valid && !empty && exccode == 5'd0; 211 | assign MA_mem_wstrb = ( {4{align_store[4]}} & mem_sw_strb ) | 212 | ( {4{align_store[3]}} & mem_sb_strb ) | 213 | ( {4{align_store[2]}} & mem_sh_strb ) | 214 | ( {4{align_store[1]}} & mem_swl_strb ) | 215 | ( {4{align_store[0]}} & mem_swr_strb ) ; 216 | assign MA_mem_addr = {alu_res[31 : 2], 2'd0}; 217 | wire [2 : 0] load_size = ( {3{align_load[6]}} & 3'd2 ) | 218 | ( {3{align_load[5] | align_load[4]}} & 3'd0 ) | 219 | ( {3{align_load[3] | align_load[2]}} & 3'd1 ) | 220 | ( {3{align_load[1] | align_load[0]}} & 3'd2 ) ; 221 | wire [2 : 0] store_size = ({3{align_store[4]}} & 3'd2) | 222 | ({3{align_store[3]}} & 3'd0) | 223 | ({3{align_store[2]}} & 3'd1) | 224 | ({3{align_store[1]}} & 3'd2) | 225 | ({3{align_store[0]}} & 3'd2) ; 226 | assign MA_mem_size = mem_read ? load_size : store_size; 227 | assign MA_mem_wdata = ( {32{align_store[4]}} & mem_sw_data ) | 228 | ( {32{align_store[3]}} & mem_sb_data ) | 229 | ( {32{align_store[2]}} & mem_sh_data ) | 230 | ( {32{align_store[1]}} & mem_swl_data ) | 231 | ( {32{align_store[0]}} & mem_swr_data ) ; 232 | 233 | reg has_mul_div_res; 234 | reg [63:0] mul_div_res; 235 | reg first_cycle; 236 | 237 | always @(posedge clk) 238 | begin 239 | if (rst_p) has_mul_div_res <= 1'd0; 240 | if (rst_p) first_cycle <= 1'd0; 241 | else first_cycle <= comming; 242 | if (mul_div[1] && !leaving && first_cycle) 243 | begin 244 | mul_div_res <= mul_div_res_in; 245 | has_mul_div_res <= 1'd1; 246 | end 247 | if (mul_div[0] && !leaving && mul_div_done_in) 248 | begin 249 | mul_div_res <= mul_div_res_in; 250 | has_mul_div_res <= 1'd1; 251 | end 252 | if (has_mul_div_res && leaving) 253 | begin 254 | {HI, LO} <= mul_div_res; 255 | has_mul_div_res <= 1'd0; 256 | end 257 | if((mul_div[0] || mul_div[1]) && leaving && !has_mul_div_res) {HI, LO} <= mul_div_res_in; 258 | 259 | else if(mt_hi_lo[0] && leaving) LO <= rf_A; 260 | else if(mt_hi_lo[1] && leaving) HI <= rf_A; 261 | else ; 262 | end 263 | 264 | always @(posedge clk) 265 | begin 266 | if(comming) MA_PC <= EX_PC; 267 | else ; 268 | end 269 | 270 | endmodule 271 | -------------------------------------------------------------------------------- /rtl/myCPU/mul_div.v: -------------------------------------------------------------------------------- 1 | module mul_div( 2 | input clk, 3 | input rst_p, 4 | 5 | input [31 : 0] A, 6 | input [31 : 0] B, 7 | 8 | input [2 : 0] mul_div, 9 | output done, 10 | 11 | output [63 : 0] res 12 | ); 13 | 14 | wire [63 : 0] mul_res; 15 | wire [31 : 0] q_res; 16 | wire [31 : 0] r_res; 17 | wire mul_doing; 18 | wire div_doing; 19 | 20 | reg [1 : 0] mul_div_save; 21 | always @(posedge clk) 22 | begin 23 | if(done) mul_div_save <= mul_div[1:0]; 24 | else ; 25 | end 26 | 27 | assign res = mul_div_save[1] ? mul_res : {r_res, q_res}; 28 | assign done = !mul_doing && !div_doing; 29 | 30 | mul_32 mul_32( 31 | .clk (clk), 32 | .rst_p (rst_p), 33 | 34 | .A (A), 35 | .B (B), 36 | .signed_mul (mul_div[2]), 37 | 38 | .start (mul_div[1]), 39 | .doing (mul_doing), 40 | 41 | .S (mul_res) 42 | ); 43 | 44 | div_32 div_32( 45 | .clk (clk), 46 | .rst_p (rst_p), 47 | 48 | .A (A), 49 | .B (B), 50 | .signed_div (mul_div[2]), 51 | 52 | .start (mul_div[0]), 53 | .doing (div_doing), 54 | 55 | .Q (q_res), 56 | .R (r_res) 57 | ); 58 | 59 | /* 60 | wire [63 : 0] mul_res; 61 | wire [79 : 0] div_res; 62 | wire [31 : 0] q_res = div_res[71:40]; 63 | wire [31 : 0] r_res = div_res[31:0]; 64 | 65 | wire [32 : 0] out_A = {mul_div[2] ? A[31] : 1'b0, A}; 66 | wire [32 : 0] out_B = {mul_div[2] ? B[31] : 1'b0, B}; 67 | 68 | reg [32 : 0] out_A_save; 69 | reg [32 : 0] out_B_save; 70 | 71 | reg [1 : 0] mul_div_save; 72 | always @(posedge clk) 73 | begin 74 | if(done) 75 | begin 76 | mul_div_save <= mul_div[1:0]; 77 | out_A_save <= out_A; 78 | out_B_save <= out_B; 79 | end 80 | else ; 81 | end 82 | 83 | assign res = mul_div_save[1] ? mul_res : {r_res, q_res}; 84 | 85 | wire mul_doing = 1'b0; //delaying res receiving leads to unnecessary to wait 86 | //waiting hear leading to combinatorial loop 87 | 88 | wire out_valid; 89 | wire in_ready; 90 | wire in_valid; 91 | 92 | reg [1 : 0] div_state; 93 | 94 | always @(posedge clk) 95 | begin 96 | if(rst_p) div_state <= 2'd0; 97 | else if(div_state == 2'd0 && mul_div[0]) div_state <= 2'd1; 98 | else if(div_state == 2'd1 && in_ready) div_state <= 2'd2; 99 | else if(div_state == 2'd2 && in_valid) div_state <= 2'd0; 100 | else ; 101 | end 102 | 103 | wire in_ready_1; 104 | wire in_ready_2; 105 | assign in_ready = in_ready_1 && in_ready_2; 106 | assign out_valid = (mul_div[0] && (div_state == 2'd0)) || (div_state == 2'd1); 107 | 108 | wire div_doing = (div_state != 2'd0); //delaying res receiving leads to unnecessary to wait in first cycle 109 | //waiting hear leading to combinatorial loop 110 | 111 | assign done = !mul_doing && !div_doing; 112 | 113 | mult_gen_0 mul_32( 114 | .CLK (clk), 115 | .A (out_A), 116 | .B (out_B), 117 | .P (mul_res) 118 | ); 119 | 120 | div_gen_0 div_32( 121 | .aclk (clk), 122 | 123 | .s_axis_dividend_tvalid (out_valid), 124 | .s_axis_dividend_tready (in_ready_2), 125 | .s_axis_dividend_tdata (div_doing ? out_A_save : out_A), 126 | 127 | .s_axis_divisor_tvalid (out_valid), 128 | .s_axis_divisor_tready (in_ready_1), 129 | .s_axis_divisor_tdata (div_doing ? out_B_save : out_B), 130 | 131 | .m_axis_dout_tvalid (in_valid), 132 | .m_axis_dout_tdata (div_res) 133 | ); 134 | */ 135 | 136 | endmodule 137 | 138 | module mul_32( 139 | input clk, 140 | input rst_p, 141 | 142 | input [31 : 0] A, 143 | input [31 : 0] B, 144 | input signed_mul, 145 | 146 | input start, 147 | output doing, 148 | 149 | output [63 : 0] S 150 | ); 151 | 152 | assign doing = 1'b0; //delaying res receiving leads to unnecessary to wait when start 153 | //waiting hear leading to combinatorial loop 154 | 155 | wire [63 : 0] A_extended = { {32{signed_mul?A[31]:1'b0}}, A}; 156 | wire [63 : 0] B_extended = { {32{signed_mul?B[31]:1'b0}}, B}; 157 | 158 | reg [63 : 0] add_num[16 : 0]; 159 | wire [34 : 0] booth_flag = {{2{B_extended[32]}}, B, 1'd0}; 160 | reg [16 : 0] cin_0; 161 | 162 | genvar i; 163 | 164 | generate 165 | for(i = 0; i < 17; i = i + 1) 166 | begin: generate_add_num 167 | always @(posedge clk) 168 | begin 169 | add_num[i] <= ( {64{(booth_flag[2*i+2 : 2*i] == 3'b000)}} & 64'd0 ) | 170 | ( {64{(booth_flag[2*i+2 : 2*i] == 3'b001)}} & A_extended << 2*i ) | 171 | ( {64{(booth_flag[2*i+2 : 2*i] == 3'b010)}} & A_extended << 2*i ) | 172 | ( {64{(booth_flag[2*i+2 : 2*i] == 3'b011)}} & (A_extended << 1 + 2*i)) | 173 | ( {64{(booth_flag[2*i+2 : 2*i] == 3'b100)}} & ~(A_extended << 1 + 2*i)) | 174 | ( {64{(booth_flag[2*i+2 : 2*i] == 3'b101)}} & ~(A_extended << 2*i) ) | 175 | ( {64{(booth_flag[2*i+2 : 2*i] == 3'b110)}} & ~(A_extended << 2*i) ) | 176 | ( {64{(booth_flag[2*i+2 : 2*i] == 3'b111)}} & 64'd0 ) ; 177 | cin_0[i] <= (booth_flag[2*i+2 : 2*i] == 3'b100) | 178 | (booth_flag[2*i+2 : 2*i] == 3'b101) | 179 | (booth_flag[2*i+2 : 2*i] == 3'b110) ; 180 | end 181 | end 182 | endgenerate 183 | 184 | wire [16 : 0] root[63 : 0]; 185 | 186 | generate 187 | for(i = 0; i < 64; i = i + 1) 188 | begin: generate_root 189 | //todo: for j 190 | assign root[i] = {add_num[16][i], add_num[15][i], add_num[14][i], add_num[13][i], 191 | add_num[12][i], add_num[11][i], add_num[10][i], add_num[ 9][i], 192 | add_num[ 8][i], add_num[ 7][i], add_num[ 6][i], add_num[ 5][i], 193 | add_num[ 4][i], add_num[ 3][i], add_num[ 2][i], add_num[ 1][i], 194 | add_num[ 0][i]}; 195 | end 196 | endgenerate 197 | 198 | wire [14 : 0] cin[63 : 0]; 199 | assign cin[0] = cin_0[14 : 0]; 200 | wire [63 : 0] num1; 201 | wire [63 : 0] num2; 202 | 203 | generate 204 | for(i = 0; i < 64; i = i + 1) 205 | begin: connect_Wallace_tree 206 | if(i < 63) Wallace_tree Wallace_tree(root[i], cin[i], cin[i+1], num1[i], num2[i+1]); 207 | else Wallace_tree Wallace_tree(root[i], cin[i], , num1[i], ); 208 | end 209 | endgenerate 210 | 211 | assign num2[0] = cin_0[15]; 212 | assign S = num1 + num2 + cin_0[16]; 213 | 214 | endmodule 215 | 216 | module Wallace_tree( 217 | //todo: 16 roots 218 | //1 bit, 17 roots, 15 cin & cout 219 | input [16 : 0] root, 220 | input [14 : 0] cin, 221 | 222 | output [14 : 0] cout, 223 | output S, 224 | output C 225 | 226 | ); 227 | 228 | wire [16 : 0] level_0 = root; 229 | wire [11 : 0] level_1; 230 | wire [ 8 : 0] level_2; 231 | wire [ 5 : 0] level_3; 232 | wire [ 2 : 0] level_4; 233 | wire [ 2 : 0] level_5; 234 | 235 | CSA #(.WIDTH(5)) CSA_0(level_0[4:0], level_0[9:5], level_0[14:10], level_1[4:0], cout[4:0]); 236 | assign level_1[6:5] = level_0[16:15]; 237 | assign level_1[11:7] = cin[4:0]; 238 | 239 | CSA #(.WIDTH(4)) CSA_1(level_1[3:0], level_1[7:4], level_1[11:8], level_2[3:0], cout[8:5]); 240 | assign level_2[7:4] = cin[8:5]; 241 | assign level_2[8] = 1'b0; 242 | 243 | CSA #(.WIDTH(3)) CSA_2(level_2[2:0], level_2[5:3], level_2[8:6], level_3[2:0], cout[11:9]); 244 | assign level_3[5:3] = cin[11:9]; 245 | 246 | CSA #(.WIDTH(2)) CSA_3(level_3[1:0], level_3[3:2], level_3[5:4], level_4[1:0], cout[13:12]); 247 | assign level_4[2] = cin[12]; 248 | 249 | CSA #(.WIDTH(1)) CSA_4(level_4[0], level_4[1], level_4[2], level_5[0], cout[14]); 250 | assign level_5[2:1] = cin[14:13]; 251 | 252 | CSA #(.WIDTH(1)) CSA_5(level_5[0], level_5[1], level_5[2], S, C); 253 | 254 | endmodule 255 | 256 | module CSA # 257 | ( 258 | parameter WIDTH = 1 259 | ) 260 | ( 261 | input [WIDTH - 1 : 0] A, 262 | input [WIDTH - 1 : 0] B, 263 | input [WIDTH - 1 : 0] C, 264 | 265 | output [WIDTH - 1 : 0] D, 266 | output [WIDTH - 1 : 0] E 267 | ); 268 | 269 | assign D = A ^ B ^ C; 270 | assign E = ((A & B) | (B & C) | (C & A)); 271 | 272 | endmodule 273 | 274 | module div_32( 275 | input clk, 276 | input rst_p, 277 | 278 | input [31 : 0] A, 279 | input [31 : 0] B, 280 | input signed_div, 281 | 282 | input start, 283 | output doing, 284 | 285 | output [31 : 0] Q, 286 | output [31 : 0] R 287 | ); 288 | 289 | reg [4 : 0] count; 290 | wire running = (count != 5'd0); //31 cycles after start 291 | 292 | assign doing = running; //delaying res receiving leads to unnecessary to wait when start 293 | //waiting hear leading to combinatorial loop 294 | 295 | always @(posedge clk) 296 | begin 297 | if(rst_p) count <= 5'd0; 298 | else if(!running && start) count <= 5'd31; 299 | else if(running) count <= count - 5'd1; 300 | else ; 301 | end 302 | 303 | wire A_signal = A[31]; 304 | wire B_signal = B[31]; 305 | wire Q_signal = (A_signal ^ B_signal) && signed_div; 306 | wire R_siganl = A_signal && signed_div; 307 | 308 | wire [63 : 0] A_extended = {32'b0, (signed_div && A_signal) ? ({1'b0, (~A[30:0])} + 32'd1) : A}; 309 | wire [32 : 0] B_extended = { 1'b0, (signed_div && B_signal) ? ({1'b0, (~B[30:0])} + 32'd1) : B}; 310 | 311 | reg Q_signal_save; 312 | reg R_signal_save; 313 | 314 | reg [63 : 0] A_extended_save; 315 | reg [32 : 0] B_extended_save; 316 | 317 | always @(posedge clk) 318 | begin 319 | if(!running && start) 320 | begin 321 | Q_signal_save <= Q_signal; 322 | R_signal_save <= R_siganl; 323 | B_extended_save <= B_extended; 324 | end 325 | else ; 326 | end 327 | 328 | wire [32 : 0] sub_res = (running ? A_extended_save[63:31] : A_extended[63:31]) - (running ? B_extended_save : B_extended); 329 | wire [32 : 0] restore = running ? A_extended_save[63:31] : A_extended[63:31]; 330 | 331 | wire less = sub_res[32]; 332 | reg [31 : 0] Q_temp; 333 | 334 | always @(posedge clk) 335 | begin 336 | if(start || running) 337 | begin 338 | A_extended_save[63:0] <= {(less ? restore[31:0] : sub_res[31:0]), 339 | running ? A_extended_save[30:0] : A_extended[30:0], 1'b0}; 340 | Q_temp[0] <= !less; 341 | Q_temp[31:1] <= Q_temp[30:0]; 342 | end 343 | else ; 344 | end 345 | 346 | assign Q = Q_signal_save ? {1'b1, ~Q_temp[30 : 0]} + 32'd1 : Q_temp[31 : 0]; 347 | assign R = R_signal_save ? {1'b1, ~A_extended_save[62 : 32]} + 32'd1 : A_extended_save[63 : 32]; 348 | 349 | endmodule 350 | -------------------------------------------------------------------------------- /rtl/myCPU/cache.v: -------------------------------------------------------------------------------- 1 | module cache( 2 | input clk, 3 | input rst_p, 4 | 5 | input inst_req, 6 | input [31 : 0] inst_addr, 7 | output [31 : 0] inst_rdata, 8 | output inst_addr_ok, 9 | output inst_data_ok, 10 | 11 | input data_req, 12 | input data_wr, 13 | input [31 : 0] data_addr, 14 | input [ 2 : 0] data_size, 15 | input [ 3 : 0] data_wstrb, 16 | input [31 : 0] data_wdata, 17 | output [31 : 0] data_rdata, 18 | output data_write_ok, 19 | output data_data_ok, 20 | output data_busy, 21 | 22 | //axi 23 | //ar 24 | output [ 3 : 0] arid, 25 | output [31 : 0] araddr, 26 | output [ 7 : 0] arlen, 27 | output [ 2 : 0] arsize, 28 | output [ 1 : 0] arburst, 29 | output [ 1 : 0] arlock, 30 | output [ 3 : 0] arcache, 31 | output [ 2 : 0] arprot, 32 | output arvalid, 33 | input arready, 34 | 35 | //r 36 | input [ 3 : 0] rid, 37 | input [31 : 0] rdata, 38 | input [ 1 : 0] rresp, 39 | input rlast, 40 | input rvalid, 41 | output rready, 42 | 43 | //aw 44 | output [ 3 : 0] awid, 45 | output [31 : 0] awaddr, 46 | output [ 7 : 0] awlen, 47 | output [ 2 : 0] awsize, 48 | output [ 1 : 0] awburst, 49 | output [ 1 : 0] awlock, 50 | output [ 3 : 0] awcache, 51 | output [ 2 : 0] awprot, 52 | output awvalid, 53 | input awready, 54 | 55 | //w 56 | output [ 3 : 0] wid, 57 | output [31 : 0] wdata, 58 | output [ 3 : 0] wstrb, 59 | output wlast, 60 | output wvalid, 61 | input wready, 62 | 63 | //b 64 | input [3 : 0] bid, 65 | input [1 : 0] bresp, 66 | input bvalid, 67 | output bready 68 | ); 69 | 70 | wire uncacheable_inst = 1'b0; //inst_req && (inst_addr[31:29] & 3'b111) == 3'b101; 71 | wire uncacheable_data = (data_addr[31:29] & 3'b111) == 3'b101; 72 | wire read_req; 73 | wire write_req; 74 | 75 | wire [31 : 0] icache_data; 76 | wire icache_valid; 77 | wire [31 : 0] icache_addr; 78 | wire icache_req; 79 | wire [255 : 0] icache_buffer; 80 | wire icache_ok; 81 | wire icache_busy; 82 | 83 | icache icache( 84 | .clk (clk), 85 | .resetn (~rst_p), 86 | 87 | .pgOffsetIn (inst_addr[11:0]), 88 | .pgOffsetValid (inst_req && !uncacheable_inst), 89 | .tagIn (inst_addr[31:12]), 90 | .tagValid (inst_req && !uncacheable_inst), 91 | 92 | .dataOut (icache_data), 93 | .dataOutReady (icache_valid), 94 | 95 | .addr2Cache2 (icache_addr), 96 | .addr2Cache2Valid (icache_req), 97 | .data2ICacheBlk1 (icache_buffer[31:0]), 98 | .data2ICacheBlk2 (icache_buffer[63:32]), 99 | .data2ICacheBlk3 (icache_buffer[95:64]), 100 | .data2ICacheBlk4 (icache_buffer[127:96]), 101 | .data2ICacheBlk5 (icache_buffer[159:128]), 102 | .data2ICacheBlk6 (icache_buffer[191:160]), 103 | .data2ICacheBlk7 (icache_buffer[223:192]), 104 | .data2ICacheBlk8 (icache_buffer[255:224]), 105 | .dataRequestedReady (icache_ok), 106 | .data2ICacheBlkReady (icache_ok), 107 | 108 | .busy (icache_busy) 109 | ); 110 | 111 | wire [31 : 0] dcache_data; 112 | wire dcache_valid; 113 | wire [31 : 0] dcache_addr; 114 | wire dcache_req; 115 | wire [255 : 0] dcache_buffer; 116 | wire dcache_ok; 117 | wire dcache_wb; 118 | wire dcache_wb_ok; 119 | wire [31 : 0] dcache_wb_addr; 120 | wire [255 : 0] dcache_wb_data; 121 | wire dcache_busy; 122 | 123 | dcache dcache( 124 | .clk (clk), 125 | .resetn (~rst_p), 126 | 127 | .pgOffsetIn (data_addr[11:0]), 128 | .pgOffsetValid (data_req && !uncacheable_data), 129 | .tagIn (data_addr[31:12]), 130 | .tagValid (data_req && !uncacheable_data), 131 | .wrIn (data_wr), 132 | .wstrbIn (data_wstrb), 133 | .wdataIn (data_wdata), 134 | 135 | .dataOut (dcache_data), 136 | .dataOutReady (dcache_valid), 137 | 138 | .addr2Cache2 (dcache_addr), 139 | .addr2Cache2Valid (dcache_req), 140 | .data2ICacheBlk1 (dcache_buffer[31:0]), 141 | .data2ICacheBlk2 (dcache_buffer[63:32]), 142 | .data2ICacheBlk3 (dcache_buffer[95:64]), 143 | .data2ICacheBlk4 (dcache_buffer[127:96]), 144 | .data2ICacheBlk5 (dcache_buffer[159:128]), 145 | .data2ICacheBlk6 (dcache_buffer[191:160]), 146 | .data2ICacheBlk7 (dcache_buffer[223:192]), 147 | .data2ICacheBlk8 (dcache_buffer[255:224]), 148 | .dataRequestedReady (dcache_ok), 149 | .data2ICacheBlkReady (dcache_ok), 150 | 151 | .dataWriteBackValid (dcache_wb), 152 | .dataWriteBackAck (dcache_wb_ok), 153 | .dataWriteBackAddr (dcache_wb_addr), 154 | .dataWriteBack (dcache_wb_data), 155 | 156 | .busy (dcache_busy) 157 | ); 158 | 159 | reg [ 3 : 0] read_index; 160 | reg [31 : 0] read_buffer[7 : 0]; 161 | reg [ 1 : 0] read_dst; 162 | wire read_free; 163 | wire read_send_addr; 164 | wire read_wait_data; 165 | 166 | reg write_dst; 167 | wire write_free; 168 | wire write_send_addr; 169 | wire write_send_data; 170 | wire write_wait_resp; 171 | 172 | assign inst_addr_ok = inst_req && !icache_busy; 173 | assign inst_data_ok = icache_valid; 174 | assign inst_rdata = icache_data; 175 | 176 | assign data_write_ok = data_wr && (uncacheable_data ? (bvalid && write_dst == 1'b1) : dcache_valid); 177 | assign data_data_ok = (dcache_valid || (rvalid && rlast && (read_dst == 2'd1))); 178 | assign data_rdata = dcache_valid ? dcache_data : rdata; 179 | assign data_busy = dcache_busy; 180 | 181 | assign read_req = icache_req || dcache_req || (data_req && uncacheable_data && !data_wr); 182 | assign write_req = dcache_wb || (data_req && uncacheable_data && data_wr); 183 | 184 | `define READ_STATE_WIDTH 2 185 | `define READ_STATE_FREE 2'd0 186 | `define READ_STATE_SEND_ADDR 2'd1 187 | `define READ_STATE_WAIT_DATA 2'd2 188 | 189 | reg [`READ_STATE_WIDTH - 1 : 0] read_state; 190 | 191 | assign read_free = (read_state == `READ_STATE_FREE); 192 | assign read_send_addr = (read_state == `READ_STATE_SEND_ADDR); 193 | assign read_wait_data = (read_state == `READ_STATE_WAIT_DATA); 194 | 195 | reg [31 : 0] read_addr; 196 | reg [ 7 : 0] read_len; 197 | reg [ 2 : 0] read_size; 198 | 199 | always @(posedge clk) 200 | begin 201 | if(rst_p) read_state <= `READ_STATE_FREE; 202 | else 203 | begin 204 | case(read_state) 205 | `READ_STATE_FREE: 206 | if(read_req) 207 | read_state <= `READ_STATE_SEND_ADDR; 208 | else ; 209 | `READ_STATE_SEND_ADDR: 210 | if(arready) 211 | read_state <= `READ_STATE_WAIT_DATA; 212 | else ; 213 | `READ_STATE_WAIT_DATA: 214 | if(rvalid && rlast) 215 | read_state <= `READ_STATE_FREE; 216 | else ; 217 | default: read_state <= `READ_STATE_FREE; 218 | endcase 219 | end 220 | end 221 | 222 | always @(posedge clk) 223 | begin 224 | if(rst_p) read_index <= 4'd0; 225 | else if(read_req && read_free) read_index <= 4'd0; 226 | else if(read_wait_data && rvalid) read_index <= read_index + 4'd1; 227 | else ; 228 | 229 | if(read_wait_data && rvalid) read_buffer[read_index] <= rdata; 230 | 231 | if(read_req && read_free) 232 | begin 233 | read_addr <= dcache_req ? dcache_addr : 234 | data_req && uncacheable_data ? data_addr : 235 | icache_addr ; 236 | read_len <= dcache_req ? 8'd7 : 237 | data_req && uncacheable_data ? 8'd0 : 238 | 8'd7 ; 239 | read_size <= dcache_req ? 3'd2 : 240 | data_req && uncacheable_data ? data_size : 241 | 3'd2 ; 242 | read_dst <= dcache_req ? 2'd0 : 243 | data_req && uncacheable_data ? 2'd1 : 244 | 2'd2 ; 245 | end 246 | end 247 | 248 | wire [255 : 0] cache_buffer = {rdata, 249 | read_buffer[6], 250 | read_buffer[5], 251 | read_buffer[4], 252 | read_buffer[3], 253 | read_buffer[2], 254 | read_buffer[1], 255 | read_buffer[0]}; 256 | 257 | assign icache_ok = rvalid && rlast && (read_dst == 2'd2); 258 | assign icache_buffer = cache_buffer; 259 | 260 | assign dcache_ok = rvalid && rlast && (read_dst == 2'd0); 261 | assign dcache_buffer = cache_buffer; 262 | 263 | assign arid = 4'd0; 264 | assign araddr = {3'd0, read_addr[28:0]}; 265 | assign arlen = read_len; 266 | assign arsize = read_size; 267 | assign arburst = 2'b01; 268 | assign arlock = 2'd0; 269 | assign arcache = 4'd0; 270 | assign arprot = 3'd0; 271 | assign arvalid = read_send_addr; 272 | 273 | assign rready = read_wait_data; 274 | 275 | `define WRITE_STATE_WIDTH 2 276 | `define WRITE_STATE_FREE 2'd0 277 | `define WRITE_STATE_SEND_ADDR 2'd1 278 | `define WRITE_STATE_SEND_DATA 2'd2 279 | `define WRITE_STATE_WAIT_RESP 2'd3 280 | 281 | reg [`WRITE_STATE_WIDTH - 1 : 0] write_state; 282 | 283 | assign write_free = (write_state == `WRITE_STATE_FREE); 284 | assign write_send_addr = (write_state == `WRITE_STATE_SEND_ADDR); 285 | assign write_send_data = (write_state == `WRITE_STATE_SEND_DATA); 286 | assign write_wait_resp = (write_state == `WRITE_STATE_WAIT_RESP); 287 | 288 | reg [ 3 : 0] write_index; 289 | reg [31 : 0] write_buffer[7 : 0]; 290 | 291 | reg [31 : 0] write_addr; 292 | reg [ 7 : 0] write_len; 293 | reg [ 2 : 0] write_size; 294 | reg [ 3 : 0] write_strb; 295 | 296 | always @(posedge clk) 297 | begin 298 | if(rst_p) write_state <= `WRITE_STATE_FREE; 299 | else 300 | begin 301 | case(write_state) 302 | `WRITE_STATE_FREE: 303 | if(write_req) 304 | write_state <= `WRITE_STATE_SEND_ADDR; 305 | else ; 306 | `WRITE_STATE_SEND_ADDR: 307 | if(awready) 308 | write_state <= `WRITE_STATE_SEND_DATA; 309 | else ; 310 | `WRITE_STATE_SEND_DATA: 311 | if(wready && wlast) 312 | write_state <= `WRITE_STATE_WAIT_RESP; 313 | else ; 314 | `WRITE_STATE_WAIT_RESP: 315 | if(bvalid) 316 | write_state <= `WRITE_STATE_FREE; 317 | else ; 318 | default: write_state <= `WRITE_STATE_FREE; 319 | endcase 320 | end 321 | end 322 | 323 | always @(posedge clk) 324 | begin 325 | if(rst_p) write_index <= 4'd0; 326 | else if(write_req && write_free) write_index <= 4'd0; 327 | else if(write_send_data && wready) write_index <= write_index + 4'd1; 328 | else ; 329 | 330 | if(write_req && write_free) 331 | begin 332 | write_addr <= data_req && uncacheable_data ? data_addr : dcache_wb_addr; 333 | write_len <= data_req && uncacheable_data ? 8'd0 : 8'd7; 334 | write_size <= data_req && uncacheable_data ? data_size : 3'd2; 335 | write_strb <= data_req && uncacheable_data ? data_wstrb : 4'b1111; 336 | write_dst <= data_req && uncacheable_data ? 1'b1 : 1'b0; 337 | write_buffer[0] <= data_req && uncacheable_data ? data_wdata : dcache_wb_data[31:0]; 338 | write_buffer[1] <= dcache_wb_data[63:32]; 339 | write_buffer[2] <= dcache_wb_data[95:64]; 340 | write_buffer[3] <= dcache_wb_data[127:96]; 341 | write_buffer[4] <= dcache_wb_data[159:128]; 342 | write_buffer[5] <= dcache_wb_data[191:160]; 343 | write_buffer[6] <= dcache_wb_data[223:192]; 344 | write_buffer[7] <= dcache_wb_data[255:224]; 345 | end 346 | end 347 | 348 | assign dcache_wb_ok = bvalid && (write_dst == 1'b0); 349 | 350 | assign awid = 4'd0; 351 | assign awaddr = {3'd0, write_addr[28:0]}; 352 | assign awlen = write_len; 353 | assign awsize = write_size; 354 | assign awburst = 2'b01; 355 | assign awlock = 2'd0; 356 | assign awcache = 4'd0; 357 | assign awprot = 3'd0; 358 | assign awvalid = write_send_addr; 359 | 360 | assign wid = 4'd0; 361 | assign wdata = write_buffer[write_index]; 362 | assign wstrb = write_strb; 363 | assign wlast = (write_index == write_len); 364 | assign wvalid = write_send_data; 365 | 366 | assign bready = write_wait_resp; 367 | 368 | endmodule 369 | -------------------------------------------------------------------------------- /rtl/myCPU/decoder.v: -------------------------------------------------------------------------------- 1 | `include "alu_op.h" 2 | 3 | module decoder( 4 | input [31 : 0] inst, 5 | 6 | output jump_reg, 7 | output jump_imm, 8 | 9 | output [4 : 0] branch, 10 | 11 | output [2 : 0] rf_waddr_src, 12 | output [2 : 0] rf_wdata_src, 13 | output rf_wen, 14 | 15 | output [2 : 0] alu_src1, 16 | output [2 : 0] alu_src2, 17 | output [`OP_NUM - 1 : 0] alu_op, 18 | output [1 : 0] mf_hi_lo, 19 | output [1 : 0] mt_hi_lo, 20 | output [2 : 0] mul_div, 21 | 22 | output mem_read, 23 | output mem_write, 24 | output [6 : 0] align_load, 25 | output [4 : 0] align_store, 26 | 27 | output eret, 28 | output mfc0, 29 | output mtc0, 30 | output [1 : 0] trap, 31 | 32 | output overflow_exception, 33 | 34 | output reserved_inst 35 | ); 36 | 37 | wire [31 : 26] opcode = inst[31 : 26]; 38 | wire [25 : 21] rs = inst[25 : 21]; 39 | wire [20 : 16] rt = inst[20 : 16]; 40 | wire [15 : 11] rd = inst[15 : 11]; 41 | wire [10 : 6] shamt = inst[10 : 6]; 42 | wire [ 5 : 0] func = inst[5 : 0]; 43 | 44 | wire [63 : 0] opcode_d; //decoded 45 | wire [31 : 0] rs_d; 46 | wire [31 : 0] rt_d; 47 | wire [31 : 0] rd_d; 48 | wire [31 : 0] shamt_d; 49 | wire [63 : 0] func_d; 50 | 51 | decoder_6_64 decoder_6_64_opcode(.in(opcode), .out(opcode_d)); 52 | decoder_5_32 decoder_5_32_rs(.in(rs), .out(rs_d)); 53 | decoder_5_32 decoder_5_32_rt(.in(rt), .out(rt_d)); 54 | decoder_5_32 decoder_5_32_rd(.in(rd), .out(rd_d)); 55 | decoder_5_32 decoder_5_32_shamt(.in(shamt), .out(shamt_d)); 56 | decoder_6_64 decoder_6_64_func(.in(func), .out(func_d)); 57 | 58 | //----------decode---------- 59 | wire inst_sll = opcode_d[6'h0] & func_d[6'h00]; 60 | wire inst_srl = opcode_d[6'h0] & func_d[6'h02]; 61 | wire inst_sra = opcode_d[6'h0] & func_d[6'h03]; 62 | wire inst_sllv = opcode_d[6'h0] & shamt_d[5'h0] & func_d[6'h04]; 63 | wire inst_srlv = opcode_d[6'h0] & shamt_d[5'h0] & func_d[6'h06]; 64 | wire inst_srav = opcode_d[6'h0] & shamt_d[5'h0] & func_d[6'h07]; 65 | 66 | wire inst_jr = opcode_d[6'h0] & rt_d[5'h0] & rd_d[5'h0] & shamt_d[5'h0] & func_d[6'h08]; 67 | wire inst_jalr = opcode_d[6'h0] & rt_d[5'h0] & shamt_d[5'h0] & func_d[6'h09]; 68 | 69 | wire inst_syscall = opcode_d[6'h0] & func_d[6'h0c]; 70 | wire inst_break = opcode_d[6'h0] & func_d[6'h0d]; 71 | 72 | wire inst_mfhi = opcode_d[6'h0] & rs_d[5'h0] & rt_d[5'h0] & shamt_d[5'h0] & func_d[6'h10]; 73 | wire inst_mthi = opcode_d[6'h0] & rt_d[5'h0] & rd_d[5'h0] & shamt_d[5'h0] & func_d[6'h11]; 74 | wire inst_mflo = opcode_d[6'h0] & rs_d[5'h0] & rt_d[5'h0] & shamt_d[5'h0] & func_d[6'h12]; 75 | wire inst_mtlo = opcode_d[6'h0] & rt_d[5'h0] & rd_d[5'h0] & shamt_d[5'h0] & func_d[6'h13]; 76 | 77 | wire inst_mul = opcode_d[6'h0] & rd_d[5'h0] & shamt_d[5'h0] & func_d[6'h18]; 78 | wire inst_mulu = opcode_d[6'h0] & rd_d[5'h0] & shamt_d[5'h0] & func_d[6'h19]; 79 | wire inst_div = opcode_d[6'h0] & rd_d[5'h0] & shamt_d[5'h0] & func_d[6'h1a]; 80 | wire inst_divu = opcode_d[6'h0] & rd_d[5'h0] & shamt_d[5'h0] & func_d[6'h1b]; 81 | 82 | wire inst_add = opcode_d[6'h0] & shamt_d[5'h0] & func_d[6'h20]; 83 | wire inst_addu = opcode_d[6'h0] & shamt_d[5'h0] & func_d[6'h21]; 84 | wire inst_sub = opcode_d[6'h0] & shamt_d[5'h0] & func_d[6'h22]; 85 | wire inst_subu = opcode_d[6'h0] & shamt_d[5'h0] & func_d[6'h23]; 86 | wire inst_and = opcode_d[6'h0] & shamt_d[5'h0] & func_d[6'h24]; 87 | wire inst_or = opcode_d[6'h0] & shamt_d[5'h0] & func_d[6'h25]; 88 | wire inst_xor = opcode_d[6'h0] & shamt_d[5'h0] & func_d[6'h26]; 89 | wire inst_nor = opcode_d[6'h0] & shamt_d[5'h0] & func_d[6'h27]; 90 | 91 | wire inst_slts = opcode_d[6'h0] & shamt_d[5'h0] & func_d[6'h2a]; 92 | wire inst_sltu = opcode_d[6'h0] & shamt_d[5'h0] & func_d[6'h2b]; 93 | 94 | wire inst_bltz = opcode_d[6'h01] & rt_d[5'h00]; 95 | wire inst_bgez = opcode_d[6'h01] & rt_d[5'h01]; 96 | wire inst_bltzal = opcode_d[6'h01] & rt_d[5'h10]; 97 | wire inst_bgezal = opcode_d[6'h01] & rt_d[5'h11]; 98 | 99 | wire inst_j = opcode_d[6'h02]; 100 | wire inst_jal = opcode_d[6'h03]; 101 | 102 | wire inst_beq = opcode_d[6'h04]; 103 | wire inst_bne = opcode_d[6'h05]; 104 | wire inst_blez = opcode_d[6'h06] & rt_d[5'h0]; 105 | wire inst_bgtz = opcode_d[6'h07] & rt_d[5'h0]; 106 | 107 | wire inst_addi = opcode_d[6'h08]; 108 | wire inst_addiu = opcode_d[6'h09]; 109 | wire inst_sltis = opcode_d[6'h0a]; 110 | wire inst_sltiu = opcode_d[6'h0b]; 111 | wire inst_andi = opcode_d[6'h0c]; 112 | wire inst_ori = opcode_d[6'h0d]; 113 | wire inst_xori = opcode_d[6'h0e]; 114 | wire inst_lui = opcode_d[6'h0f] & rs_d[5'h0]; 115 | 116 | wire inst_eret = opcode_d[6'h10] & rs_d[5'h10] & rt_d[5'h0] & rd_d[5'h0] & shamt_d[5'h0] & func_d[6'h18]; 117 | wire inst_mfc0 = opcode_d[6'h10] & rs_d[5'h00] & shamt_d[5'h0] & (func[5:3] == 3'd0); 118 | wire inst_mtc0 = opcode_d[6'h10] & rs_d[5'h04] & shamt_d[5'h0] & (func[5:3] == 3'd0); 119 | 120 | wire inst_lb = opcode_d[6'h20]; 121 | wire inst_lh = opcode_d[6'h21]; 122 | wire inst_lwl = opcode_d[6'h22]; 123 | wire inst_lw = opcode_d[6'h23]; 124 | wire inst_lbu = opcode_d[6'h24]; 125 | wire inst_lhu = opcode_d[6'h25]; 126 | wire inst_lwr = opcode_d[6'h26]; 127 | 128 | wire inst_sb = opcode_d[6'h28]; 129 | wire inst_sh = opcode_d[6'h29]; 130 | wire inst_swl = opcode_d[6'h2a]; 131 | wire inst_sw = opcode_d[6'h2b]; 132 | wire inst_swr = opcode_d[6'h2e]; 133 | //----------decode---------- 134 | 135 | wire inst_load = inst_lw | inst_lb | inst_lbu | inst_lh | inst_lhu | inst_lwl | inst_lwr; 136 | wire inst_store = inst_sw | inst_sb | inst_sh | inst_swl | inst_swr; 137 | assign align_load = {inst_lw, inst_lb, inst_lbu, inst_lh, inst_lhu, inst_lwl, inst_lwr}; 138 | assign align_store = {inst_sw, inst_sb, inst_sh, inst_swl, inst_swr}; 139 | assign alu_op = {inst_sra | inst_srav, inst_srl | inst_srlv, inst_sll | inst_sllv | inst_lui, 140 | inst_sltu | inst_sltiu, inst_slts | inst_sltis, 141 | inst_nor, inst_xor | inst_xori, inst_or | inst_ori, inst_and | inst_andi, 142 | inst_sub | inst_subu | inst_beq | inst_bne, 143 | inst_add | inst_addu | inst_addi | inst_addiu | inst_load | inst_store}; 144 | assign mf_hi_lo = {inst_mfhi, inst_mflo}; 145 | assign mt_hi_lo = {inst_mthi, inst_mtlo}; 146 | assign mul_div = {inst_mul | inst_div, inst_mul | inst_mulu, inst_div | inst_divu}; 147 | 148 | assign jump_reg = inst_jr | inst_jalr; 149 | assign jump_imm = inst_j | inst_jal; 150 | assign branch[0] = inst_beq | inst_bne; 151 | assign branch[1] = inst_bgtz; 152 | assign branch[2] = inst_bgez | inst_bgezal; 153 | assign branch[3] = inst_bltz | inst_bltzal; 154 | assign branch[4] = inst_blez; 155 | 156 | wire inst_ALI = inst_addi | inst_addiu | 157 | inst_andi | inst_ori | inst_xori | 158 | inst_sltis | inst_sltiu | inst_lui; 159 | wire inst_ALR = inst_add | inst_addu | inst_sub | inst_subu | inst_slts | inst_sltu | 160 | inst_and | inst_or | inst_xor | inst_nor | 161 | inst_sll | inst_sllv | inst_srl | inst_srlv | inst_sra | inst_srav; 162 | 163 | assign rf_waddr_src[0] = inst_ALI | inst_load | inst_mfc0; //rt 164 | assign rf_waddr_src[1] = inst_jalr | inst_ALR | inst_mfhi | inst_mflo; //rd 165 | assign rf_waddr_src[2] = inst_jal | inst_bgezal | inst_bltzal; //31-st 166 | 167 | assign rf_wdata_src[0] = inst_ALR | inst_ALI | inst_mfhi | inst_mflo | inst_mfc0; //alu_out_MA 168 | assign rf_wdata_src[1] = inst_jal | inst_jalr | inst_bgezal | inst_bltzal; //alu_out_EX 169 | assign rf_wdata_src[2] = inst_load; //mem_data 170 | 171 | assign rf_wen = inst_jal | inst_jalr | inst_bgezal | inst_bltzal | 172 | inst_ALR | inst_ALI | inst_load | inst_mfhi | inst_mflo | inst_mfc0; 173 | 174 | wire inst_shift_shamt = inst_sll | inst_srl | inst_sra; 175 | 176 | assign alu_src1[0] = (inst_ALR & ~inst_shift_shamt) | 177 | (inst_ALI & ~inst_lui) | 178 | inst_load | inst_store; //rf_A 179 | assign alu_src1[1] = inst_shift_shamt; //{27'd0, inst_shamt} 180 | assign alu_src1[2] = inst_lui; //32'd16 181 | 182 | assign alu_src2[0] = inst_ALR; //rf_B 183 | assign alu_src2[1] = inst_sltis | inst_sltiu | inst_addi | inst_addiu | 184 | inst_load | inst_store; //inst_imm_I_se 185 | assign alu_src2[2] = inst_andi | inst_ori | inst_xori | inst_lui; //inst_imm_I_ze 186 | 187 | assign mem_read = inst_load; 188 | assign mem_write = inst_store; 189 | 190 | assign eret = inst_eret; 191 | assign mfc0 = inst_mfc0; 192 | assign mtc0 = inst_mtc0; 193 | assign trap = {inst_break, inst_syscall}; 194 | 195 | assign overflow_exception = inst_add | inst_sub | inst_addi; 196 | 197 | assign reserved_inst = !( 198 | inst_sll | inst_srl | inst_sra | 199 | inst_sllv | inst_srlv | inst_srav | 200 | inst_jr | inst_jalr | 201 | inst_syscall | inst_break | 202 | inst_mfhi | inst_mthi | inst_mflo | inst_mtlo | 203 | inst_mul | inst_mulu | inst_div | inst_divu | 204 | inst_add | inst_addu | inst_sub | inst_subu | 205 | inst_and | inst_or | inst_xor | inst_nor | 206 | inst_slts | inst_sltu | 207 | inst_bltz | inst_bgez | inst_bltzal | inst_bgezal | 208 | inst_j | inst_jal | 209 | inst_beq | inst_bne | inst_blez | inst_bgtz | 210 | inst_addi | inst_addiu | inst_sltis | inst_sltiu | 211 | inst_andi | inst_ori | inst_xori | inst_lui | 212 | inst_eret | inst_mfc0 | inst_mtc0 | 213 | inst_load | inst_store 214 | ); 215 | 216 | endmodule 217 | 218 | module decoder_5_32( 219 | input [ 4 : 0] in, 220 | output [31 : 0] out 221 | ); 222 | 223 | wire [3 : 0] high; 224 | wire [7 : 0] low; 225 | 226 | assign high[3] = ( in[4]) & ( in[3]); 227 | assign high[2] = ( in[4]) & (~in[3]); 228 | assign high[1] = (~in[4]) & ( in[3]); 229 | assign high[0] = (~in[4]) & (~in[3]); 230 | 231 | assign low[7] = ( in[2]) & ( in[1]) & ( in[0]); 232 | assign low[6] = ( in[2]) & ( in[1]) & (~in[0]); 233 | assign low[5] = ( in[2]) & (~in[1]) & ( in[0]); 234 | assign low[4] = ( in[2]) & (~in[1]) & (~in[0]); 235 | assign low[3] = (~in[2]) & ( in[1]) & ( in[0]); 236 | assign low[2] = (~in[2]) & ( in[1]) & (~in[0]); 237 | assign low[1] = (~in[2]) & (~in[1]) & ( in[0]); 238 | assign low[0] = (~in[2]) & (~in[1]) & (~in[0]); 239 | 240 | assign out[31] = high[3] & low[7]; 241 | assign out[30] = high[3] & low[6]; 242 | assign out[29] = high[3] & low[5]; 243 | assign out[28] = high[3] & low[4]; 244 | assign out[27] = high[3] & low[3]; 245 | assign out[26] = high[3] & low[2]; 246 | assign out[25] = high[3] & low[1]; 247 | assign out[24] = high[3] & low[0]; 248 | assign out[23] = high[2] & low[7]; 249 | assign out[22] = high[2] & low[6]; 250 | assign out[21] = high[2] & low[5]; 251 | assign out[20] = high[2] & low[4]; 252 | assign out[19] = high[2] & low[3]; 253 | assign out[18] = high[2] & low[2]; 254 | assign out[17] = high[2] & low[1]; 255 | assign out[16] = high[2] & low[0]; 256 | assign out[15] = high[1] & low[7]; 257 | assign out[14] = high[1] & low[6]; 258 | assign out[13] = high[1] & low[5]; 259 | assign out[12] = high[1] & low[4]; 260 | assign out[11] = high[1] & low[3]; 261 | assign out[10] = high[1] & low[2]; 262 | assign out[ 9] = high[1] & low[1]; 263 | assign out[ 8] = high[1] & low[0]; 264 | assign out[ 7] = high[0] & low[7]; 265 | assign out[ 6] = high[0] & low[6]; 266 | assign out[ 5] = high[0] & low[5]; 267 | assign out[ 4] = high[0] & low[4]; 268 | assign out[ 3] = high[0] & low[3]; 269 | assign out[ 2] = high[0] & low[2]; 270 | assign out[ 1] = high[0] & low[1]; 271 | assign out[ 0] = high[0] & low[0]; 272 | 273 | endmodule 274 | 275 | module decoder_6_64( 276 | input [ 5 : 0] in, 277 | output [63 : 0] out 278 | ); 279 | 280 | wire [7 : 0] high; 281 | wire [7 : 0] low; 282 | 283 | assign high[7] = ( in[5]) & ( in[4]) & ( in[3]); 284 | assign high[6] = ( in[5]) & ( in[4]) & (~in[3]); 285 | assign high[5] = ( in[5]) & (~in[4]) & ( in[3]); 286 | assign high[4] = ( in[5]) & (~in[4]) & (~in[3]); 287 | assign high[3] = (~in[5]) & ( in[4]) & ( in[3]); 288 | assign high[2] = (~in[5]) & ( in[4]) & (~in[3]); 289 | assign high[1] = (~in[5]) & (~in[4]) & ( in[3]); 290 | assign high[0] = (~in[5]) & (~in[4]) & (~in[3]); 291 | 292 | assign low[7] = ( in[2]) & ( in[1]) & ( in[0]); 293 | assign low[6] = ( in[2]) & ( in[1]) & (~in[0]); 294 | assign low[5] = ( in[2]) & (~in[1]) & ( in[0]); 295 | assign low[4] = ( in[2]) & (~in[1]) & (~in[0]); 296 | assign low[3] = (~in[2]) & ( in[1]) & ( in[0]); 297 | assign low[2] = (~in[2]) & ( in[1]) & (~in[0]); 298 | assign low[1] = (~in[2]) & (~in[1]) & ( in[0]); 299 | assign low[0] = (~in[2]) & (~in[1]) & (~in[0]); 300 | 301 | assign out[63] = high[7] & low[7]; 302 | assign out[62] = high[7] & low[6]; 303 | assign out[61] = high[7] & low[5]; 304 | assign out[60] = high[7] & low[4]; 305 | assign out[59] = high[7] & low[3]; 306 | assign out[58] = high[7] & low[2]; 307 | assign out[57] = high[7] & low[1]; 308 | assign out[56] = high[7] & low[0]; 309 | assign out[55] = high[6] & low[7]; 310 | assign out[54] = high[6] & low[6]; 311 | assign out[53] = high[6] & low[5]; 312 | assign out[52] = high[6] & low[4]; 313 | assign out[51] = high[6] & low[3]; 314 | assign out[50] = high[6] & low[2]; 315 | assign out[49] = high[6] & low[1]; 316 | assign out[48] = high[6] & low[0]; 317 | assign out[47] = high[5] & low[7]; 318 | assign out[46] = high[5] & low[6]; 319 | assign out[45] = high[5] & low[5]; 320 | assign out[44] = high[5] & low[4]; 321 | assign out[43] = high[5] & low[3]; 322 | assign out[42] = high[5] & low[2]; 323 | assign out[41] = high[5] & low[1]; 324 | assign out[40] = high[5] & low[0]; 325 | assign out[39] = high[4] & low[7]; 326 | assign out[38] = high[4] & low[6]; 327 | assign out[37] = high[4] & low[5]; 328 | assign out[36] = high[4] & low[4]; 329 | assign out[35] = high[4] & low[3]; 330 | assign out[34] = high[4] & low[2]; 331 | assign out[33] = high[4] & low[1]; 332 | assign out[32] = high[4] & low[0]; 333 | assign out[31] = high[3] & low[7]; 334 | assign out[30] = high[3] & low[6]; 335 | assign out[29] = high[3] & low[5]; 336 | assign out[28] = high[3] & low[4]; 337 | assign out[27] = high[3] & low[3]; 338 | assign out[26] = high[3] & low[2]; 339 | assign out[25] = high[3] & low[1]; 340 | assign out[24] = high[3] & low[0]; 341 | assign out[23] = high[2] & low[7]; 342 | assign out[22] = high[2] & low[6]; 343 | assign out[21] = high[2] & low[5]; 344 | assign out[20] = high[2] & low[4]; 345 | assign out[19] = high[2] & low[3]; 346 | assign out[18] = high[2] & low[2]; 347 | assign out[17] = high[2] & low[1]; 348 | assign out[16] = high[2] & low[0]; 349 | assign out[15] = high[1] & low[7]; 350 | assign out[14] = high[1] & low[6]; 351 | assign out[13] = high[1] & low[5]; 352 | assign out[12] = high[1] & low[4]; 353 | assign out[11] = high[1] & low[3]; 354 | assign out[10] = high[1] & low[2]; 355 | assign out[ 9] = high[1] & low[1]; 356 | assign out[ 8] = high[1] & low[0]; 357 | assign out[ 7] = high[0] & low[7]; 358 | assign out[ 6] = high[0] & low[6]; 359 | assign out[ 5] = high[0] & low[5]; 360 | assign out[ 4] = high[0] & low[4]; 361 | assign out[ 3] = high[0] & low[3]; 362 | assign out[ 2] = high[0] & low[2]; 363 | assign out[ 1] = high[0] & low[1]; 364 | assign out[ 0] = high[0] & low[0]; 365 | 366 | endmodule 367 | -------------------------------------------------------------------------------- /rtl/myCPU/mycpu_top.v: -------------------------------------------------------------------------------- 1 | `include "alu_op.h" 2 | 3 | module mycpu_top( 4 | input aclk, 5 | input aresetn, 6 | 7 | input [5 : 0] int, 8 | 9 | //axi 10 | //ar 11 | output [ 3 : 0] arid, 12 | output [31 : 0] araddr, 13 | output [ 7 : 0] arlen, 14 | output [ 2 : 0] arsize, 15 | output [ 1 : 0] arburst, 16 | output [ 1 : 0] arlock, 17 | output [ 3 : 0] arcache, 18 | output [ 2 : 0] arprot, 19 | output arvalid, 20 | input arready, 21 | 22 | //r 23 | input [ 3 : 0] rid, 24 | input [31 : 0] rdata, 25 | input [ 1 : 0] rresp, 26 | input rlast, 27 | input rvalid, 28 | output rready, 29 | 30 | //aw 31 | output [ 3 : 0] awid, 32 | output [31 : 0] awaddr, 33 | output [ 7 : 0] awlen, 34 | output [ 2 : 0] awsize, 35 | output [ 1 : 0] awburst, 36 | output [ 1 : 0] awlock, 37 | output [ 3 : 0] awcache, 38 | output [ 2 : 0] awprot, 39 | output awvalid, 40 | input awready, 41 | 42 | //w 43 | output [ 3 : 0] wid, 44 | output [31 : 0] wdata, 45 | output [ 3 : 0] wstrb, 46 | output wlast, 47 | output wvalid, 48 | input wready, 49 | 50 | //b 51 | input [3 : 0] bid, 52 | input [1 : 0] bresp, 53 | input bvalid, 54 | output bready, 55 | 56 | //debug 57 | output [31 : 0] debug_wb_pc, 58 | output [ 3 : 0] debug_wb_rf_wen, 59 | output [ 4 : 0] debug_wb_rf_wnum, 60 | output [31 : 0] debug_wb_rf_wdata 61 | ); 62 | 63 | wire rst_p = ~aresetn; 64 | wire clk = aclk; 65 | 66 | wire interlayer_IF_ready; 67 | wire interlayer_MA_ready; 68 | wire interlayer_WB_ready; 69 | wire IF_enable; 70 | wire IF_ready; 71 | wire DE_enable; 72 | wire DE_ready; 73 | wire EX_enable; 74 | wire EX_ready; 75 | wire MA_enable; 76 | wire MA_ready; 77 | wire WB_enable; 78 | 79 | wire [31 : 0] IF_PC, DE_PC, EX_PC, MA_PC; 80 | 81 | wire [31 : 0] IF_mem_addr; 82 | wire [31 : 0] IF_mem_rdata; 83 | wire MA_mem_read; 84 | wire MA_mem_write; 85 | wire [ 3 : 0] MA_mem_wstrb; 86 | wire [31 : 0] MA_mem_addr; 87 | wire [ 2 : 0] MA_mem_size; 88 | wire [31 : 0] MA_mem_wdata; 89 | wire [31 : 0] WB_mem_rdata; 90 | 91 | wire PC_modified; 92 | wire [31 : 0] PC_modified_data; 93 | wire [31 : 0] IF_inst; 94 | 95 | wire [2 : 0] DE_EX_alu_src1; 96 | wire [2 : 0] DE_EX_alu_src2; 97 | wire [`OP_NUM - 1 : 0] DE_EX_alu_op; 98 | 99 | wire [1 : 0] DE_EX_mf_hi_lo; 100 | wire [1 : 0] DE_EX_mt_hi_lo; 101 | wire [2 : 0] DE_EX_mul_div; 102 | wire [1 : 0] EX_MA_mf_hi_lo; 103 | wire [1 : 0] EX_MA_mt_hi_lo; 104 | wire [2 : 0] EX_MA_mul_div; 105 | 106 | wire DE_EX_mem_read, EX_MA_mem_read, MA_WB_mem_read; 107 | wire DE_EX_mem_write, EX_MA_mem_write; 108 | 109 | wire [ 4 : 0] rf_raddr1; 110 | wire [ 4 : 0] rf_raddr2; 111 | wire [31 : 0] rf_rdata1; 112 | wire [31 : 0] rf_rdata2; 113 | wire [31 : 0] drf_rdata1; 114 | wire [31 : 0] drf_rdata2; 115 | wire forward_waiting; 116 | wire forward_isbr; 117 | wire [ 4 : 0] forward_raddr1; 118 | wire [ 4 : 0] forward_raddr2; 119 | wire [31 : 0] forward_rdata1; 120 | wire [31 : 0] forward_rdata2; 121 | wire [ 4 : 0] rf_waddr; 122 | wire [31 : 0] rf_wdata; 123 | wire rf_wen; 124 | 125 | wire [ 4 : 0] DE_EX_rf_waddr; 126 | wire [ 2 : 0] DE_EX_rf_wdata_src; 127 | wire DE_EX_rf_wen; 128 | wire [ 4 : 0] EX_MA_rf_waddr; 129 | wire [ 2 : 0] EX_MA_rf_wdata_src; 130 | wire EX_MA_rf_wen; 131 | wire [ 4 : 0] MA_WB_rf_waddr; 132 | wire [ 2 : 0] MA_WB_rf_wdata_src; 133 | wire MA_WB_rf_wen; 134 | 135 | wire [15 : 0] DE_EX_imm_16; 136 | 137 | wire [31 : 0] DE_EX_rf_A, EX_MA_rf_A; 138 | wire [31 : 0] DE_EX_rf_B, EX_MA_rf_B, MA_WB_rf_B; 139 | 140 | wire [31 : 0] EX_alu_res; 141 | wire [31 : 0] MA_alu_res; 142 | 143 | wire EX_valid, MA_valid, WB_valid; 144 | 145 | wire WB_rf_wen; 146 | wire MA_leaving; 147 | wire WB_leaving; 148 | 149 | wire mul_div_done; 150 | wire [63 : 0] mul_div_res; 151 | 152 | wire [6 : 0] DE_EX_align_load, EX_MA_align_load, MA_WB_align_load; 153 | wire [4 : 0] DE_EX_align_store, EX_MA_align_store; 154 | 155 | wire [4 : 0] IF_DE_exccode, DE_EX_exccode, EX_MA_exccode, MA_exccode; 156 | 157 | wire exception_taken; 158 | wire [31 : 0] exception_handler_entry; 159 | 160 | wire empty_exception = exception_taken; 161 | 162 | wire [4 : 0] EX_MA_inst_rd; 163 | 164 | wire DE_EX_mfc0, EX_MA_mfc0; 165 | wire DE_EX_mtc0, EX_MA_mtc0; 166 | wire DE_EX_eret, EX_MA_eret, MA_eret; 167 | 168 | wire [ 4 : 0] MA_cp0_addr; 169 | wire [31 : 0] MA_cp0_rdata; 170 | wire [31 : 0] MA_cp0_wdata; 171 | wire MA_cp0_wen; 172 | 173 | wire [31 : 0] epc; 174 | 175 | wire DE_EX_in_delay_slot, EX_MA_in_delay_slot, MA_in_delay_slot; 176 | wire DE_EX_address_error_IF, EX_MA_address_error_IF, MA_address_error_IF; 177 | wire overflow_exception; 178 | 179 | wire IF_skip; 180 | 181 | wire inst_req; 182 | wire [31 : 0] inst_addr; 183 | wire [31 : 0] inst_rdata; 184 | wire inst_addr_ok; 185 | wire inst_data_ok; 186 | wire [31 : 0] inst_addr_done; 187 | 188 | wire data_req; 189 | wire data_wr; 190 | wire [31 : 0] data_addr; 191 | wire [ 2 : 0] data_size; 192 | wire [ 3 : 0] data_wstrb; 193 | wire [31 : 0] data_wdata; 194 | wire [31 : 0] data_rdata; 195 | wire data_write_ok; 196 | wire data_data_ok; 197 | wire data_busy; 198 | 199 | cache cache( 200 | .clk (clk), 201 | .rst_p (rst_p), 202 | 203 | //inst sram_like 204 | .inst_req (inst_req), 205 | .inst_addr (inst_addr), 206 | .inst_rdata (inst_rdata), 207 | .inst_addr_ok (inst_addr_ok), 208 | .inst_data_ok (inst_data_ok), 209 | 210 | //data sram_like 211 | .data_req (data_req), 212 | .data_wr (data_wr), 213 | .data_addr (data_addr), 214 | .data_size (data_size), 215 | .data_wstrb (data_wstrb), 216 | .data_wdata (data_wdata), 217 | .data_rdata (data_rdata), 218 | .data_write_ok (data_write_ok), 219 | .data_data_ok (data_data_ok), 220 | .data_busy (data_busy), 221 | 222 | //axi 223 | //ar 224 | .arid (arid), 225 | .araddr (araddr), 226 | .arlen (arlen), 227 | .arsize (arsize), 228 | .arburst (arburst), 229 | .arlock (arlock), 230 | .arcache (arcache), 231 | .arprot (arprot), 232 | .arvalid (arvalid), 233 | .arready (arready), 234 | 235 | //r 236 | .rid (rid), 237 | .rdata (rdata), 238 | .rresp (rresp), 239 | .rlast (rlast), 240 | .rvalid (rvalid), 241 | .rready (rready), 242 | 243 | //aw 244 | .awid (awid), 245 | .awaddr (awaddr), 246 | .awlen (awlen), 247 | .awsize (awsize), 248 | .awburst (awburst), 249 | .awlock (awlock), 250 | .awcache (awcache), 251 | .awprot (awprot), 252 | .awvalid (awvalid), 253 | .awready (awready), 254 | 255 | //w 256 | .wid (wid), 257 | .wdata (wdata), 258 | .wstrb (wstrb), 259 | .wlast (wlast), 260 | .wvalid (wvalid), 261 | .wready (wready), 262 | 263 | //b 264 | .bid (bid), 265 | .bresp (bresp), 266 | .bvalid (bvalid), 267 | .bready (bready) 268 | ); 269 | 270 | interlayer interlayer( 271 | .clk (clk), 272 | .rst_p (rst_p), 273 | 274 | //---IF--- 275 | .IF_enable (IF_enable), 276 | .IF_skip (IF_skip), 277 | .interlayer_IF_ready (interlayer_IF_ready), 278 | 279 | .IF_mem_addr (IF_mem_addr), 280 | .IF_mem_rdata (IF_mem_rdata), 281 | 282 | .inst_req (inst_req), 283 | .inst_addr (inst_addr), 284 | .inst_rdata (inst_rdata), 285 | .inst_addr_ok (inst_addr_ok), 286 | .inst_data_ok (inst_data_ok), 287 | //---IF--- 288 | 289 | //---WB--- 290 | .MA_mem_read (MA_mem_read), 291 | .MA_mem_write (MA_mem_write), 292 | .interlayer_MA_ready (interlayer_MA_ready), 293 | .interlayer_WB_ready (interlayer_WB_ready), 294 | .MA_mem_wstrb (MA_mem_wstrb), 295 | .MA_mem_addr (MA_mem_addr), 296 | .MA_mem_size (MA_mem_size), 297 | .MA_mem_wdata (MA_mem_wdata), 298 | .WB_mem_rdata (WB_mem_rdata), 299 | 300 | .data_req (data_req), 301 | .data_wr (data_wr), 302 | .data_addr (data_addr), 303 | .data_size (data_size), 304 | .data_wstrb (data_wstrb), 305 | .data_wdata (data_wdata), 306 | .data_rdata (data_rdata), 307 | .data_data_ok (data_data_ok), 308 | .data_write_ok (data_write_ok) 309 | //---MA--- 310 | ); 311 | 312 | IF IF( 313 | .clk (clk), 314 | .rst_p (rst_p), 315 | .empty (1'd0), 316 | 317 | //pipeline signals 318 | .interlayer_ready (interlayer_IF_ready), 319 | .IF_enable (IF_enable), 320 | .IF_ready (IF_ready), 321 | .DE_enable (DE_enable), 322 | 323 | //memory access signals 324 | .IF_skip (IF_skip), 325 | .IF_mem_addr (IF_mem_addr), 326 | .IF_mem_rdata (IF_mem_rdata), 327 | 328 | //interact with DE 329 | .eret (DE_EX_eret), 330 | .PC_modified (PC_modified), 331 | .PC_modified_data (PC_modified_data), 332 | .IF_PC (IF_PC), 333 | .inst_out (IF_inst), 334 | .exccode_out (IF_DE_exccode), 335 | 336 | //interact with exception 337 | .exception (exception_taken), 338 | .exception_handler_entry (exception_handler_entry), 339 | .epc (epc) 340 | ); 341 | 342 | DE DE( 343 | .clk (clk), 344 | .rst_p (rst_p), 345 | .empty (empty_exception), 346 | 347 | //pipeline signals 348 | .IF_ready (IF_ready), 349 | .DE_enable (DE_enable), 350 | .DE_ready (DE_ready), 351 | .EX_enable (EX_enable), 352 | 353 | //interact with IF 354 | .inst_in (IF_inst), 355 | .IF_PC (IF_PC), 356 | .PC_modified (PC_modified), 357 | .PC_modified_data (PC_modified_data), 358 | .exccode_in (IF_DE_exccode), 359 | 360 | //interact with forward 361 | .waiting (forward_waiting), 362 | .isbr (forward_isbr), 363 | .rf_raddr1 (forward_raddr1), 364 | .rf_raddr2 (forward_raddr2), 365 | .rf_rdata1 (forward_rdata1), 366 | .rf_rdata2 (forward_rdata2), 367 | .drf_rdata1 (rf_rdata1), 368 | .drf_rdata2 (rf_rdata2), 369 | 370 | //interact with EX 371 | .rf_waddr_out (DE_EX_rf_waddr), 372 | .rf_wdata_src_out (DE_EX_rf_wdata_src), 373 | .rf_wen_out (DE_EX_rf_wen), 374 | 375 | .alu_src1_out (DE_EX_alu_src1), 376 | .alu_src2_out (DE_EX_alu_src2), 377 | .alu_op_out (DE_EX_alu_op), 378 | .mf_hi_lo_out (DE_EX_mf_hi_lo), 379 | .mt_hi_lo_out (DE_EX_mt_hi_lo), 380 | .mul_div_out (DE_EX_mul_div), 381 | 382 | .mem_read_out (DE_EX_mem_read), 383 | .mem_write_out (DE_EX_mem_write), 384 | .align_load_out (DE_EX_align_load), 385 | .align_store_out (DE_EX_align_store), 386 | 387 | .eret_out (DE_EX_eret), 388 | .mfc0_out (DE_EX_mfc0), 389 | .mtc0_out (DE_EX_mtc0), 390 | 391 | .imm_16_out (DE_EX_imm_16), 392 | 393 | .rf_A_out (DE_EX_rf_A), 394 | .rf_B_out (DE_EX_rf_B), 395 | 396 | .DE_PC (DE_PC), 397 | 398 | .in_delay_slot_out (DE_EX_in_delay_slot), 399 | .address_error_IF_out (DE_EX_address_error_IF), 400 | .overflow_exception_out (overflow_exception), 401 | .exccode_out (DE_EX_exccode) 402 | ); 403 | 404 | forward forward( 405 | .clk (clk), 406 | .rst_p (rst_p), 407 | .empty (empty_exception), 408 | 409 | .EX_rf_waddr (EX_MA_rf_waddr), 410 | .MA_rf_waddr (MA_WB_rf_waddr), 411 | .WB_rf_waddr (rf_waddr), 412 | 413 | .EX_rf_wen (EX_MA_rf_wen), 414 | .MA_rf_wen (MA_WB_rf_wen), 415 | .WB_rf_wen (WB_rf_wen), 416 | 417 | .EX_valid (EX_valid), 418 | .MA_valid (MA_valid), 419 | .WB_valid (WB_valid), 420 | 421 | .MA_leaving (MA_leaving), 422 | .WB_leaving (WB_leaving), 423 | 424 | .EX_mem_read (EX_MA_mem_read), 425 | .MA_mem_read (MA_WB_mem_read), 426 | .EX_mf ((EX_MA_mf_hi_lo != 2'd0) || EX_MA_mfc0), 427 | 428 | .EX_alu_res (EX_alu_res), 429 | .MA_alu_res (MA_alu_res), 430 | .WB_rf_wdata (rf_wdata), 431 | 432 | .rf_raddr1 (rf_raddr1), 433 | .rf_raddr2 (rf_raddr2), 434 | .rf_rdata1 (rf_rdata1), 435 | .rf_rdata2 (rf_rdata2), 436 | 437 | .raddr1 (forward_raddr1), 438 | .raddr2 (forward_raddr2), 439 | .rdata1 (forward_rdata1), 440 | .rdata2 (forward_rdata2), 441 | 442 | .waiting (forward_waiting), 443 | .isbr (forward_isbr) 444 | ); 445 | 446 | rf rf 447 | ( 448 | .clk (clk), 449 | .rst_p (rst_p), 450 | .raddr1 (rf_raddr1), 451 | .raddr2 (rf_raddr2), 452 | .rdata1 (rf_rdata1), 453 | .rdata2 (rf_rdata2), 454 | .wen (rf_wen), 455 | .waddr (rf_waddr), 456 | .wdata (rf_wdata) 457 | ); 458 | 459 | EX EX( 460 | .clk (clk), 461 | .rst_p (rst_p), 462 | .empty (empty_exception), 463 | 464 | //pipeline signals 465 | .DE_ready (DE_ready), 466 | .EX_enable (EX_enable), 467 | .EX_ready (EX_ready), 468 | .MA_enable (MA_enable), 469 | 470 | //interact with DE 471 | .rf_waddr_in (DE_EX_rf_waddr), 472 | .rf_wdata_src_in (DE_EX_rf_wdata_src), 473 | .rf_wen_in (DE_EX_rf_wen), 474 | 475 | .alu_src1_in (DE_EX_alu_src1), 476 | .alu_src2_in (DE_EX_alu_src2), 477 | .alu_op_in (DE_EX_alu_op), 478 | .mf_hi_lo_in (DE_EX_mf_hi_lo), 479 | .mt_hi_lo_in (DE_EX_mt_hi_lo), 480 | .mul_div_in (DE_EX_mul_div), 481 | 482 | .mem_read_in (DE_EX_mem_read), 483 | .mem_write_in (DE_EX_mem_write), 484 | .align_load_in (DE_EX_align_load), 485 | .align_store_in (DE_EX_align_store), 486 | 487 | .eret_in (DE_EX_eret), 488 | .mfc0_in (DE_EX_mfc0), 489 | .mtc0_in (DE_EX_mtc0), 490 | 491 | .imm_16_in (DE_EX_imm_16), 492 | 493 | .rf_A_in (DE_EX_rf_A), 494 | .rf_B_in (DE_EX_rf_B), 495 | 496 | .DE_PC (DE_PC), 497 | 498 | .in_delay_slot_in (DE_EX_in_delay_slot), 499 | .address_error_IF_in (DE_EX_address_error_IF), 500 | .overflow_exception_in (overflow_exception), 501 | .exccode_in (DE_EX_exccode), 502 | 503 | //interact with MA && mul_div 504 | .inst_rd_out (EX_MA_inst_rd), 505 | 506 | .rf_A_out (EX_MA_rf_A), 507 | .rf_B_out (EX_MA_rf_B), 508 | 509 | .rf_waddr_out (EX_MA_rf_waddr), 510 | .rf_wdata_src_out (EX_MA_rf_wdata_src), 511 | .rf_wen_out (EX_MA_rf_wen), 512 | .mf_hi_lo_out (EX_MA_mf_hi_lo), 513 | .mt_hi_lo_out (EX_MA_mt_hi_lo), 514 | .mul_div_out (EX_MA_mul_div), 515 | 516 | .mem_read_out (EX_MA_mem_read), 517 | .mem_write_out (EX_MA_mem_write), 518 | .align_load_out (EX_MA_align_load), 519 | .align_store_out (EX_MA_align_store), 520 | 521 | .eret_out (EX_MA_eret), 522 | .mfc0_out (EX_MA_mfc0), 523 | .mtc0_out (EX_MA_mtc0), 524 | 525 | .alu_res_out (EX_alu_res), 526 | 527 | .EX_PC (EX_PC), 528 | 529 | .in_delay_slot_out (EX_MA_in_delay_slot), 530 | .address_error_IF_out (EX_MA_address_error_IF), 531 | .exccode_out (EX_MA_exccode), 532 | 533 | //interact with forward 534 | .valid_out (EX_valid) 535 | ); 536 | 537 | mul_div mul_div( 538 | .clk (clk), 539 | .rst_p (rst_p), 540 | 541 | .A (EX_MA_rf_A), 542 | .B (EX_MA_rf_B), 543 | 544 | .mul_div (EX_MA_mul_div), 545 | .done (mul_div_done), 546 | 547 | .res (mul_div_res) 548 | ); 549 | 550 | MA MA( 551 | .clk (clk), 552 | .rst_p (rst_p), 553 | .empty (empty_exception), 554 | 555 | //pipeline signals 556 | .EX_ready (EX_ready), 557 | .MA_enable (MA_enable), 558 | .MA_ready (MA_ready), 559 | .WB_enable (WB_enable), 560 | 561 | //memory access signals 562 | .interlayer_ready (interlayer_MA_ready), 563 | .MA_mem_read (MA_mem_read), 564 | .MA_mem_write (MA_mem_write), 565 | .MA_mem_wstrb (MA_mem_wstrb), 566 | .MA_mem_addr (MA_mem_addr), 567 | .MA_mem_size (MA_mem_size), 568 | .MA_mem_wdata (MA_mem_wdata), 569 | .mem_busy (data_busy), 570 | 571 | //interact with EX 572 | .inst_rd_in (EX_MA_inst_rd), 573 | 574 | .rf_A_in (EX_MA_rf_A), 575 | .rf_B_in (EX_MA_rf_B), 576 | 577 | .rf_waddr_in (EX_MA_rf_waddr), 578 | .rf_wdata_src_in (EX_MA_rf_wdata_src), 579 | .rf_wen_in (EX_MA_rf_wen), 580 | .mf_hi_lo_in (EX_MA_mf_hi_lo), 581 | .mt_hi_lo_in (EX_MA_mt_hi_lo), 582 | .mul_div_in (EX_MA_mul_div), 583 | 584 | .mem_read_in (EX_MA_mem_read), 585 | .mem_write_in (EX_MA_mem_write), 586 | .align_load_in (EX_MA_align_load), 587 | .align_store_in (EX_MA_align_store), 588 | 589 | .eret_in (EX_MA_eret), 590 | .mfc0_in (EX_MA_mfc0), 591 | .mtc0_in (EX_MA_mtc0), 592 | 593 | .alu_res_in (EX_alu_res), 594 | 595 | .EX_PC (EX_PC), 596 | 597 | .in_delay_slot_in (EX_MA_in_delay_slot), 598 | .address_error_IF_in (EX_MA_address_error_IF), 599 | .exccode_in (EX_MA_exccode), 600 | 601 | //interact with WB 602 | .rf_B_out (MA_WB_rf_B), 603 | .rf_waddr_out (MA_WB_rf_waddr), 604 | .rf_wdata_src_out (MA_WB_rf_wdata_src), 605 | .rf_wen_out (MA_WB_rf_wen), 606 | .alu_res_out (MA_alu_res), 607 | .mem_read_out (MA_WB_mem_read), 608 | .align_load_out (MA_WB_align_load), 609 | 610 | .MA_PC (MA_PC), 611 | 612 | //interact with mul_div 613 | .mul_div_done_in (mul_div_done), 614 | .mul_div_res_in (mul_div_res), 615 | 616 | //interact with forward 617 | .valid_out (MA_valid), 618 | .leaving_out (MA_leaving), 619 | 620 | //interract with exception 621 | .in_delay_slot_out (MA_in_delay_slot), 622 | .address_error_IF_out (MA_address_error_IF), 623 | .cp0_addr (MA_cp0_addr), 624 | .cp0_rdata (MA_cp0_rdata), 625 | .cp0_wdata (MA_cp0_wdata), 626 | .mtc0_out (MA_cp0_wen), 627 | .eret_out (MA_eret), 628 | .exccode_out (MA_exccode) 629 | ); 630 | 631 | WB WB( 632 | .clk (clk), 633 | .rst_p (rst_p), 634 | .empty (1'd0), 635 | 636 | //pipeline signals 637 | .MA_ready (MA_ready), 638 | .WB_enable (WB_enable), 639 | .interlayer_ready (interlayer_WB_ready), 640 | 641 | //interact with MA 642 | .rf_B_in (MA_WB_rf_B), 643 | .rf_waddr_in (MA_WB_rf_waddr), 644 | .rf_wdata_src_in (MA_WB_rf_wdata_src), 645 | .rf_wen_in (MA_WB_rf_wen), 646 | .alu_res_in (MA_alu_res), 647 | .mem_read_in (MA_WB_mem_read), 648 | .align_load_in (MA_WB_align_load), 649 | 650 | .MA_PC (MA_PC), 651 | 652 | //interact with interlayer 653 | .mem_data (WB_mem_rdata), 654 | 655 | //interact with rf 656 | .rf_waddr_out (rf_waddr), 657 | .rf_wdata_out (rf_wdata), 658 | .rf_wen_leaving (rf_wen), 659 | 660 | //interact with debug 661 | .debug_PC (debug_wb_pc), 662 | .debug_wb_rf_wen (debug_wb_rf_wen), 663 | .debug_wb_rf_waddr (debug_wb_rf_wnum), 664 | .debug_wb_rf_wdata (debug_wb_rf_wdata), 665 | 666 | //interact with forward 667 | .rf_wen_out (WB_rf_wen), 668 | .leaving_out (WB_leaving), 669 | .valid_out (WB_valid) 670 | ); 671 | 672 | exception exception( 673 | .clk (clk), 674 | .rst_p (rst_p), 675 | 676 | .hw_int (int), 677 | 678 | .MA_leaving (MA_leaving), 679 | .MA_valid (MA_valid), 680 | .MA_exccode (MA_exccode), 681 | .MA_eret (MA_eret), 682 | .MA_PC (MA_PC), 683 | .MA_alu_res (MA_alu_res), 684 | 685 | .WB_enable(WB_enable), 686 | 687 | .exception (exception_taken), 688 | .exception_handler_entry (exception_handler_entry), 689 | .epc_out (epc), 690 | 691 | .in_delay_slot (MA_in_delay_slot), 692 | .address_error_IF (MA_address_error_IF), 693 | 694 | .cp0_raddr (MA_cp0_addr), 695 | .cp0_rdata (MA_cp0_rdata), 696 | 697 | .cp0_wen (MA_cp0_wen), 698 | .cp0_waddr (MA_cp0_addr), 699 | .cp0_wdata (MA_cp0_wdata) 700 | ); 701 | 702 | endmodule 703 | -------------------------------------------------------------------------------- /rtl/myCPU/icache.v: -------------------------------------------------------------------------------- 1 | module icache( 2 | input clk, 3 | input resetn, 4 | 5 | input [11:0] pgOffsetIn, 6 | input pgOffsetValid, 7 | input [19:0] tagIn, 8 | input tagValid, 9 | 10 | output [31:0] dataOut, 11 | output dataOutReady, 12 | 13 | output [31:0] addr2Cache2, 14 | output addr2Cache2Valid, 15 | input [31:0] data2ICacheBlk1, 16 | input [31:0] data2ICacheBlk2, 17 | input [31:0] data2ICacheBlk3, 18 | input [31:0] data2ICacheBlk4, 19 | input [31:0] data2ICacheBlk5, 20 | input [31:0] data2ICacheBlk6, 21 | input [31:0] data2ICacheBlk7, 22 | input [31:0] data2ICacheBlk8, 23 | input dataRequestedReady, 24 | input data2ICacheBlkReady, 25 | 26 | output busy 27 | ); 28 | 29 | //I-cache global state machine definition. 30 | parameter FREE = 0; 31 | parameter PGOFF_OK = 1; 32 | parameter TAG_OK = 2; 33 | parameter WR_CTRL = 3; 34 | parameter SELECT = 4; 35 | parameter REQ_SND = 5; 36 | parameter REQ_RTN = 6; 37 | parameter BLK_RTN = 7; 38 | parameter WR_BLK = 8; 39 | 40 | //State machine. 41 | //Global reg: 42 | reg [4:0] stage; 43 | 44 | //stage TagOK reg: 45 | reg [ 19:0] tag; 46 | reg [ 11:0] pgOffset; 47 | 48 | wire [ 6:0] index; 49 | wire [ 4:0] blkOffset; 50 | wire [19:0] tagWay1; 51 | wire [19:0] tagWay2; 52 | wire [19:0] tagWay3; 53 | wire [19:0] tagWay4; 54 | wire [ 1:0] LRUWay1; 55 | wire [ 1:0] LRUWay2; 56 | wire [ 1:0] LRUWay3; 57 | wire [ 1:0] LRUWay4; 58 | wire validWay1; 59 | wire validWay2; 60 | wire validWay3; 61 | wire validWay4; 62 | wire iCacheHitWay1; 63 | wire iCacheHitWay2; 64 | wire iCacheHitWay3; 65 | wire iCacheHitWay4; 66 | wire iCacheHit; 67 | 68 | reg [31:0] valid [15:0]; 69 | wire [31:0] wayValids; 70 | wire [3:0] wayValid; 71 | wire [31:0] newWayValids; 72 | 73 | //stage Write Control & Select reg: 74 | reg [19:0] nxtTag; 75 | reg [ 6:0] nxtIndex; 76 | reg [ 4:0] nxtBlkOffset; 77 | reg [31:0] nxtWayValids; 78 | reg [19:0] nxtTagWay1; 79 | reg [19:0] nxtTagWay2; 80 | reg [19:0] nxtTagWay3; 81 | reg [19:0] nxtTagWay4; 82 | reg [ 1:0] nxtLRUWay1; 83 | reg [ 1:0] nxtLRUWay2; 84 | reg [ 1:0] nxtLRUWay3; 85 | reg [ 1:0] nxtLRUWay4; 86 | reg nxtValidWay1; 87 | reg nxtValidWay2; 88 | reg nxtValidWay3; 89 | reg nxtValidWay4; 90 | reg nxtICacheHitWay1; 91 | reg nxtICacheHitWay2; 92 | reg nxtICacheHitWay3; 93 | reg nxtICacheHitWay4; 94 | 95 | wire [1:0] refillIndex; 96 | 97 | //stage Request Send reg: 98 | reg [ 1:0] rsRefillIndex; 99 | reg [31:0] rsAddr; 100 | 101 | assign busy = (stage != FREE); 102 | 103 | always @(posedge clk) begin 104 | 105 | if (!resetn) begin 106 | stage <= FREE; 107 | end else begin 108 | //Free--(TLB hitted)-->TagOK. 109 | if ((stage == FREE) && tagValid && pgOffsetValid) begin 110 | stage <= TAG_OK; 111 | tag <= tagIn; 112 | pgOffset <= pgOffsetIn; 113 | end 114 | 115 | if (stage == TAG_OK) begin 116 | if (iCacheHit) begin 117 | //TagOK--(i-cache hitted)-->Write control block. 118 | stage <= FREE; 119 | end else begin 120 | //TagOK--(i-cache miss)-->Select. 121 | stage <= SELECT; 122 | end 123 | 124 | //use for write back. 125 | nxtTag <= tag; 126 | nxtIndex <= index; 127 | nxtBlkOffset <= blkOffset; 128 | nxtWayValids <= wayValids; 129 | 130 | //use for generate control information writed back. 131 | nxtTagWay1 <= tagWay1; 132 | nxtTagWay2 <= tagWay2; 133 | nxtTagWay3 <= tagWay3; 134 | nxtTagWay4 <= tagWay4; 135 | 136 | //use for decided the refill way number. 137 | nxtValidWay1 <= validWay1; 138 | nxtValidWay2 <= validWay2; 139 | nxtValidWay3 <= validWay3; 140 | nxtValidWay4 <= validWay4; 141 | 142 | //use for calculate new LRU number. 143 | nxtLRUWay1 <= LRUWay1; 144 | nxtLRUWay2 <= LRUWay2; 145 | nxtLRUWay3 <= LRUWay3; 146 | nxtLRUWay4 <= LRUWay4; 147 | 148 | //use for check which way hitted. 149 | nxtICacheHitWay1 <= iCacheHitWay1; 150 | nxtICacheHitWay2 <= iCacheHitWay2; 151 | nxtICacheHitWay3 <= iCacheHitWay3; 152 | nxtICacheHitWay4 <= iCacheHitWay4; 153 | end 154 | 155 | //Write control block---->Free. 156 | if (stage == WR_CTRL) begin 157 | stage <= FREE; 158 | end 159 | 160 | //Select--(Write control block at the same time)-->Request send. 161 | if (stage == SELECT) begin 162 | stage <= REQ_SND; 163 | rsRefillIndex <= refillIndex; 164 | rsAddr <= {nxtTag, nxtIndex, nxtBlkOffset}; 165 | end 166 | 167 | //Request send--(data requested and data block return simultaneously)-->Free. 168 | if (stage == REQ_SND && dataRequestedReady && data2ICacheBlkReady) begin 169 | stage <= FREE; 170 | end 171 | end 172 | end 173 | 174 | //Free stage: when pgOffset is ok, we should read control block. 175 | wire [ 6:0] preIndex; 176 | 177 | assign preIndex = pgOffsetIn[11:5]; 178 | 179 | //TagOk stage: Look up control block to decided whether address hits i-cache. 180 | wire [95:0] ctrlBlkOut; 181 | 182 | assign index = pgOffset[11:5]; 183 | assign blkOffset = pgOffset[ 4:0]; 184 | 185 | assign tagWay1 = ctrlBlkOut[19: 0]; 186 | assign tagWay2 = ctrlBlkOut[43:24]; 187 | assign tagWay3 = ctrlBlkOut[67:48]; 188 | assign tagWay4 = ctrlBlkOut[91:72]; 189 | 190 | //control ram 191 | wire ctrlBlkWrite; 192 | wire ctrlBlkRead; 193 | wire [6:0] ctrlBlkAddr; 194 | 195 | always @(posedge clk) begin 196 | if (!resetn) begin 197 | valid[0] <= 16'd0; 198 | valid[1] <= 16'd0; 199 | valid[2] <= 16'd0; 200 | valid[3] <= 16'd0; 201 | valid[4] <= 16'd0; 202 | valid[5] <= 16'd0; 203 | valid[6] <= 16'd0; 204 | valid[7] <= 16'd0; 205 | valid[8] <= 16'd0; 206 | valid[9] <= 16'd0; 207 | valid[10] <= 16'd0; 208 | valid[11] <= 16'd0; 209 | valid[12] <= 16'd0; 210 | valid[13] <= 16'd0; 211 | valid[14] <= 16'd0; 212 | valid[15] <= 16'd0; 213 | end else if (ctrlBlkWrite) begin 214 | valid[index[6:3]] <= newWayValids; 215 | end 216 | end 217 | 218 | assign wayValids = valid[index[6:3]]; 219 | assign wayValid = (index[2:0] == 3'd0) ? wayValids[3:0] : 220 | (index[2:0] == 3'd1) ? wayValids[7:4] : 221 | (index[2:0] == 3'd2) ? wayValids[11:8] : 222 | (index[2:0] == 3'd3) ? wayValids[15:12] : 223 | (index[2:0] == 3'd4) ? wayValids[19:16] : 224 | (index[2:0] == 3'd5) ? wayValids[23:20] : 225 | (index[2:0] == 3'd6) ? wayValids[27:24] : 226 | wayValids[31:28]; 227 | 228 | assign validWay1 = wayValid[0]; 229 | assign validWay2 = wayValid[1]; 230 | assign validWay3 = wayValid[2]; 231 | assign validWay4 = wayValid[3]; 232 | 233 | assign LRUWay1 = ctrlBlkOut[21:20]; 234 | assign LRUWay2 = ctrlBlkOut[45:44]; 235 | assign LRUWay3 = ctrlBlkOut[69:68]; 236 | assign LRUWay4 = ctrlBlkOut[93:92]; 237 | 238 | assign iCacheHitWay1 = (tagWay1 == tag) & validWay1; 239 | assign iCacheHitWay2 = (tagWay2 == tag) & validWay2; 240 | assign iCacheHitWay3 = (tagWay3 == tag) & validWay3; 241 | assign iCacheHitWay4 = (tagWay4 == tag) & validWay4; 242 | 243 | assign iCacheHit = iCacheHitWay1 | iCacheHitWay2 | iCacheHitWay3 | iCacheHitWay4; 244 | 245 | //Select or Write control block stage: Calculate new LRU to write back or pass to next stage. 246 | wire LRUWay1GT2; 247 | wire LRUWay1GT3; 248 | wire LRUWay1GT4; 249 | wire LRUWay2GT3; 250 | wire LRUWay2GT4; 251 | wire LRUWay3GT4; 252 | wire [1:0] aRefillLRUWay1; 253 | wire [1:0] aRefillLRUWay2; 254 | wire [1:0] aRefillLRUWay3; 255 | wire [1:0] aRefillLRUWay4; 256 | wire [1:0] newLRUWay1; 257 | wire [1:0] newLRUWay2; 258 | wire [1:0] newLRUWay3; 259 | wire [1:0] newLRUWay4; 260 | 261 | assign LRUWay1GT2 = nxtLRUWay1 > nxtLRUWay2; 262 | assign LRUWay1GT3 = nxtLRUWay1 > nxtLRUWay3; 263 | assign LRUWay1GT4 = nxtLRUWay1 > nxtLRUWay4; 264 | assign LRUWay2GT3 = nxtLRUWay2 > nxtLRUWay3; 265 | assign LRUWay2GT4 = nxtLRUWay2 > nxtLRUWay4; 266 | assign LRUWay3GT4 = nxtLRUWay3 > nxtLRUWay4; 267 | 268 | wire LRUWay1GT2_tagok = LRUWay1 > LRUWay2; 269 | wire LRUWay1GT3_tagok = LRUWay1 > LRUWay3; 270 | wire LRUWay1GT4_tagok = LRUWay1 > LRUWay4; 271 | wire LRUWay2GT3_tagok = LRUWay2 > LRUWay3; 272 | wire LRUWay2GT4_tagok = LRUWay2 > LRUWay4; 273 | wire LRUWay3GT4_tagok = LRUWay3 > LRUWay4; 274 | 275 | assign refillIndex = //There is an empty way. 276 | (!nxtValidWay1) ? 2'd0 : 277 | (!nxtValidWay2) ? 2'd1 : 278 | (!nxtValidWay3) ? 2'd2 : 279 | (!nxtValidWay4) ? 2'd3 : 280 | //All way is valid, need to refill a way. 281 | ( LRUWay1GT2 && LRUWay1GT3 && LRUWay1GT4) ? 2'd0 : 282 | (~LRUWay1GT2 && LRUWay2GT3 && LRUWay2GT4) ? 2'd1 : 283 | (~LRUWay1GT3 && ~LRUWay2GT3 && LRUWay3GT4) ? 2'd2 : 284 | 2'd3 ; 285 | 286 | assign aRefillLRUWay1 = (refillIndex == 2'd0) ? 2'd0 : nxtLRUWay1 + 2'd1; 287 | assign aRefillLRUWay2 = (refillIndex == 2'd1) ? 2'd0 : nxtLRUWay2 + 2'd1; 288 | assign aRefillLRUWay3 = (refillIndex == 2'd2) ? 2'd0 : nxtLRUWay3 + 2'd1; 289 | assign aRefillLRUWay4 = (refillIndex == 2'd3) ? 2'd0 : nxtLRUWay4 + 2'd1; 290 | 291 | wire [1:0] refillIndex_tagok; 292 | wire [1:0] aRefillLRUWay1_tagok; 293 | wire [1:0] aRefillLRUWay2_tagok; 294 | wire [1:0] aRefillLRUWay3_tagok; 295 | wire [1:0] aRefillLRUWay4_tagok; 296 | 297 | assign refillIndex_tagok = //There is an empty way. 298 | (!validWay1) ? 2'd0 : 299 | (!validWay2) ? 2'd1 : 300 | (!validWay3) ? 2'd2 : 301 | (!validWay4) ? 2'd3 : 302 | //All way is valid, need to refill a way. 303 | ( LRUWay1GT2_tagok && LRUWay1GT3_tagok && LRUWay1GT4_tagok) ? 2'd0 : 304 | (~LRUWay1GT2_tagok && LRUWay2GT3_tagok && LRUWay2GT4_tagok) ? 2'd1 : 305 | (~LRUWay1GT3_tagok && ~LRUWay2GT3_tagok && LRUWay3GT4_tagok) ? 2'd2 : 306 | 2'd3 ; 307 | 308 | assign aRefillLRUWay1_tagok = (refillIndex_tagok == 2'd0) ? 2'd0 : LRUWay1 + 2'd1; 309 | assign aRefillLRUWay2_tagok = (refillIndex_tagok == 2'd1) ? 2'd0 : LRUWay2 + 2'd1; 310 | assign aRefillLRUWay3_tagok = (refillIndex_tagok == 2'd2) ? 2'd0 : LRUWay3 + 2'd1; 311 | assign aRefillLRUWay4_tagok = (refillIndex_tagok == 2'd3) ? 2'd0 : LRUWay4 + 2'd1; 312 | 313 | wire [1:0] newLRUWay1_selete; 314 | wire [1:0] newLRUWay2_selete; 315 | wire [1:0] newLRUWay3_selete; 316 | wire [1:0] newLRUWay4_selete; 317 | assign newLRUWay1_selete = (nxtICacheHitWay1) ? 2'd0 : 318 | (nxtICacheHitWay2) ? nxtLRUWay1 + ~LRUWay1GT2 : 319 | (nxtICacheHitWay3) ? nxtLRUWay1 + ~LRUWay1GT3 : 320 | (nxtICacheHitWay4) ? nxtLRUWay1 + ~LRUWay1GT4 : 321 | aRefillLRUWay1 ; 322 | assign newLRUWay2_selete = (nxtICacheHitWay1) ? nxtLRUWay2 + LRUWay1GT2 : 323 | (nxtICacheHitWay2) ? 2'd0 : 324 | (nxtICacheHitWay3) ? nxtLRUWay2 + ~LRUWay2GT3 : 325 | (nxtICacheHitWay4) ? nxtLRUWay2 + ~LRUWay2GT4 : 326 | aRefillLRUWay2 ; 327 | assign newLRUWay3_selete = (nxtICacheHitWay1) ? nxtLRUWay3 + LRUWay1GT3 : 328 | (nxtICacheHitWay2) ? nxtLRUWay3 + LRUWay2GT3 : 329 | (nxtICacheHitWay3) ? 2'd0 : 330 | (nxtICacheHitWay4) ? nxtLRUWay3 + ~LRUWay3GT4 : 331 | aRefillLRUWay3 ; 332 | assign newLRUWay4_selete = (nxtICacheHitWay1) ? nxtLRUWay4 + LRUWay1GT4 : 333 | (nxtICacheHitWay2) ? nxtLRUWay4 + LRUWay2GT4 : 334 | (nxtICacheHitWay3) ? nxtLRUWay4 + LRUWay3GT4 : 335 | (nxtICacheHitWay4) ? 2'd0 : 336 | aRefillLRUWay4 ; 337 | 338 | wire [1:0] newLRUWay1_tagok; 339 | wire [1:0] newLRUWay2_tagok; 340 | wire [1:0] newLRUWay3_tagok; 341 | wire [1:0] newLRUWay4_tagok; 342 | assign newLRUWay1_tagok = (iCacheHitWay1) ? 2'd0 : 343 | (iCacheHitWay2) ? LRUWay1 + ~LRUWay1GT2_tagok : 344 | (iCacheHitWay3) ? LRUWay1 + ~LRUWay1GT3_tagok : 345 | (iCacheHitWay4) ? LRUWay1 + ~LRUWay1GT4_tagok : 346 | aRefillLRUWay1_tagok ; 347 | assign newLRUWay2_tagok = (iCacheHitWay1) ? LRUWay2 + LRUWay1GT2_tagok : 348 | (iCacheHitWay2) ? 2'd0 : 349 | (iCacheHitWay3) ? LRUWay2 + ~LRUWay2GT3_tagok : 350 | (iCacheHitWay4) ? LRUWay2 + ~LRUWay2GT4_tagok : 351 | aRefillLRUWay2_tagok ; 352 | assign newLRUWay3_tagok = (iCacheHitWay1) ? LRUWay3 + LRUWay1GT3_tagok : 353 | (iCacheHitWay2) ? LRUWay3 + LRUWay2GT3_tagok : 354 | (iCacheHitWay3) ? 2'd0 : 355 | (iCacheHitWay4) ? LRUWay3 + ~LRUWay3GT4_tagok : 356 | aRefillLRUWay3_tagok ; 357 | assign newLRUWay4_tagok = (iCacheHitWay1) ? LRUWay4 + LRUWay1GT4_tagok : 358 | (iCacheHitWay2) ? LRUWay4 + LRUWay2GT4_tagok : 359 | (iCacheHitWay3) ? LRUWay4 + LRUWay3GT4_tagok : 360 | (iCacheHitWay4) ? 2'd0 : 361 | aRefillLRUWay4_tagok ; 362 | 363 | assign newLRUWay1 = (stage == SELECT) ? newLRUWay1_selete : newLRUWay1_tagok; 364 | assign newLRUWay2 = (stage == SELECT) ? newLRUWay2_selete : newLRUWay2_tagok; 365 | assign newLRUWay3 = (stage == SELECT) ? newLRUWay3_selete : newLRUWay3_tagok; 366 | assign newLRUWay4 = (stage == SELECT) ? newLRUWay4_selete : newLRUWay4_tagok; 367 | 368 | //Select or Write control block stage: generate new control state to write back. 369 | wire newValidWay1; 370 | wire newValidWay2; 371 | wire newValidWay3; 372 | wire newValidWay4; 373 | wire [19:0] newTagWay1; 374 | wire [19:0] newTagWay2; 375 | wire [19:0] newTagWay3; 376 | wire [19:0] newTagWay4; 377 | wire [95:0] newCtrl; 378 | 379 | assign newValidWay1 = (stage == SELECT && refillIndex == 2'd0) ? 1'd1 : validWay1; 380 | assign newValidWay2 = (stage == SELECT && refillIndex == 2'd1) ? 1'd1 : validWay2; 381 | assign newValidWay3 = (stage == SELECT && refillIndex == 2'd2) ? 1'd1 : validWay3; 382 | assign newValidWay4 = (stage == SELECT && refillIndex == 2'd3) ? 1'd1 : validWay4; 383 | 384 | assign newTagWay1 = (stage == SELECT && refillIndex == 2'd0) ? nxtTag : tagWay1; 385 | assign newTagWay2 = (stage == SELECT && refillIndex == 2'd1) ? nxtTag : tagWay2; 386 | assign newTagWay3 = (stage == SELECT && refillIndex == 2'd2) ? nxtTag : tagWay3; 387 | assign newTagWay4 = (stage == SELECT && refillIndex == 2'd3) ? nxtTag : tagWay4; 388 | 389 | assign newCtrl = {1'd0, newValidWay4, newLRUWay4, newTagWay4, 390 | 1'd0, newValidWay3, newLRUWay3, newTagWay3, 391 | 1'd0, newValidWay2, newLRUWay2, newTagWay2, 392 | 1'd0, newValidWay1, newLRUWay1, newTagWay1}; 393 | 394 | wire [3:0] newWayValid; 395 | 396 | assign newWayValid = {newValidWay4, newValidWay3, newValidWay2, newValidWay1}; 397 | assign newWayValids = (index[2:0] == 3'd0) ? {nxtWayValids[31:4], newWayValid} : 398 | (index[2:0] == 3'd1) ? {nxtWayValids[31:8], newWayValid, nxtWayValids[3:0]} : 399 | (index[2:0] == 3'd2) ? {nxtWayValids[31:12], newWayValid, nxtWayValids[7:0]} : 400 | (index[2:0] == 3'd3) ? {nxtWayValids[31:16], newWayValid, nxtWayValids[11:0]} : 401 | (index[2:0] == 3'd4) ? {nxtWayValids[31:20], newWayValid, nxtWayValids[15:0]} : 402 | (index[2:0] == 3'd5) ? {nxtWayValids[31:24], newWayValid, nxtWayValids[19:0]} : 403 | (index[2:0] == 3'd6) ? {nxtWayValids[31:28], newWayValid, nxtWayValids[23:0]} : 404 | {newWayValid, nxtWayValids[27:0]}; 405 | 406 | //Request send stage: Prepare the output signal. 407 | assign addr2Cache2 = {rsAddr[31:5], 5'd0}; 408 | assign addr2Cache2Valid = stage == REQ_SND; 409 | 410 | assign ctrlBlkWrite = (stage == TAG_OK) || (stage == SELECT); 411 | assign ctrlBlkRead = ((stage == FREE) && pgOffsetValid); 412 | assign ctrlBlkAddr = (!ctrlBlkRead) ? index : preIndex; 413 | 414 | ctrlBlk iCacheCtrlBlk( 415 | .clka ( clk), 416 | .ena (ctrlBlkRead | ctrlBlkWrite), 417 | .wea ( ctrlBlkWrite), 418 | .addra( ctrlBlkAddr), 419 | .dina ( newCtrl), 420 | .douta( ctrlBlkOut) 421 | ); 422 | 423 | //data ram 424 | wire [127:0] dataOutFromICacheFull; 425 | wire [ 31:0] dataOutFromCache2; 426 | wire dataBlkWrite; 427 | wire dataBlkRead; 428 | wire [ 6:0] dataBlkAddr; 429 | wire [ 15:0] dataBlkWrByteEn; 430 | wire [127:0] dataBlkOut1; 431 | wire [127:0] dataBlkOut2; 432 | wire [127:0] dataBlkOut3; 433 | wire [127:0] dataBlkOut4; 434 | wire [127:0] dataBlkOut5; 435 | wire [127:0] dataBlkOut6; 436 | wire [127:0] dataBlkOut7; 437 | wire [127:0] dataBlkOut8; 438 | 439 | assign dataOutFromICacheFull = (blkOffset[4:2] == 3'd0) ? dataBlkOut1 : 440 | (blkOffset[4:2] == 3'd1) ? dataBlkOut2 : 441 | (blkOffset[4:2] == 3'd2) ? dataBlkOut3 : 442 | (blkOffset[4:2] == 3'd3) ? dataBlkOut4 : 443 | (blkOffset[4:2] == 3'd4) ? dataBlkOut5 : 444 | (blkOffset[4:2] == 3'd5) ? dataBlkOut6 : 445 | (blkOffset[4:2] == 3'd6) ? dataBlkOut7 : 446 | dataBlkOut8 ; 447 | assign dataOutFromCache2 = (rsAddr[4:2] == 3'd0) ? data2ICacheBlk1 : 448 | (rsAddr[4:2] == 3'd1) ? data2ICacheBlk2 : 449 | (rsAddr[4:2] == 3'd2) ? data2ICacheBlk3 : 450 | (rsAddr[4:2] == 3'd3) ? data2ICacheBlk4 : 451 | (rsAddr[4:2] == 3'd4) ? data2ICacheBlk5 : 452 | (rsAddr[4:2] == 3'd5) ? data2ICacheBlk6 : 453 | (rsAddr[4:2] == 3'd6) ? data2ICacheBlk7 : 454 | data2ICacheBlk8 ; 455 | assign dataOut = (stage != TAG_OK) ? dataOutFromCache2 : 456 | //TagOK stage: need to select which way. 457 | (iCacheHitWay1) ? dataOutFromICacheFull[ 31: 0] : 458 | (iCacheHitWay2) ? dataOutFromICacheFull[ 63:32] : 459 | (iCacheHitWay3) ? dataOutFromICacheFull[ 95:64] : 460 | dataOutFromICacheFull[127:96] ; 461 | assign dataOutReady = (stage == TAG_OK && iCacheHit) || (stage == REQ_SND && dataRequestedReady && data2ICacheBlkReady); 462 | 463 | assign dataBlkWrite = (stage == REQ_SND && dataRequestedReady && data2ICacheBlkReady); 464 | assign dataBlkRead = (stage == FREE) && pgOffsetValid; 465 | assign dataBlkAddr = (!dataBlkRead) ? rsAddr[11:5] : preIndex; 466 | assign dataBlkWrByteEn = (!dataBlkWrite) ? 16'd0 : 467 | //need to refill one way 468 | (rsRefillIndex == 2'd0) ? 16'h000f : 469 | (rsRefillIndex == 2'd1) ? 16'h00f0 : 470 | (rsRefillIndex == 2'd2) ? 16'h0f00 : 471 | 16'hf000 ; 472 | 473 | dataBlk_128X128 iCacheDataBlk1( 474 | .clka ( clk), 475 | .ena (dataBlkRead | dataBlkWrite), 476 | .wea ( dataBlkWrByteEn), 477 | .addra( dataBlkAddr), 478 | .dina ( {4{data2ICacheBlk1}}), 479 | .douta( dataBlkOut1) 480 | ); 481 | 482 | dataBlk_128X128 iCacheDataBlk2( 483 | .clka ( clk), 484 | .ena (dataBlkRead | dataBlkWrite), 485 | .wea ( dataBlkWrByteEn), 486 | .addra( dataBlkAddr), 487 | .dina ( {4{data2ICacheBlk2}}), 488 | .douta( dataBlkOut2) 489 | ); 490 | 491 | dataBlk_128X128 iCacheDataBlk3( 492 | .clka ( clk), 493 | .ena (dataBlkRead | dataBlkWrite), 494 | .wea ( dataBlkWrByteEn), 495 | .addra( dataBlkAddr), 496 | .dina ( {4{data2ICacheBlk3}}), 497 | .douta( dataBlkOut3) 498 | ); 499 | 500 | dataBlk_128X128 iCacheDataBlk4( 501 | .clka ( clk), 502 | .ena (dataBlkRead | dataBlkWrite), 503 | .wea ( dataBlkWrByteEn), 504 | .addra( dataBlkAddr), 505 | .dina ( {4{data2ICacheBlk4}}), 506 | .douta( dataBlkOut4) 507 | ); 508 | 509 | dataBlk_128X128 iCacheDataBlk5( 510 | .clka ( clk), 511 | .ena (dataBlkRead | dataBlkWrite), 512 | .wea ( dataBlkWrByteEn), 513 | .addra( dataBlkAddr), 514 | .dina ( {4{data2ICacheBlk5}}), 515 | .douta( dataBlkOut5) 516 | ); 517 | 518 | dataBlk_128X128 iCacheDataBlk6( 519 | .clka ( clk), 520 | .ena (dataBlkRead | dataBlkWrite), 521 | .wea ( dataBlkWrByteEn), 522 | .addra( dataBlkAddr), 523 | .dina ( {4{data2ICacheBlk6}}), 524 | .douta( dataBlkOut6) 525 | ); 526 | 527 | dataBlk_128X128 iCacheDataBlk7( 528 | .clka ( clk), 529 | .ena (dataBlkRead | dataBlkWrite), 530 | .wea ( dataBlkWrByteEn), 531 | .addra( dataBlkAddr), 532 | .dina ( {4{data2ICacheBlk7}}), 533 | .douta( dataBlkOut7) 534 | ); 535 | 536 | dataBlk_128X128 iCacheDataBlk8( 537 | .clka ( clk), 538 | .ena (dataBlkRead | dataBlkWrite), 539 | .wea ( dataBlkWrByteEn), 540 | .addra( dataBlkAddr), 541 | .dina ( {4{data2ICacheBlk8}}), 542 | .douta( dataBlkOut8) 543 | ); 544 | 545 | endmodule 546 | -------------------------------------------------------------------------------- /rtl/myCPU/dcache.v: -------------------------------------------------------------------------------- 1 | module dcache( 2 | input clk, 3 | input resetn, 4 | 5 | input [11:0] pgOffsetIn, 6 | input pgOffsetValid, 7 | input [19:0] tagIn, 8 | input tagValid, 9 | input wrIn, 10 | input [3:0] wstrbIn, 11 | input [31:0] wdataIn, 12 | 13 | output [31:0] dataOut, 14 | output dataOutReady, 15 | 16 | output [31:0] addr2Cache2, 17 | output addr2Cache2Valid, 18 | input [31:0] data2ICacheBlk1, 19 | input [31:0] data2ICacheBlk2, 20 | input [31:0] data2ICacheBlk3, 21 | input [31:0] data2ICacheBlk4, 22 | input [31:0] data2ICacheBlk5, 23 | input [31:0] data2ICacheBlk6, 24 | input [31:0] data2ICacheBlk7, 25 | input [31:0] data2ICacheBlk8, 26 | input dataRequestedReady, 27 | input data2ICacheBlkReady, 28 | 29 | output dataWriteBackValid, 30 | input dataWriteBackAck, 31 | output [31:0] dataWriteBackAddr, 32 | output [255:0] dataWriteBack, 33 | 34 | output busy 35 | ); 36 | 37 | //I-cache global state machine definition. 38 | parameter FREE = 0; 39 | parameter PGOFF_OK = 1; 40 | parameter TAG_OK = 2; 41 | parameter WR_CTRL = 3; 42 | parameter SELECT = 4; 43 | parameter REQ_SND = 5; 44 | parameter REQ_RTN = 6; 45 | parameter BLK_RTN = 7; 46 | parameter WR_BLK = 8; 47 | parameter WRITE_BACK = 9; 48 | 49 | //State machine. 50 | //Global reg: 51 | reg [4:0] stage; 52 | 53 | //stage TagOK reg: 54 | reg [ 19:0] tag; 55 | reg [ 11:0] pgOffset; 56 | 57 | reg wr; 58 | reg [3:0] wstrb; 59 | reg [31:0] wdata; 60 | 61 | wire [ 6:0] index; 62 | wire [ 4:0] blkOffset; 63 | wire [19:0] tagWay1; 64 | wire [19:0] tagWay2; 65 | wire [19:0] tagWay3; 66 | wire [19:0] tagWay4; 67 | wire [ 1:0] LRUWay1; 68 | wire [ 1:0] LRUWay2; 69 | wire [ 1:0] LRUWay3; 70 | wire [ 1:0] LRUWay4; 71 | wire validWay1; 72 | wire validWay2; 73 | wire validWay3; 74 | wire validWay4; 75 | wire dirtyWay1; 76 | wire dirtyWay2; 77 | wire dirtyWay3; 78 | wire dirtyWay4; 79 | wire iCacheHitWay1; 80 | wire iCacheHitWay2; 81 | wire iCacheHitWay3; 82 | wire iCacheHitWay4; 83 | wire iCacheHit; 84 | 85 | reg [31:0] valid [15:0]; 86 | wire [31:0] wayValids; 87 | wire [3:0] wayValid; 88 | wire [31:0] newWayValids; 89 | 90 | wire needWriteBack; 91 | 92 | //stage Write Control & Select reg: 93 | reg [19:0] nxtTag; 94 | reg [ 6:0] nxtIndex; 95 | reg [ 4:0] nxtBlkOffset; 96 | reg [31:0] nxtWayValids; 97 | reg [19:0] nxtTagWay1; 98 | reg [19:0] nxtTagWay2; 99 | reg [19:0] nxtTagWay3; 100 | reg [19:0] nxtTagWay4; 101 | reg [ 1:0] nxtLRUWay1; 102 | reg [ 1:0] nxtLRUWay2; 103 | reg [ 1:0] nxtLRUWay3; 104 | reg [ 1:0] nxtLRUWay4; 105 | reg nxtValidWay1; 106 | reg nxtValidWay2; 107 | reg nxtValidWay3; 108 | reg nxtValidWay4; 109 | reg nxtDirtyWay1; 110 | reg nxtDirtyWay2; 111 | reg nxtDirtyWay3; 112 | reg nxtDirtyWay4; 113 | reg nxtICacheHitWay1; 114 | reg nxtICacheHitWay2; 115 | reg nxtICacheHitWay3; 116 | reg nxtICacheHitWay4; 117 | 118 | wire [1:0] refillIndex; 119 | 120 | //stage Request Send reg: 121 | reg [ 1:0] rsRefillIndex; 122 | reg [31:0] rsAddr; 123 | 124 | reg noWrCtrl; 125 | 126 | assign busy = stage != FREE; 127 | 128 | always @(posedge clk) begin 129 | 130 | if (!resetn) begin 131 | stage <= FREE; 132 | noWrCtrl <= 1'b0; 133 | end else begin 134 | //Free--(TLB hitted)-->TagOK. 135 | if ((stage == FREE) && tagValid && pgOffsetValid) begin 136 | stage <= TAG_OK; 137 | tag <= tagIn; 138 | pgOffset <= pgOffsetIn; 139 | wr <= wrIn; 140 | wstrb <= wstrbIn; 141 | wdata <= wdataIn; 142 | end 143 | 144 | if (stage == TAG_OK) begin 145 | if (iCacheHit) begin 146 | //TagOK--(i-cache hitted)-->Write control block. 147 | if(noWrCtrl) begin 148 | stage <= FREE; 149 | noWrCtrl <= 1'b0; 150 | end else begin 151 | stage <= WR_CTRL; 152 | end 153 | end else begin 154 | //TagOK--(i-cache miss)-->Select. 155 | stage <= SELECT; 156 | end 157 | 158 | //use for write back. 159 | nxtTag <= tag; 160 | nxtIndex <= index; 161 | nxtBlkOffset <= blkOffset; 162 | nxtWayValids <= wayValids; 163 | 164 | //use for generate control information writed back. 165 | nxtTagWay1 <= tagWay1; 166 | nxtTagWay2 <= tagWay2; 167 | nxtTagWay3 <= tagWay3; 168 | nxtTagWay4 <= tagWay4; 169 | 170 | //use for decided the refill way number. 171 | nxtValidWay1 <= validWay1; 172 | nxtValidWay2 <= validWay2; 173 | nxtValidWay3 <= validWay3; 174 | nxtValidWay4 <= validWay4; 175 | 176 | nxtDirtyWay1 <= dirtyWay1; 177 | nxtDirtyWay2 <= dirtyWay2; 178 | nxtDirtyWay3 <= dirtyWay3; 179 | nxtDirtyWay4 <= dirtyWay4; 180 | 181 | //use for calculate new LRU number. 182 | nxtLRUWay1 <= LRUWay1; 183 | nxtLRUWay2 <= LRUWay2; 184 | nxtLRUWay3 <= LRUWay3; 185 | nxtLRUWay4 <= LRUWay4; 186 | 187 | //use for check which way hitted. 188 | nxtICacheHitWay1 <= iCacheHitWay1; 189 | nxtICacheHitWay2 <= iCacheHitWay2; 190 | nxtICacheHitWay3 <= iCacheHitWay3; 191 | nxtICacheHitWay4 <= iCacheHitWay4; 192 | end 193 | 194 | //Write control block---->Free. 195 | if (stage == WR_CTRL) begin 196 | stage <= FREE; 197 | end 198 | 199 | //Select--(Write control block at the same time)-->Request send. 200 | if (stage == SELECT) begin 201 | rsRefillIndex <= refillIndex; 202 | rsAddr <= {nxtTag, nxtIndex, nxtBlkOffset}; 203 | if(needWriteBack) begin 204 | stage <= WRITE_BACK; 205 | end else begin 206 | stage <= REQ_SND; 207 | end 208 | end 209 | 210 | if (stage == WRITE_BACK && dataWriteBackAck) begin 211 | stage <= REQ_SND; 212 | end 213 | 214 | //Request send--(data requested and data block return simultaneously)-->Free. 215 | if (stage == REQ_SND && dataRequestedReady && data2ICacheBlkReady) begin 216 | stage <= TAG_OK; 217 | noWrCtrl <= 1'b1; 218 | end 219 | end 220 | end 221 | 222 | //Free stage: when pgOffset is ok, we should read control block. 223 | wire [ 6:0] preIndex; 224 | 225 | assign preIndex = pgOffsetIn[11:5]; 226 | 227 | //TagOk stage: Look up control block to decided whether address hits i-cache. 228 | wire [95:0] ctrlBlkOut; 229 | 230 | assign index = pgOffset[11:5]; 231 | assign blkOffset = pgOffset[ 4:0]; 232 | 233 | assign tagWay1 = ctrlBlkOut[19: 0]; 234 | assign tagWay2 = ctrlBlkOut[43:24]; 235 | assign tagWay3 = ctrlBlkOut[67:48]; 236 | assign tagWay4 = ctrlBlkOut[91:72]; 237 | 238 | //control ram 239 | wire ctrlBlkWrite; 240 | wire ctrlBlkRead; 241 | wire [6:0] ctrlBlkAddr; 242 | 243 | always @(posedge clk) begin 244 | if (!resetn) begin 245 | valid[0] <= 16'd0; 246 | valid[1] <= 16'd0; 247 | valid[2] <= 16'd0; 248 | valid[3] <= 16'd0; 249 | valid[4] <= 16'd0; 250 | valid[5] <= 16'd0; 251 | valid[6] <= 16'd0; 252 | valid[7] <= 16'd0; 253 | valid[8] <= 16'd0; 254 | valid[9] <= 16'd0; 255 | valid[10] <= 16'd0; 256 | valid[11] <= 16'd0; 257 | valid[12] <= 16'd0; 258 | valid[13] <= 16'd0; 259 | valid[14] <= 16'd0; 260 | valid[15] <= 16'd0; 261 | end else if (ctrlBlkWrite) begin 262 | valid[index[6:3]] <= newWayValids; 263 | end 264 | end 265 | 266 | assign wayValids = valid[index[6:3]]; 267 | assign wayValid = (index[2:0] == 3'd0) ? wayValids[3:0] : 268 | (index[2:0] == 3'd1) ? wayValids[7:4] : 269 | (index[2:0] == 3'd2) ? wayValids[11:8] : 270 | (index[2:0] == 3'd3) ? wayValids[15:12] : 271 | (index[2:0] == 3'd4) ? wayValids[19:16] : 272 | (index[2:0] == 3'd5) ? wayValids[23:20] : 273 | (index[2:0] == 3'd6) ? wayValids[27:24] : 274 | wayValids[31:28]; 275 | 276 | assign validWay1 = wayValid[0]; 277 | assign validWay2 = wayValid[1]; 278 | assign validWay3 = wayValid[2]; 279 | assign validWay4 = wayValid[3]; 280 | 281 | assign dirtyWay1 = ctrlBlkOut[23]; 282 | assign dirtyWay2 = ctrlBlkOut[47]; 283 | assign dirtyWay3 = ctrlBlkOut[71]; 284 | assign dirtyWay4 = ctrlBlkOut[95]; 285 | 286 | assign LRUWay1 = ctrlBlkOut[21:20]; 287 | assign LRUWay2 = ctrlBlkOut[45:44]; 288 | assign LRUWay3 = ctrlBlkOut[69:68]; 289 | assign LRUWay4 = ctrlBlkOut[93:92]; 290 | 291 | assign iCacheHitWay1 = (tagWay1 == tag) & validWay1; 292 | assign iCacheHitWay2 = (tagWay2 == tag) & validWay2; 293 | assign iCacheHitWay3 = (tagWay3 == tag) & validWay3; 294 | assign iCacheHitWay4 = (tagWay4 == tag) & validWay4; 295 | 296 | assign iCacheHit = iCacheHitWay1 | iCacheHitWay2 | iCacheHitWay3 | iCacheHitWay4; 297 | 298 | //Select or Write control block stage: Calculate new LRU to write back or pass to next stage. 299 | wire LRUWay1GT2; 300 | wire LRUWay1GT3; 301 | wire LRUWay1GT4; 302 | wire LRUWay2GT3; 303 | wire LRUWay2GT4; 304 | wire LRUWay3GT4; 305 | wire [1:0] aRefillLRUWay1; 306 | wire [1:0] aRefillLRUWay2; 307 | wire [1:0] aRefillLRUWay3; 308 | wire [1:0] aRefillLRUWay4; 309 | wire [1:0] newLRUWay1; 310 | wire [1:0] newLRUWay2; 311 | wire [1:0] newLRUWay3; 312 | wire [1:0] newLRUWay4; 313 | 314 | assign LRUWay1GT2 = nxtLRUWay1 > nxtLRUWay2; 315 | assign LRUWay1GT3 = nxtLRUWay1 > nxtLRUWay3; 316 | assign LRUWay1GT4 = nxtLRUWay1 > nxtLRUWay4; 317 | assign LRUWay2GT3 = nxtLRUWay2 > nxtLRUWay3; 318 | assign LRUWay2GT4 = nxtLRUWay2 > nxtLRUWay4; 319 | assign LRUWay3GT4 = nxtLRUWay3 > nxtLRUWay4; 320 | 321 | assign refillIndex = //There is an empty way. 322 | (!nxtValidWay1) ? 2'd0 : 323 | (!nxtValidWay2) ? 2'd1 : 324 | (!nxtValidWay3) ? 2'd2 : 325 | (!nxtValidWay4) ? 2'd3 : 326 | //All way is valid, need to refill a way. 327 | ( LRUWay1GT2 && LRUWay1GT3 && LRUWay1GT4) ? 2'd0 : 328 | (~LRUWay1GT2 && LRUWay2GT3 && LRUWay2GT4) ? 2'd1 : 329 | (~LRUWay1GT3 && ~LRUWay2GT3 && LRUWay3GT4) ? 2'd2 : 330 | 2'd3 ; 331 | 332 | assign aRefillLRUWay1 = (refillIndex == 2'd0) ? 2'd0 : nxtLRUWay1 + 2'd1; 333 | assign aRefillLRUWay2 = (refillIndex == 2'd1) ? 2'd0 : nxtLRUWay2 + 2'd1; 334 | assign aRefillLRUWay3 = (refillIndex == 2'd2) ? 2'd0 : nxtLRUWay3 + 2'd1; 335 | assign aRefillLRUWay4 = (refillIndex == 2'd3) ? 2'd0 : nxtLRUWay4 + 2'd1; 336 | 337 | assign newLRUWay1 = (nxtICacheHitWay1) ? 2'd0 : 338 | (nxtICacheHitWay2) ? nxtLRUWay1 + ~LRUWay1GT2 : 339 | (nxtICacheHitWay3) ? nxtLRUWay1 + ~LRUWay1GT3 : 340 | (nxtICacheHitWay4) ? nxtLRUWay1 + ~LRUWay1GT4 : 341 | aRefillLRUWay1 ; 342 | assign newLRUWay2 = (nxtICacheHitWay1) ? nxtLRUWay2 + LRUWay1GT2 : 343 | (nxtICacheHitWay2) ? 2'd0 : 344 | (nxtICacheHitWay3) ? nxtLRUWay2 + ~LRUWay2GT3 : 345 | (nxtICacheHitWay4) ? nxtLRUWay2 + ~LRUWay2GT4 : 346 | aRefillLRUWay2 ; 347 | assign newLRUWay3 = (nxtICacheHitWay1) ? nxtLRUWay3 + LRUWay1GT3 : 348 | (nxtICacheHitWay2) ? nxtLRUWay3 + LRUWay2GT3 : 349 | (nxtICacheHitWay3) ? 2'd0 : 350 | (nxtICacheHitWay4) ? nxtLRUWay3 + ~LRUWay3GT4 : 351 | aRefillLRUWay3 ; 352 | assign newLRUWay4 = (nxtICacheHitWay1) ? nxtLRUWay4 + LRUWay1GT4 : 353 | (nxtICacheHitWay2) ? nxtLRUWay4 + LRUWay2GT4 : 354 | (nxtICacheHitWay3) ? nxtLRUWay4 + LRUWay3GT4 : 355 | (nxtICacheHitWay4) ? 2'd0 : 356 | aRefillLRUWay4 ; 357 | 358 | //Select or Write control block stage: generate new control state to write back. 359 | wire newValidWay1; 360 | wire newValidWay2; 361 | wire newValidWay3; 362 | wire newValidWay4; 363 | wire [19:0] newTagWay1; 364 | wire [19:0] newTagWay2; 365 | wire [19:0] newTagWay3; 366 | wire [19:0] newTagWay4; 367 | wire [95:0] newCtrl; 368 | 369 | assign newValidWay1 = (stage == SELECT && refillIndex == 2'd0) ? 1'd1 : nxtValidWay1; 370 | assign newValidWay2 = (stage == SELECT && refillIndex == 2'd1) ? 1'd1 : nxtValidWay2; 371 | assign newValidWay3 = (stage == SELECT && refillIndex == 2'd2) ? 1'd1 : nxtValidWay3; 372 | assign newValidWay4 = (stage == SELECT && refillIndex == 2'd3) ? 1'd1 : nxtValidWay4; 373 | 374 | assign newTagWay1 = (stage == SELECT && refillIndex == 2'd0) ? nxtTag : nxtTagWay1; 375 | assign newTagWay2 = (stage == SELECT && refillIndex == 2'd1) ? nxtTag : nxtTagWay2; 376 | assign newTagWay3 = (stage == SELECT && refillIndex == 2'd2) ? nxtTag : nxtTagWay3; 377 | assign newTagWay4 = (stage == SELECT && refillIndex == 2'd3) ? nxtTag : nxtTagWay4; 378 | 379 | wire newDirtyWay1 = ((stage == SELECT && refillIndex == 2'd0) || (stage == WR_CTRL && nxtIndex == 2'd0)) ? wr : nxtDirtyWay1; 380 | wire newDirtyWay2 = ((stage == SELECT && refillIndex == 2'd1) || (stage == WR_CTRL && nxtIndex == 2'd1)) ? wr : nxtDirtyWay2; 381 | wire newDirtyWay3 = ((stage == SELECT && refillIndex == 2'd2) || (stage == WR_CTRL && nxtIndex == 2'd2)) ? wr : nxtDirtyWay3; 382 | wire newDirtyWay4 = ((stage == SELECT && refillIndex == 2'd3) || (stage == WR_CTRL && nxtIndex == 2'd3)) ? wr : nxtDirtyWay4; 383 | 384 | assign newCtrl = {wr, newValidWay4, newLRUWay4, newTagWay4, 385 | wr, newValidWay3, newLRUWay3, newTagWay3, 386 | wr, newValidWay2, newLRUWay2, newTagWay2, 387 | wr, newValidWay1, newLRUWay1, newTagWay1}; 388 | 389 | wire [3:0] newWayValid; 390 | 391 | assign newWayValid = {newValidWay4, newValidWay3, newValidWay2, newValidWay1}; 392 | assign newWayValids = (index[2:0] == 3'd0) ? {nxtWayValids[31:4], newWayValid} : 393 | (index[2:0] == 3'd1) ? {nxtWayValids[31:8], newWayValid, nxtWayValids[3:0]} : 394 | (index[2:0] == 3'd2) ? {nxtWayValids[31:12], newWayValid, nxtWayValids[7:0]} : 395 | (index[2:0] == 3'd3) ? {nxtWayValids[31:16], newWayValid, nxtWayValids[11:0]} : 396 | (index[2:0] == 3'd4) ? {nxtWayValids[31:20], newWayValid, nxtWayValids[15:0]} : 397 | (index[2:0] == 3'd5) ? {nxtWayValids[31:24], newWayValid, nxtWayValids[19:0]} : 398 | (index[2:0] == 3'd6) ? {nxtWayValids[31:28], newWayValid, nxtWayValids[23:0]} : 399 | {newWayValid, nxtWayValids[27:0]}; 400 | 401 | assign needWriteBack = (stage == SELECT) && 402 | (nxtValidWay1 && refillIndex == 2'd0 && nxtDirtyWay1) || 403 | (nxtValidWay2 && refillIndex == 2'd1 && nxtDirtyWay2) || 404 | (nxtValidWay3 && refillIndex == 2'd2 && nxtDirtyWay3) || 405 | (nxtValidWay4 && refillIndex == 2'd3 && nxtDirtyWay4) ; 406 | assign dataWriteBackValid = (stage == WRITE_BACK); 407 | wire [127:0] dataBlkOut1; 408 | wire [127:0] dataBlkOut2; 409 | wire [127:0] dataBlkOut3; 410 | wire [127:0] dataBlkOut4; 411 | wire [127:0] dataBlkOut5; 412 | wire [127:0] dataBlkOut6; 413 | wire [127:0] dataBlkOut7; 414 | wire [127:0] dataBlkOut8; 415 | wire [255:0] dataWay[3:0]; 416 | assign dataWay[0] = {dataBlkOut1[31 : 0], dataBlkOut2[31 : 0], 417 | dataBlkOut3[31 : 0], dataBlkOut4[31 : 0], 418 | dataBlkOut5[31 : 0], dataBlkOut6[31 : 0], 419 | dataBlkOut7[31 : 0], dataBlkOut8[31 : 0]}; 420 | assign dataWay[1] = {dataBlkOut1[63 : 32], dataBlkOut2[63 : 32], 421 | dataBlkOut3[63 : 32], dataBlkOut4[63 : 32], 422 | dataBlkOut5[63 : 32], dataBlkOut6[63 : 32], 423 | dataBlkOut7[63 : 32], dataBlkOut8[63 : 32]}; 424 | assign dataWay[2] = {dataBlkOut1[95 : 64], dataBlkOut2[95 : 64], 425 | dataBlkOut3[95 : 64], dataBlkOut4[95 : 64], 426 | dataBlkOut5[95 : 64], dataBlkOut6[95 : 64], 427 | dataBlkOut7[95 : 64], dataBlkOut8[95 : 64]}; 428 | assign dataWay[3] = {dataBlkOut1[127 : 96], dataBlkOut2[127 : 96], 429 | dataBlkOut3[127 : 96], dataBlkOut4[127 : 96], 430 | dataBlkOut5[127 : 96], dataBlkOut6[127 : 96], 431 | dataBlkOut7[127 : 96], dataBlkOut8[127 : 96]}; 432 | reg [255:0] dataWriteBackReg; 433 | always @(posedge clk) 434 | begin 435 | if(stage == TAG_OK) 436 | dataWriteBackReg <= (refillIndex == 2'd0 & dataWay[0]) || 437 | (refillIndex == 2'd1 & dataWay[1]) || 438 | (refillIndex == 2'd2 & dataWay[2]) || 439 | (refillIndex == 2'd3 & dataWay[3]) ; 440 | end 441 | assign dataWriteBack = dataWriteBackReg; 442 | wire [19:0] writeBackTag = refillIndex == 2'd0 ? nxtTagWay1 : 443 | refillIndex == 2'd1 ? nxtTagWay2 : 444 | refillIndex == 2'd2 ? nxtTagWay3 : 445 | nxtTagWay4 ; 446 | assign dataWriteBackAddr = {writeBackTag, nxtIndex, 5'd0}; 447 | 448 | //Request send stage: Prepare the output signal. 449 | assign addr2Cache2 = {rsAddr[31:5], 5'd0}; 450 | assign addr2Cache2Valid = stage == REQ_SND; 451 | 452 | assign ctrlBlkWrite = (stage == WR_CTRL) | (stage == SELECT); 453 | assign ctrlBlkRead = ((stage == FREE) && pgOffsetValid); 454 | assign ctrlBlkAddr = (!ctrlBlkRead) ? nxtIndex : preIndex; 455 | 456 | ctrlBlk iCacheCtrlBlk( 457 | .clka ( clk), 458 | .ena (ctrlBlkRead | ctrlBlkWrite), 459 | .wea ( ctrlBlkWrite), 460 | .addra( ctrlBlkAddr), 461 | .dina ( newCtrl), 462 | .douta( ctrlBlkOut) 463 | ); 464 | 465 | //data ram 466 | wire [127:0] dataOutFromICacheFull; 467 | wire [ 31:0] dataOutFromCache2; 468 | wire dataBlkRead; 469 | wire [ 6:0] dataBlkAddr; 470 | wire [ 15:0] dataBlkWrByteEn; 471 | 472 | assign dataOutFromICacheFull = (blkOffset[4:2] == 3'd0) ? dataBlkOut1 : 473 | (blkOffset[4:2] == 3'd1) ? dataBlkOut2 : 474 | (blkOffset[4:2] == 3'd2) ? dataBlkOut3 : 475 | (blkOffset[4:2] == 3'd3) ? dataBlkOut4 : 476 | (blkOffset[4:2] == 3'd4) ? dataBlkOut5 : 477 | (blkOffset[4:2] == 3'd5) ? dataBlkOut6 : 478 | (blkOffset[4:2] == 3'd6) ? dataBlkOut7 : 479 | dataBlkOut8 ; 480 | assign dataOutFromCache2 = (rsAddr[4:2] == 3'd0) ? data2ICacheBlk1 : 481 | (rsAddr[4:2] == 3'd1) ? data2ICacheBlk2 : 482 | (rsAddr[4:2] == 3'd2) ? data2ICacheBlk3 : 483 | (rsAddr[4:2] == 3'd3) ? data2ICacheBlk4 : 484 | (rsAddr[4:2] == 3'd4) ? data2ICacheBlk5 : 485 | (rsAddr[4:2] == 3'd5) ? data2ICacheBlk6 : 486 | (rsAddr[4:2] == 3'd6) ? data2ICacheBlk7 : 487 | data2ICacheBlk8 ; 488 | assign dataOut = (iCacheHitWay1) ? dataOutFromICacheFull[ 31: 0] : 489 | (iCacheHitWay2) ? dataOutFromICacheFull[ 63:32] : 490 | (iCacheHitWay3) ? dataOutFromICacheFull[ 95:64] : 491 | dataOutFromICacheFull[127:96] ; 492 | assign dataOutReady = (stage == TAG_OK && iCacheHit); 493 | 494 | wire dataBlkWriteIn = (stage == TAG_OK) && wr; 495 | wire [7:0] dataBlkWrSel = {8{dataBlkWriteIn}} & 496 | {blkOffset[4:2] == 3'd7, 497 | blkOffset[4:2] == 3'd6, 498 | blkOffset[4:2] == 3'd5, 499 | blkOffset[4:2] == 3'd4, 500 | blkOffset[4:2] == 3'd3, 501 | blkOffset[4:2] == 3'd2, 502 | blkOffset[4:2] == 3'd1, 503 | blkOffset[4:2] == 3'd0}; 504 | 505 | wire [15:0] dataBlkWstrb = ((iCacheHitWay1) ? 16'h000f : 506 | (iCacheHitWay2) ? 16'h00f0 : 507 | (iCacheHitWay3) ? 16'h0f00 : 508 | 16'hf000 ) & {4{wstrb}}; 509 | 510 | wire [15:0] dataBlkWrByteEnIn[7:0]; 511 | assign dataBlkWrByteEnIn[0] = dataBlkWstrb & {16{dataBlkWrSel[0]}}; 512 | assign dataBlkWrByteEnIn[1] = dataBlkWstrb & {16{dataBlkWrSel[1]}}; 513 | assign dataBlkWrByteEnIn[2] = dataBlkWstrb & {16{dataBlkWrSel[2]}}; 514 | assign dataBlkWrByteEnIn[3] = dataBlkWstrb & {16{dataBlkWrSel[3]}}; 515 | assign dataBlkWrByteEnIn[4] = dataBlkWstrb & {16{dataBlkWrSel[4]}}; 516 | assign dataBlkWrByteEnIn[5] = dataBlkWstrb & {16{dataBlkWrSel[5]}}; 517 | assign dataBlkWrByteEnIn[6] = dataBlkWstrb & {16{dataBlkWrSel[6]}}; 518 | assign dataBlkWrByteEnIn[7] = dataBlkWstrb & {16{dataBlkWrSel[7]}}; 519 | 520 | wire [31:0] dataBlkWdata1 = (stage == REQ_SND) ? data2ICacheBlk1 : wdata; 521 | wire [31:0] dataBlkWdata2 = (stage == REQ_SND) ? data2ICacheBlk2 : wdata; 522 | wire [31:0] dataBlkWdata3 = (stage == REQ_SND) ? data2ICacheBlk3 : wdata; 523 | wire [31:0] dataBlkWdata4 = (stage == REQ_SND) ? data2ICacheBlk4 : wdata; 524 | wire [31:0] dataBlkWdata5 = (stage == REQ_SND) ? data2ICacheBlk5 : wdata; 525 | wire [31:0] dataBlkWdata6 = (stage == REQ_SND) ? data2ICacheBlk6 : wdata; 526 | wire [31:0] dataBlkWdata7 = (stage == REQ_SND) ? data2ICacheBlk7 : wdata; 527 | wire [31:0] dataBlkWdata8 = (stage == REQ_SND) ? data2ICacheBlk8 : wdata; 528 | 529 | wire dataBlkWriteAlloc = (stage == REQ_SND && dataRequestedReady && data2ICacheBlkReady); 530 | assign dataBlkRead = (stage == FREE) && pgOffsetValid; 531 | assign dataBlkAddr = (!dataBlkRead) ? ((stage == REQ_SND) ? rsAddr[11:5] : index) : preIndex; 532 | assign dataBlkWrByteEn = (!dataBlkWriteAlloc) ? 16'd0 : 533 | //need to refill one way 534 | (rsRefillIndex == 2'd0) ? 16'h000f : 535 | (rsRefillIndex == 2'd1) ? 16'h00f0 : 536 | (rsRefillIndex == 2'd2) ? 16'h0f00 : 537 | 16'hf000 ; 538 | 539 | dataBlk_128X128 iCacheDataBlk1( 540 | .clka ( clk), 541 | .ena (dataBlkRead | dataBlkWriteAlloc | dataBlkWriteIn), 542 | .wea ( dataBlkWrByteEn | dataBlkWrByteEnIn[0]), 543 | .addra( dataBlkAddr), 544 | .dina ( {4{dataBlkWdata1}}), 545 | .douta( dataBlkOut1) 546 | ); 547 | 548 | dataBlk_128X128 iCacheDataBlk2( 549 | .clka ( clk), 550 | .ena (dataBlkRead | dataBlkWriteAlloc | dataBlkWriteIn), 551 | .wea ( dataBlkWrByteEn | dataBlkWrByteEnIn[1]), 552 | .addra( dataBlkAddr), 553 | .dina ( {4{dataBlkWdata2}}), 554 | .douta( dataBlkOut2) 555 | ); 556 | 557 | dataBlk_128X128 iCacheDataBlk3( 558 | .clka ( clk), 559 | .ena (dataBlkRead | dataBlkWriteAlloc | dataBlkWriteIn), 560 | .wea ( dataBlkWrByteEn | dataBlkWrByteEnIn[2]), 561 | .addra( dataBlkAddr), 562 | .dina ( {4{dataBlkWdata3}}), 563 | .douta( dataBlkOut3) 564 | ); 565 | 566 | dataBlk_128X128 iCacheDataBlk4( 567 | .clka ( clk), 568 | .ena (dataBlkRead | dataBlkWriteAlloc | dataBlkWriteIn), 569 | .wea ( dataBlkWrByteEn | dataBlkWrByteEnIn[3]), 570 | .addra( dataBlkAddr), 571 | .dina ( {4{dataBlkWdata4}}), 572 | .douta( dataBlkOut4) 573 | ); 574 | 575 | dataBlk_128X128 iCacheDataBlk5( 576 | .clka ( clk), 577 | .ena (dataBlkRead | dataBlkWriteAlloc | dataBlkWriteIn), 578 | .wea ( dataBlkWrByteEn | dataBlkWrByteEnIn[4]), 579 | .addra( dataBlkAddr), 580 | .dina ( {4{dataBlkWdata5}}), 581 | .douta( dataBlkOut5) 582 | ); 583 | 584 | dataBlk_128X128 iCacheDataBlk6( 585 | .clka ( clk), 586 | .ena (dataBlkRead | dataBlkWriteAlloc | dataBlkWriteIn), 587 | .wea ( dataBlkWrByteEn | dataBlkWrByteEnIn[5]), 588 | .addra( dataBlkAddr), 589 | .dina ( {4{dataBlkWdata6}}), 590 | .douta( dataBlkOut6) 591 | ); 592 | 593 | dataBlk_128X128 iCacheDataBlk7( 594 | .clka ( clk), 595 | .ena (dataBlkRead | dataBlkWriteAlloc | dataBlkWriteIn), 596 | .wea ( dataBlkWrByteEn | dataBlkWrByteEnIn[6]), 597 | .addra( dataBlkAddr), 598 | .dina ( {4{dataBlkWdata7}}), 599 | .douta( dataBlkOut7) 600 | ); 601 | 602 | dataBlk_128X128 iCacheDataBlk8( 603 | .clka ( clk), 604 | .ena (dataBlkRead | dataBlkWriteAlloc | dataBlkWriteIn), 605 | .wea ( dataBlkWrByteEn | dataBlkWrByteEnIn[7]), 606 | .addra( dataBlkAddr), 607 | .dina ( {4{dataBlkWdata8}}), 608 | .douta( dataBlkOut8) 609 | ); 610 | 611 | endmodule 612 | -------------------------------------------------------------------------------- /rtl/xilinx_ip/ctrlBlk/ctrlBlk.xci: -------------------------------------------------------------------------------- 1 | 2 | 3 | xilinx.com 4 | xci 5 | unknown 6 | 1.0 7 | 8 | 9 | ctrlBlk 10 | 11 | 12 | 4096 13 | 1 14 | 0 15 | 0 16 | 0 17 | 18 | 1 19 | 100000000 20 | 0 21 | 0 22 | 0 23 | 0 24 | 0 25 | 0 26 | 0 27 | 0 28 | 0 29 | 0 30 | 0 31 | 1 32 | 1 33 | 1 34 | 1 35 | 1 36 | 0.000 37 | AXI4LITE 38 | READ_WRITE 39 | 0 40 | 0 41 | 0 42 | 0 43 | 0 44 | 1 45 | 0 46 | 0 47 | 0 48 | 49 | 1 50 | 100000000 51 | 0 52 | 0 53 | 0 54 | 0 55 | 0 56 | 0 57 | 0 58 | 0 59 | 0 60 | 0 61 | 0 62 | 1 63 | 1 64 | 1 65 | 1 66 | 1 67 | 0.000 68 | AXI4LITE 69 | READ_WRITE 70 | 0 71 | 0 72 | 0 73 | 0 74 | 0 75 | OTHER 76 | NONE 77 | 8192 78 | 32 79 | 1 80 | 81 | OTHER 82 | NONE 83 | 8192 84 | 32 85 | 1 86 | 87 | 88 | 100000000 89 | 0 90 | 0.000 91 | 0 92 | 7 93 | 7 94 | 1 95 | 4 96 | 0 97 | 1 98 | 9 99 | 0 100 | 1 101 | 1 102 | NONE 103 | 0 104 | 0 105 | 0 106 | ./ 107 | 0 108 | 0 109 | 0 110 | 0 111 | 0 112 | 0 113 | 0 114 | 0 115 | Estimated Power for IP : 10.2646 mW 116 | artix7 117 | 0 118 | 1 119 | 0 120 | 0 121 | 0 122 | 0 123 | 0 124 | 0 125 | 0 126 | 0 127 | 0 128 | 0 129 | 0 130 | 0 131 | 0 132 | 0 133 | ctrlBlk.mem 134 | no_coe_file_loaded 135 | 0 136 | 0 137 | 0 138 | 0 139 | 1 140 | 128 141 | 128 142 | 1 143 | 1 144 | 96 145 | 96 146 | 0 147 | 0 148 | CE 149 | CE 150 | ALL 151 | 0 152 | 0 153 | 0 154 | 1 155 | 0 156 | 0 157 | 0 158 | 1 159 | 1 160 | 128 161 | 128 162 | WRITE_FIRST 163 | WRITE_FIRST 164 | 96 165 | 96 166 | artix7 167 | 4 168 | Memory_Slave 169 | AXI4_Full 170 | false 171 | Minimum_Area 172 | false 173 | 9 174 | NONE 175 | no_coe_file_loaded 176 | ALL 177 | ctrlBlk 178 | false 179 | false 180 | false 181 | false 182 | false 183 | false 184 | false 185 | false 186 | false 187 | Use_ENA_Pin 188 | Always_Enabled 189 | Single_Bit_Error_Injection 190 | true 191 | Native 192 | false 193 | no_mem_loaded 194 | Single_Port_RAM 195 | WRITE_FIRST 196 | WRITE_FIRST 197 | 0 198 | 0 199 | BRAM 200 | 0 201 | 100 202 | 100 203 | 50 204 | 0 205 | 0 206 | 0 207 | 8kx2 208 | false 209 | false 210 | 1 211 | 1 212 | 96 213 | 96 214 | false 215 | false 216 | false 217 | false 218 | 0 219 | false 220 | false 221 | CE 222 | CE 223 | SYNC 224 | false 225 | false 226 | false 227 | false 228 | false 229 | false 230 | false 231 | 128 232 | 96 233 | 96 234 | No_ECC 235 | false 236 | false 237 | false 238 | Stand_Alone 239 | artix7 240 | 241 | 242 | xc7a200t 243 | fbg676 244 | VERILOG 245 | 246 | MIXED 247 | -2 248 | 249 | TRUE 250 | TRUE 251 | IP_Flow 252 | 2 253 | TRUE 254 | . 255 | 256 | . 257 | 2018.3 258 | OUT_OF_CONTEXT 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | --------------------------------------------------------------------------------