diff --git a/synthetical/func_test/soc_sram_func/rtl/myCPU/MiniMIPS32.sv b/synthetical/func_test/soc_sram_func/rtl/myCPU/MiniMIPS32.sv index bf36b2587071bfce02f6b8e6968ca8a510bc54ef..e543c4aa03a31b51658ec686f4f2ec1102998dcb 100644 --- a/synthetical/func_test/soc_sram_func/rtl/myCPU/MiniMIPS32.sv +++ b/synthetical/func_test/soc_sram_func/rtl/myCPU/MiniMIPS32.sv @@ -37,7 +37,7 @@ module MiniMIPS32( logic [`Alutype_size-1: 0] id_alutype, exe_alutype; logic [`Aluop_size-1: 0] id_aluop, exe_aluop; logic id_wreg, id_shift, rtsel, sext, upper, immsel, id_mreg, - equ, stallreq_id, jal, id_mfc0, id_mtc0, next_delay, id_delay, syscall, _break, eret, div_sig; + equ, stallreq_id, jal, id_mfc0, id_mtc0, next_delay, id_delay, syscall,RI, _break, eret, div_sig; logic [1: 0] id_whilo, fwrd1, fwrd2; logic [31: 0] unsigned_imm, signed_imm, out_imm; logic [31: 0] ans_imm; @@ -54,12 +54,14 @@ module MiniMIPS32( //MEM logic mem_wreg, mem_mreg, mem_cp0_we, mem_delay, AdEL, AdES, flush, need_extend; - logic[4: 0] mem_rd, mem_cp0_rd, mem_exccode_in, mem_exccode_out; + logic[4: 0] mem_rd, mem_cp0_rd, mem_exccode_in, mem_exccode_out,cp0_exccode; logic[31: 0] mem_res, mem_rd2, mem_cp0_data, mem_pc, excaddr, mem_big_addr, vaddr; logic[63: 0] mem_mulres; logic[`Aluop_size-1: 0] mem_aluop; logic[3: 0] mem_dre; logic [1: 0] mem_whilo; + reg [`REG_BUS] status; + reg [`REG_BUS] cause; //WB logic wb_mreg, wb_wreg, wb_cp0_we, wb_need_extend; @@ -158,7 +160,8 @@ module MiniMIPS32( .syscall(syscall), ._break(_break), .eret(eret), - .id_src1(id_src1) + .id_src1(id_src1), + .RI(RI) ); register id_module3( @@ -217,6 +220,9 @@ module MiniMIPS32( else if(eret)begin id_exccode_out = 5'h11; end + else if(RI)begin + id_exccode_out = 5'h0a; + end else begin id_exccode_out = id_exccode_in; end @@ -314,14 +320,16 @@ module MiniMIPS32( .waddr(wb_cp0_rd), .wdata(wb_cp0_data), .delay(mem_delay), - .exccode(mem_exccode_out), + .exccode(cp0_exccode), .int_i(ext_int), .pc(mem_pc), .excaddr(excaddr), .flush(flush), .data_o(cp0_data), .raddr(exe_cp0_rd), - .vaddr(vaddr) + .vaddr(vaddr), + .status(status), + .cause(cause) ); assign vaddr = mem_exccode_in == 5'h4 ? mem_pc : mem_res; // TODO: (ALU����ͬѧ����)aluop��ij??????λ����Ӧ��???����һ??????, exe_module5��exe_module7 @@ -424,6 +432,12 @@ module MiniMIPS32( .AdES(AdES), .need_extend(need_extend) ); + exception mem_module3( + .status(status), + .cause(cause), + .mem_exccode_out(mem_exccode_out), + .cp0_exccode(cp0_exccode) + ); always_comb begin if(AdES)begin mem_exccode_out = 5'h5; @@ -435,6 +449,7 @@ module MiniMIPS32( mem_exccode_out = mem_exccode_in; end end + // MEM - WB ---------------------------------- @@ -474,7 +489,7 @@ module MiniMIPS32( .wb_need_extend(wb_need_extend) ); - // TODO: (MCU����ͬѧ����)����dre��???������������ݣ�����?131?????? + // TODO: (MCU����ͬѧ����)����dre��???������������ݣ����??131?????? assign pre_dre_dout = dout; mux6 wb_module3(wb_need_extend, wb_dre, pre_dre_dout, wb_dout); diff --git a/synthetical/func_test/soc_sram_func/rtl/myCPU/cp0.sv b/synthetical/func_test/soc_sram_func/rtl/myCPU/cp0.sv index 2d376b544bc1d4c3c0aec49e03b140e63b5a362c..f51d7c95078e93ee58c5be0b9c54b318da88812f 100644 --- a/synthetical/func_test/soc_sram_func/rtl/myCPU/cp0.sv +++ b/synthetical/func_test/soc_sram_func/rtl/myCPU/cp0.sv @@ -23,28 +23,30 @@ module cp0( input logic cpu_clk, input logic cpu_rst_n, - input logic we,//写使能 + input logic we,//写使? input logic [4: 0] waddr,//写入的寄存器地址 - input logic [31: 0] wdata,//写入的数据 + input logic [31: 0] wdata,//写入的数? input logic delay,//是否是延迟槽指令 - input logic [4: 0] exccode,//异常的信号类型 + input logic [4: 0] exccode,//异常的信号类? input logic [7: 0] int_i,//中断 input logic [31: 0] pc,//发生异常的指令的PC地址 input logic [4: 0] raddr, input logic [31: 0] vaddr,// badvaddr - output logic [31: 0] excaddr,//异常处理程序的地址入口 + output logic [31: 0] excaddr,//异常处理程序的地?入口 output logic [31: 0] data_o,//从CP0中读出的寄存器的数据 output logic flush,//清除信号 - output logic flush_im + output logic flush_im, + output logic [`REG_BUS] status, + output logic [`REG_BUS] cause //整个程序过程中删去了读使能,在CP0或�?�是CCU里判断异常并跳转 ); - reg [`REG_BUS] badvaddr; //CP0的BadVaddr寄存器 - reg [`REG_BUS] status; //CP0的Status寄存器 - reg [`REG_BUS] cause; //CP0的Cause寄存器 - reg [`REG_BUS] epc; //CP0的EPC寄存器 + reg [`REG_BUS] badvaddr; //CP0的BadVaddr寄存? + reg [`REG_BUS] status; //CP0的Status寄存? + reg [`REG_BUS] cause; //CP0的Cause寄存? + reg [`REG_BUS] epc; //CP0的EPC寄存? - //得到status和cause寄存器的�?? + //得到status和cause寄存器的??? assign status_o = status; assign cause_o = cause; always_comb begin @@ -56,7 +58,7 @@ module cp0( default: data_o = 32'b0; endcase end - + //flush信号 always_comb begin if(cpu_rst_n == `RST_ENABLE) begin @@ -70,7 +72,7 @@ module cp0( end end - //清除指令存储器IM的信�?? flush_im + //清除指令存储器IM的信??? flush_im always @(posedge cpu_clk) begin if(cpu_rst_n == `RST_ENABLE) begin flush_im <= 1'b0; @@ -108,25 +110,31 @@ module cp0( endtask //异常处理地址 - always_comb begin - case(exccode) - `EXC_INT: excaddr = `EXC_INT_ADDR; - `EXC_ERET: begin - if(waddr == `CP0_EPC && we == `WRITE_ENABLE)begin - excaddr = wdata; + always @(*) begin + if(cpu_rst_n == `RST_ENABLE) begin + excaddr = `PC_INIT; end else begin - excaddr = epc; - end - end - `EXC_SYS: excaddr = `EXC_ADDR; - `EXC_NONE: excaddr = `EXC_ADDR; - `EXC_AdEL:excaddr = `EXC_ADDR; - `EXC_AdES: excaddr = `EXC_ADDR; - `EXC_BREAK: excaddr = `EXC_ADDR; - `EXC_OV: excaddr = `EXC_ADDR; - default:excaddr = `ZERO_WORD; - endcase; + case(exccode) + `EXC_INT: excaddr = `EXC_INT_ADDR; + `EXC_ERET: begin + if(waddr == `CP0_EPC && we == `WRITE_ENABLE)begin + excaddr = wdata; + end + else begin + excaddr = epc; + end + end + `EXC_SYS: excaddr = `EXC_ADDR; + `EXC_NONE: excaddr = `EXC_ADDR; + `EXC_AdEL:excaddr = `EXC_ADDR; + `EXC_AdES: excaddr = `EXC_ADDR; + `EXC_BREAK: excaddr = `EXC_ADDR; + `EXC_OV: excaddr = `EXC_ADDR; + `EXC_RI: excaddr = `EXC_ADDR; + default:excaddr = `ZERO_WORD; + endcase; + end end always @(posedge cpu_clk) begin diff --git a/synthetical/func_test/soc_sram_func/rtl/myCPU/dcu.sv b/synthetical/func_test/soc_sram_func/rtl/myCPU/dcu.sv index 0a85f709004631b1587ac9b167d5fcc2a666e513..b7b340161afefca9f9b15c3d17aec85f9b1e1d19 100644 --- a/synthetical/func_test/soc_sram_func/rtl/myCPU/dcu.sv +++ b/synthetical/func_test/soc_sram_func/rtl/myCPU/dcu.sv @@ -20,7 +20,7 @@ // ////////////////////////////////////////////////////////////////////////////////// -//139�?? +//139�??? module dcu( input logic cpu_rst_n, input logic[5: 0] op, @@ -33,16 +33,16 @@ module dcu( input logic mem_wreg, input logic exe_mreg, input logic mem_mreg, - input logic equ,//beq和bne的两个条件是否相�? + input logic equ,//beq和bne的两个条件是否相�?? input logic [31: 0] id_src1, - output logic wreg,//寄存器写使能�? 0无效 + output logic wreg,//寄存器写使能�?? 0无效 output logic[`Alutype_size-1: 0] alutype,//选择算术运算还是逻辑运算 output logic[`Aluop_size-1: 0] aluop,//alu选择信号 output logic[1: 0] whilo,//hilo寄存器写使能?? 0无效 output logic shift,//移位选择信号?? 0表示使用rd1,1表示使用sa output logic rtsel,//选择写入寄存器的索引为rd还是rt?? 0表示用rd?? 1表示用rt output logic sext,//是否进行符号扩展??1时进行符号扩?? - output logic upper,//是进行立即数扩展还是左移16位,0�????择立�??? + output logic upper,//是进行立即数扩展还是左移16位,0�?????择立�???? output logic immsel,//决定第二个源操作数是来自rt还是立即数, 0表示用rt output logic mreg,//是写入计算结果还是读存储器得来的结果??0表示将计算结果写?? output logic [1: 0] fwrd1, @@ -56,7 +56,8 @@ module dcu( output logic syscall, output logic _break, output logic eret, - output logic next_delay//下一条指令是否是延迟槽指�? + output logic next_delay,//下一条指令是否是延迟槽指�?? + output logic RI ); logic add, addi, addu, addiu, sub, subu, slt, slti, sltu, @@ -118,7 +119,7 @@ module dcu( assign eret = ~op[5] & op[4] & ~op[3] & ~op[2] & ~op[1] & ~op[0] & id_rs[4] & ~id_rs[2]; assign syscall = _reg & ~func[5] & ~func[4] & func[3] & func[2] & ~func[1] & ~func[0]; assign _break = _reg & ~func[5] & ~func[4] & func[3] & func[2] & ~func[1] & func[0]; - + assign RI = ~(blez|bltz|bgezal|bltzal| jalr|bgtz|bgez|_break | syscall | eret | mtc0 | mfc0 | sw | sh | sb | lw | lhu | lh | lbu | lb | mtlo | mthi | mflo | mfhi |jr | jal | j |bne |beq | srl| srlv| sra | srav | sll | sllv | xori | _xor | ori | _or | _nor| lui | andi | _and|multu | mult | divu | div | sltiu | sltu | slti | slt | subu | sub | addiu | addu | addi | add ); assign bgez = ~op[5] & ~op[4] & ~op[3] & ~op[2] & ~op[1] & op[0] & ~id_rt[4] & id_rt[0]; assign bgtz = ~op[5] & ~op[4] & ~op[3] & op[2] & op[1] & op[0]; assign blez = ~op[5] & ~op[4] & ~op[3] & op[2] & op[1] & ~op[0]; @@ -128,7 +129,6 @@ module dcu( assign jalr = _reg & ~func[5] & ~func[4] & func[3] & ~func[2] & ~func[1] & func[0]; assign ge = $signed(id_src1) >= 0; assign g = $signed(id_src1) > 0; - always_comb begin if(cpu_rst_n == `RST_ENABLE)begin wreg = 1'b0; diff --git a/synthetical/func_test/soc_sram_func/rtl/myCPU/defines.sv b/synthetical/func_test/soc_sram_func/rtl/myCPU/defines.sv index 62b990ead4c2ad36ebea12bafb4c6be495cae46d..1b62ca2d62c5ac36f45f8fccaaa35c0b18b509e3 100644 --- a/synthetical/func_test/soc_sram_func/rtl/myCPU/defines.sv +++ b/synthetical/func_test/soc_sram_func/rtl/myCPU/defines.sv @@ -83,7 +83,8 @@ `define EXC_AdES 5'h5 //AdES异常的编码 `define EXC_AdEL 5'h4 //AdEL异常的编码 `define EXC_BREAK 5'h09 //Break - +`define EXC_RI 5'h0a //RI +`define PC_INIT 32'hBFBF_FFFC //流水线暂停参数 `define STALL_BUS 3 : 0 //暂停信号宽度 `define STOP 1'b1 //流水线暂停 diff --git a/synthetical/func_test/soc_sram_func/rtl/myCPU/exception.sv b/synthetical/func_test/soc_sram_func/rtl/myCPU/exception.sv new file mode 100644 index 0000000000000000000000000000000000000000..fb14f11a00d7a2dd1a7bcd7f7128e10e85c50475 --- /dev/null +++ b/synthetical/func_test/soc_sram_func/rtl/myCPU/exception.sv @@ -0,0 +1,38 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 2021/11/30 08:45:23 +// Design Name: +// Module Name: exception +// Project Name: +// Target Devices: +// Tool Versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// + + +module exception( +input logic [31:0] status, +input logic [31:0] cause, +input logic [4:0] mem_exccode_out, +output logic [4:0] cp0_exccode + + ); + always @(*) begin + if(status[1]== 0 && status[0] == 1 && (status[15:8] & cause[15:8] !=8'h00))begin + cp0_exccode <= `EXC_INT; + end + else begin + cp0_exccode <= mem_exccode_out; + end + end +endmodule