From 015a391e2c9ae53c960aad7b251e67ed4d66eb74 Mon Sep 17 00:00:00 2001 From: Rookie <74707760+Rookie-Cai-niao@users.noreply.github.com> Date: Wed, 30 Mar 2022 10:23:24 +0800 Subject: [PATCH 001/114] add syscall,break --- inst_rom.bin | Bin 0 -> 128 bytes src/vsrc/cpu_top.v | 63 +++++++++++++++++++++---- src/vsrc/ctrl.v | 37 +++++++++++++-- src/vsrc/defines.v | 2 + src/vsrc/if_buffer.v | 6 +++ src/vsrc/pc_reg.v | 5 ++ src/vsrc/pipeline/1_fetch/if_id.v | 6 +++ src/vsrc/pipeline/2_decode/id.v | 27 ++++++++++- src/vsrc/pipeline/2_decode/id_ex.v | 24 +++++++++- src/vsrc/pipeline/3_execution/ex.v | 9 +++- src/vsrc/pipeline/3_execution/ex_mem.v | 22 ++++++++- src/vsrc/pipeline/4_mem/mem.v | 13 ++++- src/vsrc/pipeline/4_mem/mem_wb.v | 15 +++++- 13 files changed, 209 insertions(+), 20 deletions(-) create mode 100644 inst_rom.bin diff --git a/inst_rom.bin b/inst_rom.bin new file mode 100644 index 0000000000000000000000000000000000000000..3279497b16fcf9e9256f20ede3f5acb48a4a7b32 GIT binary patch literal 128 zcmWN=Eet?V6oApY=PxRE6N#dzz9@>SD2l2mimE7zswj%8D2nDg+fgxzim|NObLP%l l#R-_QV8ek64?Zex$c!ahj$C>2Rq-O`tk`kl#*3edAOB+X66F8@ literal 0 HcmV?d00001 diff --git a/src/vsrc/cpu_top.v b/src/vsrc/cpu_top.v index f0874fd..f575e89 100644 --- a/src/vsrc/cpu_top.v +++ b/src/vsrc/cpu_top.v @@ -48,6 +48,8 @@ module cpu_top ( assign Instram_branch_flag=branch_flag; wire[`RegBus] branch_target_address; wire[`RegBus] link_addr; + wire flush; + wire[`RegBus] new_pc; pc_reg u_pc_reg( .clk(clk), @@ -55,23 +57,26 @@ module cpu_top ( .pc(pc), .ce(chip_enable), .branch_flag_i(branch_flag), - .branch_target_address(branch_target_address) + .branch_target_address(branch_target_address), + .flush(flush), + .new_pc(new_pc) ); wire [`InstAddrBus]pc2; + wire if_inst_valid; if_buffer if_buffer_1( .clk(clk), .rst(rst), .pc_i(pc), .branch_flag_i(branch_flag), .pc_valid(if_inst_valid), - .pc_o(pc2) + .pc_o(pc2), + .flush(flush) ); wire[`InstAddrBus] id_pc; wire[`InstBus] id_inst; - wire if_inst_valid; // wire if_id_instr_invalid; if_id u_if_id( @@ -82,7 +87,8 @@ module cpu_top ( .id_pc_o(id_pc), .id_inst_o(id_inst), .if_inst_valid(if_inst_valid), - .branch_flag_i(branch_flag) + .branch_flag_i(branch_flag), + .flush(flush) ); wire[`AluOpBus] id_aluop; @@ -113,6 +119,9 @@ module cpu_top ( wire stallreq_from_id; + wire[1:0] id_excepttype_o; + wire[`RegBus] id_current_inst_address_o; + id u_id( .rst(rst), @@ -151,7 +160,10 @@ module cpu_top ( .branch_target_address_o(branch_target_address), .link_addr_o(link_addr), - .stallreq(stallreq_from_id) + .stallreq(stallreq_from_id), + + .excepttype_o(id_excepttype_o), + .current_inst_address_o(id_current_inst_address_o) ); wire[`AluOpBus] ex_aluop; @@ -164,6 +176,8 @@ module cpu_top ( wire[`InstAddrBus] ex_inst_pc_i; wire[`RegBus] ex_link_address; wire[`RegBus] ex_inst_i; + wire[1:0] ex_excepttype_i; + wire[`RegBus] ex_current_inst_address_i; id_ex id_ex0( .clk(clk), @@ -179,6 +193,9 @@ module cpu_top ( .id_inst_valid(id_inst_valid), .id_link_address(link_addr), .id_inst(id_inst_o), + .flush(flush), + .id_excepttype(id_excepttype_o), + .id_current_inst_address(id_current_inst_address_o), .ex_aluop(ex_aluop), .ex_alusel(ex_alusel), @@ -189,7 +206,9 @@ module cpu_top ( .ex_inst_pc(ex_inst_pc_i), .ex_inst_valid(ex_inst_valid_i), .ex_link_address(ex_link_address), - .ex_inst(ex_inst_i) + .ex_inst(ex_inst_i), + .ex_excepttype(ex_excepttype_i), + .ex_current_inst_address(ex_current_inst_address_i) ); @@ -197,6 +216,8 @@ module cpu_top ( wire[`InstAddrBus] ex_inst_pc_o; wire[`RegBus] ex_addr_o; wire[`RegBus] ex_reg2_o; + wire[1:0] ex_excepttype_o; + wire[`RegBus] ex_current_inst_address_o; ex u_ex( .rst(rst), @@ -211,6 +232,8 @@ module cpu_top ( .inst_pc_i(ex_inst_pc_i), .inst_i(ex_inst_i), .link_addr_i(ex_link_address), + .excepttype_i(ex_excepttype_i), + .current_inst_address_i(ex_current_inst_address_i), .wd_o(ex_reg_waddr_o), .wreg_o(ex_wreg_o), @@ -219,7 +242,9 @@ module cpu_top ( .inst_pc_o(ex_inst_pc_o), .aluop_o(ex_aluop_o), .mem_addr_o(ex_addr_o), - .reg2_o(ex_reg2_o) + .reg2_o(ex_reg2_o), + .excepttype_o(ex_excepttype_o), + .current_inst_address_o(ex_current_inst_address_o) ); @@ -233,6 +258,8 @@ module cpu_top ( wire[`AluOpBus] mem_aluop_i; wire[`RegBus] mem_addr_i; wire[`RegBus] mem_reg2_i; + wire[1:0] mem_excepttype_i; + wire[`RegBus] mem_current_inst_address_i; ex_mem u_ex_mem( .clk(clk ), @@ -246,6 +273,9 @@ module cpu_top ( .ex_aluop(ex_aluop_o), .ex_mem_addr(ex_addr_o), .ex_reg2(ex_reg2_o), + .flush(flush), + .ex_excepttype(ex_excepttype_o), + .ex_current_inst_address(ex_current_inst_address_o), .mem_wd(mem_reg_waddr_i ), .mem_wreg(mem_wreg_i ), @@ -254,7 +284,9 @@ module cpu_top ( .mem_inst_pc(mem_inst_pc), .mem_aluop(mem_aluop_i), .mem_mem_addr(mem_addr_i), - .mem_reg2(mem_reg2_i) + .mem_reg2(mem_reg2_i), + .mem_excepttype(mem_excepttype_i), + .mem_current_inst_address(mem_current_inst_address_i) ); wire LLbit_o; @@ -262,6 +294,8 @@ module cpu_top ( wire wb_LLbit_value_i; wire mem_LLbit_we_o; wire mem_LLbit_value_o; + wire[1:0] mem_excepttype_o; + wire[`RegBus] mem_current_inst_address_o; mem u_mem( .rst (rst ), @@ -279,6 +313,9 @@ module cpu_top ( .wb_LLbit_we_i(wb_LLbit_we_i), .wb_LLbit_value_i(wb_LLbit_value_i), + .excepttype_i(mem_excepttype_i), + .current_inst_address_i(mem_current_inst_address_i), + .wd_o (mem_reg_waddr_o), .wreg_o (mem_wreg_o ), @@ -291,7 +328,10 @@ module cpu_top ( .mem_ce_o(dram_ce_o), .LLbit_we_o(mem_LLbit_we_o), - .LLbit_value_o(mem_LLbit_value_o) + .LLbit_value_o(mem_LLbit_value_o), + + .excepttype_o(mem_excepttype_o), + .current_inst_address_o(mem_current_inst_address_o) ); @@ -320,6 +360,8 @@ module cpu_top ( .mem_LLbit_we(mem_LLbit_we_o), .mem_LLbit_value(mem_LLbit_value_o), + .flush(flush), + .wb_wd(wb_reg_waddr), .wb_wreg(wb_wreg), .wb_wdata(wb_reg_wdata), @@ -354,6 +396,9 @@ module cpu_top ( .rst (rst ), .id_is_branch_instr_i (branch_flag), .stallreq_from_id(stallreq_from_id), + .excepttype_i(mem_excepttype_o), + .new_pc(new_pc), + .flush(flush), .pc_instr_invalid_o (), .if_id_instr_invalid_o () ); diff --git a/src/vsrc/ctrl.v b/src/vsrc/ctrl.v index e915871..d9d7946 100644 --- a/src/vsrc/ctrl.v +++ b/src/vsrc/ctrl.v @@ -1,8 +1,15 @@ +`include "defines.v" module ctrl ( input wire clk, input wire rst, input wire id_is_branch_instr_i, input wire stallreq_from_id, + + input wire[1:0] excepttype_i, + + output reg[`RegBus] new_pc, + output reg flush, + output wire pc_instr_invalid_o, output wire if_id_instr_invalid_o @@ -14,12 +21,36 @@ module ctrl ( always @(posedge clk or negedge rst_n) begin if (!rst_n) - branch_flush_cnt <= 0; + begin + branch_flush_cnt <= 2'b0; + flush <= 1'b0; + new_pc <= `ZeroWord; + end else if (!(branch_flush_cnt==0)) - branch_flush_cnt <= branch_flush_cnt -1; + begin + branch_flush_cnt <= branch_flush_cnt -1; + flush <= 1'b0; + new_pc <= `ZeroWord; + end else if(id_is_branch_instr_i) - branch_flush_cnt <= 1; + begin + branch_flush_cnt <= 1; + flush <= 1'b0; + new_pc <= `ZeroWord; + end + else if(excepttype_i != 0) + begin + flush <= 1'b1; + case (excepttype_i) + 2'b01: + new_pc <= 32'h00000020; + 2'b10: + new_pc <= 32'h00000040; + default:begin + end + endcase + end else branch_flush_cnt <= branch_flush_cnt; diff --git a/src/vsrc/defines.v b/src/vsrc/defines.v index 73bd24b..5c8c8ea 100644 --- a/src/vsrc/defines.v +++ b/src/vsrc/defines.v @@ -150,6 +150,8 @@ `define EXE_LL_OP 8'b00100010 `define EXE_SC_OP 8'b00100011 `define EXE_PCADD_OP 8'b00100100 +`define EXE_SYSCALL_OP 8'b00100101 +`define EXE_BREAK_OP 8'b00100110 diff --git a/src/vsrc/if_buffer.v b/src/vsrc/if_buffer.v index 125ce99..b7c0256 100644 --- a/src/vsrc/if_buffer.v +++ b/src/vsrc/if_buffer.v @@ -4,6 +4,7 @@ module if_buffer ( input wire clk, input wire rst, input wire [`InstAddrBus] pc_i, + input wire flush, input wire branch_flag_i, output reg [`InstAddrBus] pc_o, @@ -22,6 +23,11 @@ module if_buffer ( pc_o <= `ZeroWord; pc_valid <= `InstInvalid; end + else if(flush == 1'b1) + begin + pc_o <= `ZeroWord; + pc_valid <= `InstInvalid; + end else begin pc_o <= pc_i; diff --git a/src/vsrc/pc_reg.v b/src/vsrc/pc_reg.v index eae6168..4a24782 100644 --- a/src/vsrc/pc_reg.v +++ b/src/vsrc/pc_reg.v @@ -6,6 +6,9 @@ module pc_reg ( input wire branch_flag_i, input wire[`RegBus] branch_target_address, + input wire flush, + input wire[`RegBus] new_pc, + output reg[`InstAddrBus] pc, output reg ce ); @@ -14,6 +17,8 @@ module pc_reg ( begin if(ce == `ChipDisable) pc <= 32'h1c000000; + else if(flush == 1'b1) + pc <= new_pc; else if(branch_flag_i == `Branch) pc <= branch_target_address; else diff --git a/src/vsrc/pipeline/1_fetch/if_id.v b/src/vsrc/pipeline/1_fetch/if_id.v index f759967..94c1047 100644 --- a/src/vsrc/pipeline/1_fetch/if_id.v +++ b/src/vsrc/pipeline/1_fetch/if_id.v @@ -7,6 +7,7 @@ module if_id ( input wire[`InstAddrBus] if_pc_i, input wire[`InstAddrBus] if_inst_i, input wire if_inst_valid, + input wire flush, output reg[`InstAddrBus] id_pc_o, output reg[`InstBus] id_inst_o ); @@ -19,6 +20,11 @@ module if_id ( id_pc_o <= `ZeroWord; id_inst_o <= `ZeroWord; end + else if(flush == 1'b1) + begin + id_pc_o <= `ZeroWord; + id_inst_o <= `ZeroWord; + end else if(branch_flag_i || if_inst_valid == `InstInvalid) begin id_pc_o <= `ZeroWord; diff --git a/src/vsrc/pipeline/2_decode/id.v b/src/vsrc/pipeline/2_decode/id.v index 7e3bcde..eb3d618 100644 --- a/src/vsrc/pipeline/2_decode/id.v +++ b/src/vsrc/pipeline/2_decode/id.v @@ -37,6 +37,8 @@ module id( output reg inst_valid, output reg[`InstAddrBus] inst_pc, output wire[`RegBus] inst_o, + output wire[1:0] excepttype_o, + output wire[`RegBus] current_inst_address_o, // -> PC output reg branch_flag_o, @@ -90,6 +92,13 @@ module id( (ex_aluop_i == `EXE_ST_H_OP) || (ex_aluop_i == `EXE_ST_W_OP) ) ? 1'b1 : 1'b0; + reg excepttype_is_syscall; + reg excepttype_is_break; + + assign excepttype_o = {excepttype_is_syscall,excepttype_is_break}; + assign current_inst_address_o = pc_i; + + always @(*) begin stallreq_for_reg1_loadrelate = `NoStop; @@ -132,6 +141,8 @@ module id( branch_flag_o = `NotBranch; branch_target_address_o = `ZeroWord; link_addr_o = `ZeroWord; + excepttype_is_break = `False_v; + excepttype_is_syscall = `False_v; end else begin @@ -691,11 +702,23 @@ module id( end `EXE_BREAK: begin - + wreg_o = `WriteDisable; + aluop_o = `EXE_BREAK_OP; + alusel_o = `EXE_RES_NOP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + inst_valid = `InstValid; + excepttype_is_break = `True_v; end `EXE_SYSCALL: begin - + wreg_o = `WriteEnable; + aluop_o = `EXE_SYSCALL_OP; + alusel_o = `EXE_RES_NOP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + inst_valid = `InstValid; + excepttype_is_syscall = `True_v; end default: begin diff --git a/src/vsrc/pipeline/2_decode/id_ex.v b/src/vsrc/pipeline/2_decode/id_ex.v index 3f89c6c..69bb543 100644 --- a/src/vsrc/pipeline/2_decode/id_ex.v +++ b/src/vsrc/pipeline/2_decode/id_ex.v @@ -13,6 +13,9 @@ module id_ex ( input wire[`InstAddrBus] id_inst_pc, input wire[`RegBus] id_link_address, input wire[`RegBus] id_inst, + input wire flush, + input wire[1:0] id_excepttype, + input wire[`RegBus] id_current_inst_address, output reg[`AluOpBus] ex_aluop, output reg[`AluSelBus] ex_alusel, @@ -23,7 +26,9 @@ module id_ex ( output reg ex_inst_valid, output reg[`InstAddrBus] ex_inst_pc, output reg[`RegBus] ex_link_address, - output reg[`RegBus] ex_inst + output reg[`RegBus] ex_inst, + output reg[1:0]ex_excepttype, + output reg[`RegBus] ex_current_inst_address ); always @(posedge clk) begin @@ -38,6 +43,21 @@ always @(posedge clk) begin ex_inst_valid <= `InstInvalid; ex_link_address <= `ZeroWord; ex_inst <= `ZeroWord; + ex_excepttype <= 2'b00; + ex_current_inst_address <= `ZeroWord; + end else if(flush == 1'b1)begin + ex_aluop <= `EXE_NOP_OP; + ex_alusel <= `EXE_RES_NOP; + ex_reg1 <= `ZeroWord; + ex_reg2 <= `ZeroWord; + ex_wd <= `NOPRegAddr; + ex_wreg <= `WriteDisable; + ex_inst_pc <= `ZeroWord; + ex_inst_valid <= `InstInvalid; + ex_link_address <= `ZeroWord; + ex_inst <= `ZeroWord; + ex_excepttype <= 2'b00; + ex_current_inst_address <= `ZeroWord; end else begin ex_aluop <= id_aluop; ex_alusel <= id_alusel; @@ -49,6 +69,8 @@ always @(posedge clk) begin ex_inst_valid <= id_inst_valid; ex_link_address <= id_link_address; ex_inst <= id_inst; + ex_excepttype <= id_excepttype; + ex_current_inst_address <= id_current_inst_address; end end diff --git a/src/vsrc/pipeline/3_execution/ex.v b/src/vsrc/pipeline/3_execution/ex.v index 2bda9af..88db66e 100644 --- a/src/vsrc/pipeline/3_execution/ex.v +++ b/src/vsrc/pipeline/3_execution/ex.v @@ -13,6 +13,8 @@ module ex ( input wire[`InstAddrBus] inst_pc_i, input wire[`RegBus] inst_i, input wire[`RegBus] link_addr_i, + input wire[1:0] excepttype_i, + input wire[`RegBus] current_inst_address_i, output reg[`RegAddrBus] wd_o, output reg wreg_o, @@ -21,7 +23,9 @@ module ex ( output reg[`InstAddrBus] inst_pc_o, output wire[`AluOpBus] aluop_o, output wire[`RegBus] mem_addr_o, - output wire[`RegBus] reg2_o + output wire[`RegBus] reg2_o, + output wire[1:0] excepttype_o, + output wire[`RegBus] current_inst_address_o ); reg[`RegBus] logicout; @@ -33,6 +37,9 @@ module ex ( assign mem_addr_o = reg1_i + {{20{inst_i[21]}},inst_i[21:10]}; assign reg2_o = reg2_i; + assign excepttype_o = excepttype_i; + assign current_inst_address_o = current_inst_address_i; + always @(*) begin if(rst == `RstEnable) diff --git a/src/vsrc/pipeline/3_execution/ex_mem.v b/src/vsrc/pipeline/3_execution/ex_mem.v index 48df26a..e6b000d 100644 --- a/src/vsrc/pipeline/3_execution/ex_mem.v +++ b/src/vsrc/pipeline/3_execution/ex_mem.v @@ -12,6 +12,9 @@ module ex_mem ( input wire[`AluOpBus] ex_aluop, input wire[`RegBus] ex_mem_addr, input wire[`RegBus] ex_reg2, + input wire flush, + input wire[1:0] ex_excepttype, + input wire[`RegBus] ex_curent_inst_address, output reg[`RegAddrBus] mem_wd, output reg mem_wreg, @@ -20,7 +23,9 @@ module ex_mem ( output reg[`InstAddrBus] mem_inst_pc, output reg[`AluOpBus] mem_aluop, output reg[`RegBus] mem_mem_addr, - output reg[`RegBus] mem_reg2 + output reg[`RegBus] mem_reg2, + output reg[1:0] mem_excepttype, + output reg[`RegBus] mem_current_inst_address ); always @ (posedge clk)begin @@ -33,6 +38,19 @@ always @ (posedge clk)begin mem_aluop <= `EXE_NOP_OP; mem_mem_addr <= `ZeroWord; mem_reg2 <= `ZeroWord; + mem_excepttype <= 2'b00; + mem_current_inst_address <= `ZeroWord; + end else if(flush == 1'b1)begin + mem_wd <= `NOPRegAddr; + mem_wreg <= `WriteDisable; + mem_wdata <= `ZeroWord; + mem_inst_pc <= `ZeroWord; + mem_inst_valid <= `InstInvalid; + mem_aluop <= `EXE_NOP_OP; + mem_mem_addr <= `ZeroWord; + mem_reg2 <= `ZeroWord; + mem_excepttype <= 2'b00; + mem_current_inst_address <= `ZeroWord; end else begin mem_wd <= ex_wd; mem_wreg <= ex_wreg; @@ -42,6 +60,8 @@ always @ (posedge clk)begin mem_aluop <= ex_aluop; mem_mem_addr <= ex_mem_addr; mem_reg2 <= ex_reg2; + mem_excepttype <= ex_excepttype; + mem_current_inst_address <= ex_curent_inst_address; end end diff --git a/src/vsrc/pipeline/4_mem/mem.v b/src/vsrc/pipeline/4_mem/mem.v index a06a9d6..13674ee 100644 --- a/src/vsrc/pipeline/4_mem/mem.v +++ b/src/vsrc/pipeline/4_mem/mem.v @@ -16,6 +16,9 @@ module mem ( input wire wb_LLbit_we_i, input wire wb_LLbit_value_i, + input wire[2:0] excepttype_i, + input wire[`RegBus] current_inst_address_i, + output reg[`RegAddrBus] wd_o, output reg wreg_o, output reg[`RegBus] wdata_o, @@ -27,13 +30,19 @@ module mem ( output reg mem_ce_o, output reg LLbit_we_o, - output reg LLbit_value_o + output reg LLbit_value_o, + + output wire[1:0] excepttype_o, + output wire[`RegBus] current_inst_address_o ); reg mem_we; reg LLbit; - assign mem_we_o = mem_we; + assign mem_we_o = mem_we & (~(|excepttype_i)); + + assign excepttype_o = excepttype_i; + assign current_inst_address_o = current_inst_address_i; always @(*) begin diff --git a/src/vsrc/pipeline/4_mem/mem_wb.v b/src/vsrc/pipeline/4_mem/mem_wb.v index cca4205..141e34f 100644 --- a/src/vsrc/pipeline/4_mem/mem_wb.v +++ b/src/vsrc/pipeline/4_mem/mem_wb.v @@ -14,6 +14,8 @@ module mem_wb ( input wire mem_LLbit_we, input wire mem_LLbit_value, + input wire flush, + output reg[`RegAddrBus] wb_wd, output reg wb_wreg, output reg[`RegBus] wb_wdata, @@ -43,7 +45,18 @@ module mem_wb ( debug_commit_pc <= `ZeroWord; debug_commit_valid <= `InstInvalid; end - else + else if(flush == 1'b1) + begin + wb_wd <= `NOPRegAddr; + wb_wreg <= `WriteDisable; + wb_wdata <= `ZeroWord; + wb_LLbit_we <= 1'b0; + wb_LLbit_value <= 1'b0; + debug_commit_instr <= `ZeroWord; + debug_commit_pc <= `ZeroWord; + debug_commit_valid <= `InstInvalid; + end + else begin wb_wd <= mem_wd; wb_wreg <= mem_wreg; From 1d6fdc615c3e5a329a8584783b2c4b09e0e97f5c Mon Sep 17 00:00:00 2001 From: Rookie <74707760+Rookie-Cai-niao@users.noreply.github.com> Date: Wed, 30 Mar 2022 10:33:12 +0800 Subject: [PATCH 002/114] add syscall,break(2) --- src/vsrc/ctrl.v | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vsrc/ctrl.v b/src/vsrc/ctrl.v index d9d7946..b0a4d83 100644 --- a/src/vsrc/ctrl.v +++ b/src/vsrc/ctrl.v @@ -44,9 +44,9 @@ module ctrl ( flush <= 1'b1; case (excepttype_i) 2'b01: - new_pc <= 32'h00000020; + new_pc <= 32'h0000000c; 2'b10: - new_pc <= 32'h00000040; + new_pc <= 32'h0000000c; default:begin end endcase From 8e2b3b1ac8a4a018a2b2d90882573af6cee6cb09 Mon Sep 17 00:00:00 2001 From: Rookie <74707760+Rookie-Cai-niao@users.noreply.github.com> Date: Wed, 30 Mar 2022 16:05:50 +0800 Subject: [PATCH 003/114] fix a little bug --- src/SimTop.v | 2 +- src/vsrc/pipeline/3_execution/ex_mem.v | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SimTop.v b/src/SimTop.v index 0d66e83..5e442d0 100644 --- a/src/SimTop.v +++ b/src/SimTop.v @@ -17,7 +17,7 @@ module SimTop( wire chip_enable; wire[`RegBus] ram_raddr; - reg[`RegBus] ram_rdata; + wire[`RegBus] ram_rdata; wire[`RegBus] ramhelper_rdata; wire[`RegBus] ram_waddr; wire[`RegBus] ram_wdata; diff --git a/src/vsrc/pipeline/3_execution/ex_mem.v b/src/vsrc/pipeline/3_execution/ex_mem.v index e6b000d..b65ca04 100644 --- a/src/vsrc/pipeline/3_execution/ex_mem.v +++ b/src/vsrc/pipeline/3_execution/ex_mem.v @@ -14,7 +14,7 @@ module ex_mem ( input wire[`RegBus] ex_reg2, input wire flush, input wire[1:0] ex_excepttype, - input wire[`RegBus] ex_curent_inst_address, + input wire[`RegBus] ex_current_inst_address, output reg[`RegAddrBus] mem_wd, output reg mem_wreg, @@ -61,7 +61,7 @@ always @ (posedge clk)begin mem_mem_addr <= ex_mem_addr; mem_reg2 <= ex_reg2; mem_excepttype <= ex_excepttype; - mem_current_inst_address <= ex_curent_inst_address; + mem_current_inst_address <= ex_current_inst_address; end end From e452d103648a0e0c2465ee62fda212200119c874 Mon Sep 17 00:00:00 2001 From: Rookie <74707760+Rookie-Cai-niao@users.noreply.github.com> Date: Fri, 1 Apr 2022 08:58:27 +0800 Subject: [PATCH 004/114] fix load bug --- src/SimTop.v | 4 ++-- src/vsrc/ctrl.v | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/SimTop.v b/src/SimTop.v index 5e442d0..52655a6 100644 --- a/src/SimTop.v +++ b/src/SimTop.v @@ -41,7 +41,7 @@ module SimTop( cpu_top u_cpu_top( .clk(clock), .rst(reset), - .dram_data_i(dram_data_i), + .dram_data_i(dram_data_o), .ram_rdata_i(ram_rdata), .ram_raddr_o(ram_raddr), @@ -51,7 +51,7 @@ module SimTop( .ram_en_o (chip_enable), .dram_addr_o(dram_addr), - .dram_data_o(dram_data_o), + .dram_data_o(dram_data_i), .dram_we_o(dram_we), .dram_sel_o(dram_sel), .dram_ce_o(dram_ce), diff --git a/src/vsrc/ctrl.v b/src/vsrc/ctrl.v index b0a4d83..39a47c4 100644 --- a/src/vsrc/ctrl.v +++ b/src/vsrc/ctrl.v @@ -51,6 +51,12 @@ module ctrl ( end endcase end + else if(stallreq_from_id == `Stop) + begin + branch_flush_cnt <= 1; + flush <= 1'b0; + new_pc <= `ZeroWord; + end else branch_flush_cnt <= branch_flush_cnt; From 7db5d8c7fdd89949db7b4d1083b560aab01492b0 Mon Sep 17 00:00:00 2001 From: Rookie <74707760+Rookie-Cai-niao@users.noreply.github.com> Date: Fri, 1 Apr 2022 14:50:59 +0800 Subject: [PATCH 005/114] add stop with bug --- src/vsrc/cpu_top.v | 19 +++++++++++++++---- src/vsrc/ctrl.v | 16 +++++++++++++++- src/vsrc/if_buffer.v | 8 +++++++- src/vsrc/pc_reg.v | 12 ++++++++---- src/vsrc/pipeline/1_fetch/if_id.v | 8 +++++++- src/vsrc/pipeline/2_decode/id.v | 2 +- src/vsrc/pipeline/2_decode/id_ex.v | 16 +++++++++++++++- src/vsrc/pipeline/3_execution/ex.v | 4 +++- src/vsrc/pipeline/3_execution/ex_mem.v | 14 +++++++++++++- src/vsrc/pipeline/4_mem/mem_wb.v | 14 +++++++++++++- 10 files changed, 97 insertions(+), 16 deletions(-) diff --git a/src/vsrc/cpu_top.v b/src/vsrc/cpu_top.v index f575e89..5b5f1ca 100644 --- a/src/vsrc/cpu_top.v +++ b/src/vsrc/cpu_top.v @@ -50,6 +50,7 @@ module cpu_top ( wire[`RegBus] link_addr; wire flush; wire[`RegBus] new_pc; + wire[5:0] stall; pc_reg u_pc_reg( .clk(clk), @@ -59,7 +60,8 @@ module cpu_top ( .branch_flag_i(branch_flag), .branch_target_address(branch_target_address), .flush(flush), - .new_pc(new_pc) + .new_pc(new_pc), + .stall(stall) ); wire [`InstAddrBus]pc2; @@ -71,7 +73,8 @@ module cpu_top ( .branch_flag_i(branch_flag), .pc_valid(if_inst_valid), .pc_o(pc2), - .flush(flush) + .flush(flush), + .stall(stall) ); @@ -88,7 +91,8 @@ module cpu_top ( .id_inst_o(id_inst), .if_inst_valid(if_inst_valid), .branch_flag_i(branch_flag), - .flush(flush) + .flush(flush), + .stall(stall) ); wire[`AluOpBus] id_aluop; @@ -118,6 +122,7 @@ module cpu_top ( wire[`RegBus] mem_reg_wdata_o; wire stallreq_from_id; + wire stallreq_from_ex; wire[1:0] id_excepttype_o; wire[`RegBus] id_current_inst_address_o; @@ -182,6 +187,7 @@ module cpu_top ( id_ex id_ex0( .clk(clk), .rst(rst), + .stall(stall), .id_aluop(id_aluop), .id_alusel(id_alusel), @@ -244,7 +250,9 @@ module cpu_top ( .mem_addr_o(ex_addr_o), .reg2_o(ex_reg2_o), .excepttype_o(ex_excepttype_o), - .current_inst_address_o(ex_current_inst_address_o) + .current_inst_address_o(ex_current_inst_address_o), + + .stallreq(stallreq_from_ex) ); @@ -264,6 +272,7 @@ module cpu_top ( ex_mem u_ex_mem( .clk(clk ), .rst(rst ), + .stall(stall), .ex_wd (ex_reg_waddr_o ), .ex_wreg (ex_wreg_o ), @@ -349,6 +358,7 @@ module cpu_top ( mem_wb mem_wb0( .clk(clk), .rst(rst), + .stall(stall), .mem_wd(mem_reg_waddr_o), .mem_wreg(mem_wreg_o), @@ -396,6 +406,7 @@ module cpu_top ( .rst (rst ), .id_is_branch_instr_i (branch_flag), .stallreq_from_id(stallreq_from_id), + .stallreq_from_ex(stallreq_from_ex), .excepttype_i(mem_excepttype_o), .new_pc(new_pc), .flush(flush), diff --git a/src/vsrc/ctrl.v b/src/vsrc/ctrl.v index 39a47c4..8e406d0 100644 --- a/src/vsrc/ctrl.v +++ b/src/vsrc/ctrl.v @@ -4,9 +4,11 @@ module ctrl ( input wire rst, input wire id_is_branch_instr_i, input wire stallreq_from_id, + input wire stallreq_from_ex, input wire[1:0] excepttype_i, + output reg[6:0]stall, output reg[`RegBus] new_pc, output reg flush, @@ -25,6 +27,7 @@ module ctrl ( branch_flush_cnt <= 2'b0; flush <= 1'b0; new_pc <= `ZeroWord; + stall <= 7'b0000000; end else if (!(branch_flush_cnt==0)) @@ -32,16 +35,19 @@ module ctrl ( branch_flush_cnt <= branch_flush_cnt -1; flush <= 1'b0; new_pc <= `ZeroWord; + stall <= 7'b0000000; end else if(id_is_branch_instr_i) begin branch_flush_cnt <= 1; flush <= 1'b0; new_pc <= `ZeroWord; + stall <= 7'b0000000; end else if(excepttype_i != 0) begin flush <= 1'b1; + stall <= 7'b0000000; case (excepttype_i) 2'b01: new_pc <= 32'h0000000c; @@ -53,9 +59,17 @@ module ctrl ( end else if(stallreq_from_id == `Stop) begin - branch_flush_cnt <= 1; + branch_flush_cnt <= 0; + flush <= 1'b0; + new_pc <= `ZeroWord; + stall <= 7'b0000111; + end + else if(stallreq_from_ex == `Stop) + begin + branch_flush_cnt <= 0; flush <= 1'b0; new_pc <= `ZeroWord; + stall <= 7'b0001111; end else branch_flush_cnt <= branch_flush_cnt; diff --git a/src/vsrc/if_buffer.v b/src/vsrc/if_buffer.v index b7c0256..e4f7cc8 100644 --- a/src/vsrc/if_buffer.v +++ b/src/vsrc/if_buffer.v @@ -5,6 +5,7 @@ module if_buffer ( input wire rst, input wire [`InstAddrBus] pc_i, input wire flush, + input wire[6:0] stall, input wire branch_flag_i, output reg [`InstAddrBus] pc_o, @@ -28,7 +29,12 @@ module if_buffer ( pc_o <= `ZeroWord; pc_valid <= `InstInvalid; end - else + else if(stall[1] == `Stop && stall[2] == `NoStop) + begin + pc_o <= `ZeroWord; + pc_valid <= `InstInvalid; + end + else if(stall[1] == `NoStop) begin pc_o <= pc_i; pc_valid <= `InstValid; diff --git a/src/vsrc/pc_reg.v b/src/vsrc/pc_reg.v index 4a24782..da7d3a0 100644 --- a/src/vsrc/pc_reg.v +++ b/src/vsrc/pc_reg.v @@ -2,6 +2,7 @@ module pc_reg ( input wire clk, input wire rst, + input wire[6:0] stall, input wire branch_flag_i, input wire[`RegBus] branch_target_address, @@ -19,10 +20,13 @@ module pc_reg ( pc <= 32'h1c000000; else if(flush == 1'b1) pc <= new_pc; - else if(branch_flag_i == `Branch) - pc <= branch_target_address; - else - pc <= pc + 32'h4; + else if(stall[0] == `NoStop) + begin + if(branch_flag_i == `Branch) + pc <= branch_target_address; + else + pc <= pc + 32'h4; + end end always @(posedge clk) diff --git a/src/vsrc/pipeline/1_fetch/if_id.v b/src/vsrc/pipeline/1_fetch/if_id.v index 94c1047..e9048f0 100644 --- a/src/vsrc/pipeline/1_fetch/if_id.v +++ b/src/vsrc/pipeline/1_fetch/if_id.v @@ -8,6 +8,7 @@ module if_id ( input wire[`InstAddrBus] if_inst_i, input wire if_inst_valid, input wire flush, + input wire[5:0] stall, output reg[`InstAddrBus] id_pc_o, output reg[`InstBus] id_inst_o ); @@ -30,7 +31,12 @@ module if_id ( id_pc_o <= `ZeroWord; id_inst_o <= `ZeroWord; end - else + else if(stall[2] == `Stop && stall[3] == `NoStop) + begin + id_inst_o <= `ZeroWord; + id_pc_o <= `ZeroWord; + end + else if(stall[2] == `NoStop) begin id_inst_o <= if_inst_i; id_pc_o <= if_pc_i; diff --git a/src/vsrc/pipeline/2_decode/id.v b/src/vsrc/pipeline/2_decode/id.v index eb3d618..2ffcfa6 100644 --- a/src/vsrc/pipeline/2_decode/id.v +++ b/src/vsrc/pipeline/2_decode/id.v @@ -46,7 +46,7 @@ module id( output reg[`RegBus] link_addr_o, // ->Ctrl - output stallreq + output wire stallreq ); wire[5:0] opcode_6 = inst_i[31:26]; diff --git a/src/vsrc/pipeline/2_decode/id_ex.v b/src/vsrc/pipeline/2_decode/id_ex.v index 69bb543..3309374 100644 --- a/src/vsrc/pipeline/2_decode/id_ex.v +++ b/src/vsrc/pipeline/2_decode/id_ex.v @@ -2,6 +2,7 @@ module id_ex ( input wire clk, input wire rst, + input wire[6:0] stall, input wire[`AluOpBus] id_aluop, input wire[`AluSelBus] id_alusel, @@ -58,7 +59,20 @@ always @(posedge clk) begin ex_inst <= `ZeroWord; ex_excepttype <= 2'b00; ex_current_inst_address <= `ZeroWord; - end else begin + end else if(stall[3] == `Stop && stall[4] == `NoStop)begin + ex_aluop <= `EXE_NOP_OP; + ex_alusel <= `EXE_RES_NOP; + ex_reg1 <= `ZeroWord; + ex_reg2 <= `ZeroWord; + ex_wd <= `NOPRegAddr; + ex_wreg <= `WriteDisable; + ex_inst_pc <= `ZeroWord; + ex_inst_valid <= `InstInvalid; + ex_link_address <= `ZeroWord; + ex_inst <= `ZeroWord; + ex_excepttype <= 2'b00; + ex_current_inst_address <= `ZeroWord; + end else if(stall[3] == `NoStop) begin ex_aluop <= id_aluop; ex_alusel <= id_alusel; ex_reg1 <= id_reg1; diff --git a/src/vsrc/pipeline/3_execution/ex.v b/src/vsrc/pipeline/3_execution/ex.v index 88db66e..3e54728 100644 --- a/src/vsrc/pipeline/3_execution/ex.v +++ b/src/vsrc/pipeline/3_execution/ex.v @@ -25,7 +25,9 @@ module ex ( output wire[`RegBus] mem_addr_o, output wire[`RegBus] reg2_o, output wire[1:0] excepttype_o, - output wire[`RegBus] current_inst_address_o + output wire[`RegBus] current_inst_address_o, + + output wire stallreq ); reg[`RegBus] logicout; diff --git a/src/vsrc/pipeline/3_execution/ex_mem.v b/src/vsrc/pipeline/3_execution/ex_mem.v index b65ca04..3bd28a9 100644 --- a/src/vsrc/pipeline/3_execution/ex_mem.v +++ b/src/vsrc/pipeline/3_execution/ex_mem.v @@ -3,6 +3,7 @@ module ex_mem ( input wire clk, input wire rst, + input wire[5:0] stall, input wire[`RegAddrBus] ex_wd, input wire ex_wreg, @@ -51,7 +52,18 @@ always @ (posedge clk)begin mem_reg2 <= `ZeroWord; mem_excepttype <= 2'b00; mem_current_inst_address <= `ZeroWord; - end else begin + end else if(stall[4] == `Stop &&stall[5] == `NoStop)begin + mem_wd <= `NOPRegAddr; + mem_wreg <= `WriteDisable; + mem_wdata <= `ZeroWord; + mem_inst_pc <= `ZeroWord; + mem_inst_valid <= `InstInvalid; + mem_aluop <= `EXE_NOP_OP; + mem_mem_addr <= `ZeroWord; + mem_reg2 <= `ZeroWord; + mem_excepttype <= 2'b00; + mem_current_inst_address <= `ZeroWord; + end else if(stall[4] == `NoStop) begin mem_wd <= ex_wd; mem_wreg <= ex_wreg; mem_wdata <= ex_wdata; diff --git a/src/vsrc/pipeline/4_mem/mem_wb.v b/src/vsrc/pipeline/4_mem/mem_wb.v index 141e34f..9364318 100644 --- a/src/vsrc/pipeline/4_mem/mem_wb.v +++ b/src/vsrc/pipeline/4_mem/mem_wb.v @@ -3,6 +3,7 @@ module mem_wb ( input wire clk, input wire rst, + input wire[5:0] stall, input wire[`RegAddrBus] mem_wd, input wire mem_wreg, @@ -56,7 +57,18 @@ module mem_wb ( debug_commit_pc <= `ZeroWord; debug_commit_valid <= `InstInvalid; end - else + else if(stall[5] == `Stop && stall[6] == `NoStop) + begin + wb_wd <= `NOPRegAddr; + wb_wreg <= `WriteDisable; + wb_wdata <= `ZeroWord; + wb_LLbit_we <= 1'b0; + wb_LLbit_value <= 1'b0; + debug_commit_instr <= `ZeroWord; + debug_commit_pc <= `ZeroWord; + debug_commit_valid <= `InstInvalid; + end + else if(stall[5] == `NoStop) begin wb_wd <= mem_wd; wb_wreg <= mem_wreg; From 13a348786f532ccba52d05dd9418567c58c820b8 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Fri, 1 Apr 2022 22:49:47 +0800 Subject: [PATCH 006/114] fix: fix data ram read - 1 cycle data ram read latency --- src/data_ram.v | 80 +++++++++--------- src/vsrc/cpu_top.v | 20 ++--- src/vsrc/ctrl.v | 50 ++++------- src/vsrc/if_buffer.v | 10 +-- src/vsrc/pc_reg.v | 12 ++- src/vsrc/pipeline/1_fetch/if_id.v | 10 +-- src/vsrc/pipeline/2_decode/id_ex.v | 111 ++++++++++++------------- src/vsrc/pipeline/3_execution/ex_mem.v | 98 +++++++++++----------- src/vsrc/pipeline/4_mem/mem_wb.v | 13 +-- 9 files changed, 190 insertions(+), 214 deletions(-) diff --git a/src/data_ram.v b/src/data_ram.v index d24f71f..f630872 100644 --- a/src/data_ram.v +++ b/src/data_ram.v @@ -1,45 +1,49 @@ `include "vsrc/defines.v" module data_ram( - input wire clk, - input wire ce, - input wire we, - input wire[`DataAddrBus] addr, - input wire[3:0] sel, - input wire[`DataBus] data_i, - output reg[`DataBus] data_o - -); + input wire clk, + input wire ce, + input wire we, + input wire[`DataAddrBus] addr, + input wire[3:0] sel, + input wire[`DataBus] data_i, + output reg[`DataBus] data_o -reg[`ByteWidth] data_mem0[0:`DataMemNum-1]; -reg[`ByteWidth] data_mem1[0:`DataMemNum-1]; -reg[`ByteWidth] data_mem2[0:`DataMemNum-1]; -reg[`ByteWidth] data_mem3[0:`DataMemNum-1]; + ); -always @ (posedge clk) begin - if (ce == `ChipDisable) begin - end else if(we == `WriteEnable) begin - if (sel[3] == 1'b1) - data_mem3[addr[`DataMemNumLog2+1:2]] <= data_i[31:24]; - if (sel[2] == 1'b1) - data_mem2[addr[`DataMemNumLog2+1:2]] <= data_i[23:16]; - if (sel[1] == 1'b1) - data_mem1[addr[`DataMemNumLog2+1:2]] <= data_i[15:8]; - if (sel[0] == 1'b1) - data_mem0[addr[`DataMemNumLog2+1:2]] <= data_i[7:0]; - end -end - - always @ (*) begin - if (ce == `ChipDisable) - data_o <= `ZeroWord; - else if(we == `WriteDisable) - data_o <= {data_mem3[addr[`DataMemNumLog2+1:2]], - data_mem2[addr[`DataMemNumLog2+1:2]], - data_mem1[addr[`DataMemNumLog2+1:2]], - data_mem0[addr[`DataMemNumLog2+1:2]]}; - else - data_o <= `ZeroWord; - end + reg[`ByteWidth] data_mem0[0:`DataMemNum-1]; + reg[`ByteWidth] data_mem1[0:`DataMemNum-1]; + reg[`ByteWidth] data_mem2[0:`DataMemNum-1]; + reg[`ByteWidth] data_mem3[0:`DataMemNum-1]; + + always @ (posedge clk) + begin + if (ce == `ChipDisable) + begin + end + else if(we == `WriteEnable) + begin + if (sel[3] == 1'b1) + data_mem3[addr[`DataMemNumLog2+1:2]] <= data_i[31:24]; + if (sel[2] == 1'b1) + data_mem2[addr[`DataMemNumLog2+1:2]] <= data_i[23:16]; + if (sel[1] == 1'b1) + data_mem1[addr[`DataMemNumLog2+1:2]] <= data_i[15:8]; + if (sel[0] == 1'b1) + data_mem0[addr[`DataMemNumLog2+1:2]] <= data_i[7:0]; + end + end + + always @ (posedge clk) + begin + if (ce == `ChipDisable) + data_o <= `ZeroWord; + else + data_o <= {data_mem3[addr[`DataMemNumLog2+1:2]], + data_mem2[addr[`DataMemNumLog2+1:2]], + data_mem1[addr[`DataMemNumLog2+1:2]], + data_mem0[addr[`DataMemNumLog2+1:2]]}; + + end endmodule diff --git a/src/vsrc/cpu_top.v b/src/vsrc/cpu_top.v index 5b5f1ca..7423729 100644 --- a/src/vsrc/cpu_top.v +++ b/src/vsrc/cpu_top.v @@ -50,7 +50,7 @@ module cpu_top ( wire[`RegBus] link_addr; wire flush; wire[`RegBus] new_pc; - wire[5:0] stall; + wire[6:0] stall; // [pc_reg,if_buffer_1, if_id, id_ex, ex_mem, mem_wb, ctrl] pc_reg u_pc_reg( .clk(clk), @@ -61,7 +61,7 @@ module cpu_top ( .branch_target_address(branch_target_address), .flush(flush), .new_pc(new_pc), - .stall(stall) + .stall(stall[0]) ); wire [`InstAddrBus]pc2; @@ -74,7 +74,7 @@ module cpu_top ( .pc_valid(if_inst_valid), .pc_o(pc2), .flush(flush), - .stall(stall) + .stall(stall[1]) ); @@ -92,7 +92,7 @@ module cpu_top ( .if_inst_valid(if_inst_valid), .branch_flag_i(branch_flag), .flush(flush), - .stall(stall) + .stall(stall[2]) ); wire[`AluOpBus] id_aluop; @@ -187,7 +187,7 @@ module cpu_top ( id_ex id_ex0( .clk(clk), .rst(rst), - .stall(stall), + .stall(stall[3]), .id_aluop(id_aluop), .id_alusel(id_alusel), @@ -272,7 +272,7 @@ module cpu_top ( ex_mem u_ex_mem( .clk(clk ), .rst(rst ), - .stall(stall), + .stall(stall[4]), .ex_wd (ex_reg_waddr_o ), .ex_wreg (ex_wreg_o ), @@ -358,7 +358,7 @@ module cpu_top ( mem_wb mem_wb0( .clk(clk), .rst(rst), - .stall(stall), + .stall(stall[5]), .mem_wd(mem_reg_waddr_o), .mem_wreg(mem_wreg_o), @@ -404,14 +404,12 @@ module cpu_top ( ctrl u_ctrl( .clk (clk ), .rst (rst ), - .id_is_branch_instr_i (branch_flag), + .stall(stall), .stallreq_from_id(stallreq_from_id), .stallreq_from_ex(stallreq_from_ex), .excepttype_i(mem_excepttype_o), .new_pc(new_pc), - .flush(flush), - .pc_instr_invalid_o (), - .if_id_instr_invalid_o () + .flush(flush) ); LLbit_reg u_LLbit_reg( diff --git a/src/vsrc/ctrl.v b/src/vsrc/ctrl.v index 8e406d0..12d6645 100644 --- a/src/vsrc/ctrl.v +++ b/src/vsrc/ctrl.v @@ -2,81 +2,61 @@ module ctrl ( input wire clk, input wire rst, - input wire id_is_branch_instr_i, input wire stallreq_from_id, input wire stallreq_from_ex, input wire[1:0] excepttype_i, - + output reg[6:0]stall, output reg[`RegBus] new_pc, - output reg flush, - - output wire pc_instr_invalid_o, - output wire if_id_instr_invalid_o - + output reg flush ); wire rst_n = ~rst; - reg [1:0] branch_flush_cnt; always @(posedge clk or negedge rst_n) begin if (!rst_n) begin - branch_flush_cnt <= 2'b0; flush <= 1'b0; new_pc <= `ZeroWord; stall <= 7'b0000000; end else - if (!(branch_flush_cnt==0)) - begin - branch_flush_cnt <= branch_flush_cnt -1; - flush <= 1'b0; - new_pc <= `ZeroWord; - stall <= 7'b0000000; - end - else if(id_is_branch_instr_i) - begin - branch_flush_cnt <= 1; - flush <= 1'b0; - new_pc <= `ZeroWord; - stall <= 7'b0000000; - end - else if(excepttype_i != 0) + if(excepttype_i != 0) begin flush <= 1'b1; stall <= 7'b0000000; case (excepttype_i) 2'b01: - new_pc <= 32'h0000000c; + new_pc <= 32'h0000000c; 2'b10: - new_pc <= 32'h0000000c; - default:begin - end + new_pc <= 32'h0000000c; + default: + begin + end endcase end else if(stallreq_from_id == `Stop) begin - branch_flush_cnt <= 0; flush <= 1'b0; new_pc <= `ZeroWord; - stall <= 7'b0000111; + stall <= 7'b0011111; end else if(stallreq_from_ex == `Stop) begin - branch_flush_cnt <= 0; flush <= 1'b0; new_pc <= `ZeroWord; - stall <= 7'b0001111; + stall <= 7'b0011111; end else - branch_flush_cnt <= branch_flush_cnt; + begin + flush <= 1'b0; + new_pc <= `ZeroWord; + stall <= 7'b0000000; + end end - assign pc_instr_invalid_o = id_is_branch_instr_i; - assign if_id_instr_invalid_o = id_is_branch_instr_i || (branch_flush_cnt == 1); endmodule //ctrl diff --git a/src/vsrc/if_buffer.v b/src/vsrc/if_buffer.v index e4f7cc8..29d70fc 100644 --- a/src/vsrc/if_buffer.v +++ b/src/vsrc/if_buffer.v @@ -5,7 +5,7 @@ module if_buffer ( input wire rst, input wire [`InstAddrBus] pc_i, input wire flush, - input wire[6:0] stall, + input wire stall, input wire branch_flag_i, output reg [`InstAddrBus] pc_o, @@ -29,12 +29,12 @@ module if_buffer ( pc_o <= `ZeroWord; pc_valid <= `InstInvalid; end - else if(stall[1] == `Stop && stall[2] == `NoStop) + else if(stall == `Stop) // Stall, hold output begin - pc_o <= `ZeroWord; - pc_valid <= `InstInvalid; + pc_o <= pc_o; + pc_valid <= pc_valid; end - else if(stall[1] == `NoStop) + else begin pc_o <= pc_i; pc_valid <= `InstValid; diff --git a/src/vsrc/pc_reg.v b/src/vsrc/pc_reg.v index da7d3a0..69df8a2 100644 --- a/src/vsrc/pc_reg.v +++ b/src/vsrc/pc_reg.v @@ -2,7 +2,7 @@ module pc_reg ( input wire clk, input wire rst, - input wire[6:0] stall, + input wire stall, input wire branch_flag_i, input wire[`RegBus] branch_target_address, @@ -20,12 +20,16 @@ module pc_reg ( pc <= 32'h1c000000; else if(flush == 1'b1) pc <= new_pc; - else if(stall[0] == `NoStop) + else if(stall == `Stop) // Hold output + begin + pc <= pc; + end + else begin if(branch_flag_i == `Branch) - pc <= branch_target_address; + pc <= branch_target_address; else - pc <= pc + 32'h4; + pc <= pc + 32'h4; end end diff --git a/src/vsrc/pipeline/1_fetch/if_id.v b/src/vsrc/pipeline/1_fetch/if_id.v index e9048f0..b538fc4 100644 --- a/src/vsrc/pipeline/1_fetch/if_id.v +++ b/src/vsrc/pipeline/1_fetch/if_id.v @@ -8,7 +8,7 @@ module if_id ( input wire[`InstAddrBus] if_inst_i, input wire if_inst_valid, input wire flush, - input wire[5:0] stall, + input wire stall, // current stage stall, hold output output reg[`InstAddrBus] id_pc_o, output reg[`InstBus] id_inst_o ); @@ -31,12 +31,12 @@ module if_id ( id_pc_o <= `ZeroWord; id_inst_o <= `ZeroWord; end - else if(stall[2] == `Stop && stall[3] == `NoStop) + else if(stall == `Stop) begin - id_inst_o <= `ZeroWord; - id_pc_o <= `ZeroWord; + id_inst_o <= id_inst_o; + id_pc_o <= id_pc_o; end - else if(stall[2] == `NoStop) + else begin id_inst_o <= if_inst_i; id_pc_o <= if_pc_i; diff --git a/src/vsrc/pipeline/2_decode/id_ex.v b/src/vsrc/pipeline/2_decode/id_ex.v index 3309374..e6bd840 100644 --- a/src/vsrc/pipeline/2_decode/id_ex.v +++ b/src/vsrc/pipeline/2_decode/id_ex.v @@ -2,7 +2,7 @@ module id_ex ( input wire clk, input wire rst, - input wire[6:0] stall, + input wire stall, input wire[`AluOpBus] id_aluop, input wire[`AluSelBus] id_alusel, @@ -30,62 +30,59 @@ module id_ex ( output reg[`RegBus] ex_inst, output reg[1:0]ex_excepttype, output reg[`RegBus] ex_current_inst_address -); + ); -always @(posedge clk) begin - if(rst == `RstEnable)begin - ex_aluop <= `EXE_NOP_OP; - ex_alusel <= `EXE_RES_NOP; - ex_reg1 <= `ZeroWord; - ex_reg2 <= `ZeroWord; - ex_wd <= `NOPRegAddr; - ex_wreg <= `WriteDisable; - ex_inst_pc <= `ZeroWord; - ex_inst_valid <= `InstInvalid; - ex_link_address <= `ZeroWord; - ex_inst <= `ZeroWord; - ex_excepttype <= 2'b00; - ex_current_inst_address <= `ZeroWord; - end else if(flush == 1'b1)begin - ex_aluop <= `EXE_NOP_OP; - ex_alusel <= `EXE_RES_NOP; - ex_reg1 <= `ZeroWord; - ex_reg2 <= `ZeroWord; - ex_wd <= `NOPRegAddr; - ex_wreg <= `WriteDisable; - ex_inst_pc <= `ZeroWord; - ex_inst_valid <= `InstInvalid; - ex_link_address <= `ZeroWord; - ex_inst <= `ZeroWord; - ex_excepttype <= 2'b00; - ex_current_inst_address <= `ZeroWord; - end else if(stall[3] == `Stop && stall[4] == `NoStop)begin - ex_aluop <= `EXE_NOP_OP; - ex_alusel <= `EXE_RES_NOP; - ex_reg1 <= `ZeroWord; - ex_reg2 <= `ZeroWord; - ex_wd <= `NOPRegAddr; - ex_wreg <= `WriteDisable; - ex_inst_pc <= `ZeroWord; - ex_inst_valid <= `InstInvalid; - ex_link_address <= `ZeroWord; - ex_inst <= `ZeroWord; - ex_excepttype <= 2'b00; - ex_current_inst_address <= `ZeroWord; - end else if(stall[3] == `NoStop) begin - ex_aluop <= id_aluop; - ex_alusel <= id_alusel; - ex_reg1 <= id_reg1; - ex_reg2 <= id_reg2; - ex_wd <= id_wd; - ex_wreg <= id_wreg; - ex_inst_pc <= id_inst_pc; - ex_inst_valid <= id_inst_valid; - ex_link_address <= id_link_address; - ex_inst <= id_inst; - ex_excepttype <= id_excepttype; - ex_current_inst_address <= id_current_inst_address; + always @(posedge clk) + begin + if(rst == `RstEnable) + begin + ex_aluop <= `EXE_NOP_OP; + ex_alusel <= `EXE_RES_NOP; + ex_reg1 <= `ZeroWord; + ex_reg2 <= `ZeroWord; + ex_wd <= `NOPRegAddr; + ex_wreg <= `WriteDisable; + ex_inst_pc <= `ZeroWord; + ex_inst_valid <= `InstInvalid; + ex_link_address <= `ZeroWord; + ex_inst <= `ZeroWord; + ex_excepttype <= 2'b00; + ex_current_inst_address <= `ZeroWord; + end + else if(flush == 1'b1) + begin + ex_aluop <= `EXE_NOP_OP; + ex_alusel <= `EXE_RES_NOP; + ex_reg1 <= `ZeroWord; + ex_reg2 <= `ZeroWord; + ex_wd <= `NOPRegAddr; + ex_wreg <= `WriteDisable; + ex_inst_pc <= `ZeroWord; + ex_inst_valid <= `InstInvalid; + ex_link_address <= `ZeroWord; + ex_inst <= `ZeroWord; + ex_excepttype <= 2'b00; + ex_current_inst_address <= `ZeroWord; + end + else if(stall == `Stop) + begin + + end + else + begin + ex_aluop <= id_aluop; + ex_alusel <= id_alusel; + ex_reg1 <= id_reg1; + ex_reg2 <= id_reg2; + ex_wd <= id_wd; + ex_wreg <= id_wreg; + ex_inst_pc <= id_inst_pc; + ex_inst_valid <= id_inst_valid; + ex_link_address <= id_link_address; + ex_inst <= id_inst; + ex_excepttype <= id_excepttype; + ex_current_inst_address <= id_current_inst_address; + end end -end -endmodule \ No newline at end of file +endmodule diff --git a/src/vsrc/pipeline/3_execution/ex_mem.v b/src/vsrc/pipeline/3_execution/ex_mem.v index 3bd28a9..dc6f2ae 100644 --- a/src/vsrc/pipeline/3_execution/ex_mem.v +++ b/src/vsrc/pipeline/3_execution/ex_mem.v @@ -3,7 +3,7 @@ module ex_mem ( input wire clk, input wire rst, - input wire[5:0] stall, + input wire stall, input wire[`RegAddrBus] ex_wd, input wire ex_wreg, @@ -27,54 +27,52 @@ module ex_mem ( output reg[`RegBus] mem_reg2, output reg[1:0] mem_excepttype, output reg[`RegBus] mem_current_inst_address -); + ); -always @ (posedge clk)begin - if (rst == `RstEnable)begin - mem_wd <= `NOPRegAddr; - mem_wreg <= `WriteDisable; - mem_wdata <= `ZeroWord; - mem_inst_pc <= `ZeroWord; - mem_inst_valid <= `InstInvalid; - mem_aluop <= `EXE_NOP_OP; - mem_mem_addr <= `ZeroWord; - mem_reg2 <= `ZeroWord; - mem_excepttype <= 2'b00; - mem_current_inst_address <= `ZeroWord; - end else if(flush == 1'b1)begin - mem_wd <= `NOPRegAddr; - mem_wreg <= `WriteDisable; - mem_wdata <= `ZeroWord; - mem_inst_pc <= `ZeroWord; - mem_inst_valid <= `InstInvalid; - mem_aluop <= `EXE_NOP_OP; - mem_mem_addr <= `ZeroWord; - mem_reg2 <= `ZeroWord; - mem_excepttype <= 2'b00; - mem_current_inst_address <= `ZeroWord; - end else if(stall[4] == `Stop &&stall[5] == `NoStop)begin - mem_wd <= `NOPRegAddr; - mem_wreg <= `WriteDisable; - mem_wdata <= `ZeroWord; - mem_inst_pc <= `ZeroWord; - mem_inst_valid <= `InstInvalid; - mem_aluop <= `EXE_NOP_OP; - mem_mem_addr <= `ZeroWord; - mem_reg2 <= `ZeroWord; - mem_excepttype <= 2'b00; - mem_current_inst_address <= `ZeroWord; - end else if(stall[4] == `NoStop) begin - mem_wd <= ex_wd; - mem_wreg <= ex_wreg; - mem_wdata <= ex_wdata; - mem_inst_pc <= ex_inst_pc; - mem_inst_valid <= ex_inst_valid; - mem_aluop <= ex_aluop; - mem_mem_addr <= ex_mem_addr; - mem_reg2 <= ex_reg2; - mem_excepttype <= ex_excepttype; - mem_current_inst_address <= ex_current_inst_address; + always @ (posedge clk) + begin + if (rst == `RstEnable) + begin + mem_wd <= `NOPRegAddr; + mem_wreg <= `WriteDisable; + mem_wdata <= `ZeroWord; + mem_inst_pc <= `ZeroWord; + mem_inst_valid <= `InstInvalid; + mem_aluop <= `EXE_NOP_OP; + mem_mem_addr <= `ZeroWord; + mem_reg2 <= `ZeroWord; + mem_excepttype <= 2'b00; + mem_current_inst_address <= `ZeroWord; + end + else if(flush == 1'b1) + begin + mem_wd <= `NOPRegAddr; + mem_wreg <= `WriteDisable; + mem_wdata <= `ZeroWord; + mem_inst_pc <= `ZeroWord; + mem_inst_valid <= `InstInvalid; + mem_aluop <= `EXE_NOP_OP; + mem_mem_addr <= `ZeroWord; + mem_reg2 <= `ZeroWord; + mem_excepttype <= 2'b00; + mem_current_inst_address <= `ZeroWord; + end + else if(stall == `Stop) + begin + end + else + begin + mem_wd <= ex_wd; + mem_wreg <= ex_wreg; + mem_wdata <= ex_wdata; + mem_inst_pc <= ex_inst_pc; + mem_inst_valid <= ex_inst_valid; + mem_aluop <= ex_aluop; + mem_mem_addr <= ex_mem_addr; + mem_reg2 <= ex_reg2; + mem_excepttype <= ex_excepttype; + mem_current_inst_address <= ex_current_inst_address; + end end -end - -endmodule \ No newline at end of file + +endmodule diff --git a/src/vsrc/pipeline/4_mem/mem_wb.v b/src/vsrc/pipeline/4_mem/mem_wb.v index 9364318..14a29dd 100644 --- a/src/vsrc/pipeline/4_mem/mem_wb.v +++ b/src/vsrc/pipeline/4_mem/mem_wb.v @@ -3,7 +3,7 @@ module mem_wb ( input wire clk, input wire rst, - input wire[5:0] stall, + input wire stall, input wire[`RegAddrBus] mem_wd, input wire mem_wreg, @@ -57,18 +57,13 @@ module mem_wb ( debug_commit_pc <= `ZeroWord; debug_commit_valid <= `InstInvalid; end - else if(stall[5] == `Stop && stall[6] == `NoStop) + else if(stall == `Stop) begin - wb_wd <= `NOPRegAddr; - wb_wreg <= `WriteDisable; - wb_wdata <= `ZeroWord; - wb_LLbit_we <= 1'b0; - wb_LLbit_value <= 1'b0; - debug_commit_instr <= `ZeroWord; debug_commit_pc <= `ZeroWord; + debug_commit_instr <= `ZeroWord; debug_commit_valid <= `InstInvalid; end - else if(stall[5] == `NoStop) + else begin wb_wd <= mem_wd; wb_wreg <= mem_wreg; From f2b119b088310f143c4ebbec3be509cca0ad7901 Mon Sep 17 00:00:00 2001 From: Rookie <74707760+Rookie-Cai-niao@users.noreply.github.com> Date: Sun, 3 Apr 2022 15:24:16 +0800 Subject: [PATCH 007/114] dual-issue without data relation --- src/SimTop.v | 204 +++++++---- src/data_ram.v | 82 +++-- src/ram.v | 27 +- src/vsrc/cpu_top.v | 870 +++++++++++++++++++++++++++++++-------------- src/vsrc/ctrl.v | 47 ++- src/vsrc/pc_reg.v | 37 +- src/vsrc/regfile.v | 96 +++-- 7 files changed, 954 insertions(+), 409 deletions(-) diff --git a/src/SimTop.v b/src/SimTop.v index 52655a6..5408cc9 100644 --- a/src/SimTop.v +++ b/src/SimTop.v @@ -16,52 +16,83 @@ module SimTop( ); wire chip_enable; - wire[`RegBus] ram_raddr; - wire[`RegBus] ram_rdata; + wire[`RegBus] ram_raddr_1; + wire[`RegBus] ram_raddr_2; + wire[`RegBus] ram_rdata_1; + wire[`RegBus] ram_rdata_2; wire[`RegBus] ramhelper_rdata; wire[`RegBus] ram_waddr; wire[`RegBus] ram_wdata; wire ram_wen; - wire dram_ce; - wire dram_we; - wire[`DataAddrBus] dram_addr; - wire[3:0] dram_sel; - wire[`DataBus] dram_data_i; - wire[`DataBus] dram_data_o; - - wire [`RegBus] debug_commit_pc; - wire debug_commit_valid; - wire[`InstBus] debug_commit_instr; - wire debug_commit_wreg; - wire [`RegAddrBus] debug_commit_reg_waddr; - wire [`RegBus] debug_commit_reg_wdata; + wire dram_ce_1; + wire dram_we_1; + wire[`DataAddrBus] dram_addr_1; + wire[3:0] dram_sel_1; + wire[`DataBus] dram_data_i_1; + wire[`DataBus] dram_data_o_1; + + wire dram_ce_2; + wire dram_we_2; + wire[`DataAddrBus] dram_addr_2; + wire[3:0] dram_sel_2; + wire[`DataBus] dram_data_i_2; + wire[`DataBus] dram_data_o_2; + + wire [`RegBus] debug_commit_pc_o_1; + wire debug_commit_valid_o_1; + wire[`InstBus] debug_commit_instr_o_1; + wire debug_commit_wreg_o_1; + wire [`RegAddrBus] debug_commit_reg_waddr_o_1; + wire [`RegBus] debug_commit_reg_wdata_o_1; + wire [`RegBus] debug_commit_pc_o_2; + wire debug_commit_valid_o_2; + wire[`InstBus] debug_commit_instr_o_2; + wire debug_commit_wreg_o_2; + wire [`RegAddrBus] debug_commit_reg_waddr_o_2; + wire [`RegBus] debug_commit_reg_wdata_o_2; wire[1023:0] debug_reg; wire Instram_branch_flag; cpu_top u_cpu_top( .clk(clock), .rst(reset), - .dram_data_i(dram_data_o), - .ram_rdata_i(ram_rdata), - .ram_raddr_o(ram_raddr), + .dram_data_i_1(dram_data_o_1), + .dram_data_i_2(dram_data_o_2), + .ram_rdata_i_1(ram_rdata_1), + .ram_rdata_i_2(ram_rdata_2), + + .ram_raddr_o_1(ram_raddr_1), + .ram_raddr_o_2(ram_raddr_2), .ram_wdata_o(ram_wdata), .ram_waddr_o(ram_waddr), .ram_wen_o (ram_wen), .ram_en_o (chip_enable), - .dram_addr_o(dram_addr), - .dram_data_o(dram_data_i), - .dram_we_o(dram_we), - .dram_sel_o(dram_sel), - .dram_ce_o(dram_ce), - - .debug_commit_pc(debug_commit_pc ), - .debug_commit_valid(debug_commit_valid ), - .debug_commit_instr(debug_commit_instr ), - .debug_commit_wreg(debug_commit_wreg ), - .debug_commit_reg_waddr(debug_commit_reg_waddr ), - .debug_commit_reg_wdata(debug_commit_reg_wdata ), + .dram_addr_o_1(dram_addr_1), + .dram_data_o_1(dram_data_i_1), + .dram_we_o_1(dram_we_1), + .dram_sel_o_1(dram_sel_1), + .dram_ce_o_1(dram_ce_1), + + .dram_addr_o_2(dram_addr_2), + .dram_data_o_2(dram_data_i_2), + .dram_we_o_2(dram_we_2), + .dram_sel_o_2(dram_sel_2), + .dram_ce_o_2(dram_ce_2), + + .debug_commit_pc_1(debug_commit_pc_o_1 ), + .debug_commit_valid_1(debug_commit_valid_o_1 ), + .debug_commit_instr_1(debug_commit_instr_o_1 ), + .debug_commit_wreg_1(debug_commit_wreg_o_1 ), + .debug_commit_reg_waddr_1(debug_commit_reg_waddr_o_1 ), + .debug_commit_reg_wdata_1(debug_commit_reg_wdata_o_1 ), + .debug_commit_pc_2(debug_commit_pc_o_2 ), + .debug_commit_valid_2(debug_commit_valid_o_2 ), + .debug_commit_instr_2(debug_commit_instr_o_2 ), + .debug_commit_wreg_2(debug_commit_wreg_o_2 ), + .debug_commit_reg_waddr_2(debug_commit_reg_waddr_o_2 ), + .debug_commit_reg_wdata_2(debug_commit_reg_wdata_o_2 ), .debug_reg(debug_reg ), .Instram_branch_flag(Instram_branch_flag) ); @@ -82,8 +113,10 @@ module SimTop( .clock (clock ), .reset (reset ), .ce (chip_enable), - .raddr (ram_raddr ), - .rdata (ram_rdata ), + .raddr_1 (ram_raddr_1 ), + .rdata_1 (ram_rdata_1 ), + .raddr_2 (ram_raddr_2 ), + .rdata_2 (ram_rdata_2 ), .waddr (ram_waddr ), .wdata (ram_wdata ), .wen (ram_wen ), @@ -94,12 +127,18 @@ module SimTop( data_ram u_data_ram( .clk(clock), - .ce(dram_ce), - .we(dram_we), - .addr(dram_addr), - .sel(dram_sel), - .data_i(dram_data_i), - .data_o(dram_data_o) + .ce_1(dram_ce_1), + .we_1(dram_we_1), + .addr_1(dram_addr_1), + .sel_1(dram_sel_1), + .data_i_1(dram_data_i_1), + .data_o_1(dram_data_o_1), + .ce_2(dram_ce_2), + .we_2(dram_we_2), + .addr_2(dram_addr_2), + .sel_2(dram_sel_2), + .data_i_2(dram_data_i_2), + .data_o_2(dram_data_o_2) ); @@ -116,12 +155,20 @@ module SimTop( reg [63:0] cycleCnt; reg [63:0] instrCnt; - reg [`RegBus] debug_commit_pc_1; - reg debug_commit_valid_1; - reg [`InstBus] debug_commit_instr_1; - reg debug_commit_wreg_1; - reg [`RegAddrBus] debug_commit_reg_waddr_1; - reg [`RegBus] debug_commit_reg_wdata_1; + + reg [`RegBus] debug_commit_pc_i_1; + reg debug_commit_valid_i_1; + reg [`InstBus] debug_commit_instr_i_1; + reg debug_commit_wreg_i_1; + reg [`RegAddrBus] debug_commit_reg_waddr_i_1; + reg [`RegBus] debug_commit_reg_wdata_i_1; + + reg [`RegBus] debug_commit_pc_i_2; + reg debug_commit_valid_i_2; + reg [`InstBus] debug_commit_instr_i_2; + reg debug_commit_wreg_i_2; + reg [`RegAddrBus] debug_commit_reg_waddr_i_2; + reg [`RegBus] debug_commit_reg_wdata_i_2; always @(posedge clock or negedge reset_n) begin @@ -129,23 +176,35 @@ module SimTop( begin cycleCnt <= 0; instrCnt <= 0; - debug_commit_instr_1 <= 0; - debug_commit_valid_1 <= 0; - debug_commit_pc_1 <= 0; - debug_commit_wreg_1 <= 0; - debug_commit_reg_waddr_1 <= 0; - debug_commit_reg_wdata_1 <= 0; + debug_commit_instr_i_1 <= 0; + debug_commit_valid_i_1 <= 0; + debug_commit_pc_i_1 <= 0; + debug_commit_wreg_i_1 <= 0; + debug_commit_reg_waddr_i_1 <= 0; + debug_commit_reg_wdata_i_1 <= 0; + debug_commit_instr_i_2 <= 0; + debug_commit_valid_i_2 <= 0; + debug_commit_pc_i_2 <= 0; + debug_commit_wreg_i_2 <= 0; + debug_commit_reg_waddr_i_2 <= 0; + debug_commit_reg_wdata_i_2 <= 0; end else begin cycleCnt <= cycleCnt + 1; - instrCnt <= instrCnt + debug_commit_valid_1; - debug_commit_instr_1 <= debug_commit_instr; - debug_commit_valid_1 <= debug_commit_valid & chip_enable; - debug_commit_pc_1 <= debug_commit_pc; - debug_commit_wreg_1 <= debug_commit_wreg; - debug_commit_reg_waddr_1 <= debug_commit_reg_waddr; - debug_commit_reg_wdata_1 <= debug_commit_reg_wdata; + instrCnt <= instrCnt + debug_commit_valid__i1 + debug_commit_valid_i_2; + debug_commit_instr_i_1 <= debug_commit_instr_o_1; + debug_commit_valid_i_1 <= debug_commit_valid_o_1 & chip_enable; + debug_commit_pc_i_1 <= debug_commit_pc_o_1; + debug_commit_wreg_i_1 <= debug_commit_wreg_o_1; + debug_commit_reg_waddr_i_1 <= debug_commit_reg_waddr_o_1; + debug_commit_reg_wdata_i_1 <= debug_commit_reg_wdata_o_1; + debug_commit_instr_i_2 <= debug_commit_instr_o_2; + debug_commit_valid_i_2 <= debug_commit_valid_o_2 & chip_enable; + debug_commit_pc_i_2 <= debug_commit_pc_o_2; + debug_commit_wreg_i_2 <= debug_commit_wreg_o_2; + debug_commit_reg_waddr_i_2 <= debug_commit_reg_waddr_o_2; + debug_commit_reg_wdata_i_2 <= debug_commit_reg_wdata_o_2; ram_rdata <= ramhelper_rdata; end end @@ -171,21 +230,38 @@ module SimTop( .wen() ); - DifftestInstrCommit difftest_instr_commit( + DifftestInstrCommit difftest_instr_commit_1( + .clock(clock), + .coreid(coreid), + .index(index), + .valid(debug_commit_valid_i_1), // Non-zero means valid, checked per-cycle, if valid, instr count as as commit + .pc(debug_commit_pc_i_1), + .instr(debug_commit_instr_i_1), + .skip(), + .is_TLBFILL(), + .TLBFILL_index(), + .is_CNTinst(), + .timer_64_value(), + .wen(debug_commit_wreg_i_1), + .wdest(debug_commit_reg_waddr_i_1), + .wdata(debug_commit_reg_wdata_i_1) + ); + + DifftestInstrCommit difftest_instr_commit_2( .clock(clock), .coreid(coreid), .index(index), - .valid(debug_commit_valid_1), // Non-zero means valid, checked per-cycle, if valid, instr count as as commit - .pc(debug_commit_pc), - .instr(debug_commit_instr_1), + .valid(debug_commit_valid_i_2), // Non-zero means valid, checked per-cycle, if valid, instr count as as commit + .pc(debug_commit_pc_i_2), + .instr(debug_commit_instr_i_2), .skip(), .is_TLBFILL(), .TLBFILL_index(), .is_CNTinst(), .timer_64_value(), - .wen(debug_commit_wreg_1), - .wdest(debug_commit_reg_waddr_1), - .wdata(debug_commit_reg_wdata_1) + .wen(debug_commit_wreg_i_2), + .wdest(debug_commit_reg_waddr_i_2), + .wdata(debug_commit_reg_wdata_i_2) ); DifftestArchIntRegState difftest_arch_int_reg_state( diff --git a/src/data_ram.v b/src/data_ram.v index f630872..8c8ff8b 100644 --- a/src/data_ram.v +++ b/src/data_ram.v @@ -2,12 +2,20 @@ module data_ram( input wire clk, - input wire ce, - input wire we, - input wire[`DataAddrBus] addr, - input wire[3:0] sel, - input wire[`DataBus] data_i, - output reg[`DataBus] data_o + + input wire ce_1, + input wire we_1, + input wire[`DataAddrBus] addr_1, + input wire[3:0] sel_1, + input wire[`DataBus] data_i_1, + output reg[`DataBus] data_o_1, + + input wire ce_2, + input wire we_2, + input wire[`DataAddrBus] addr_2, + input wire[3:0] sel_2, + input wire[`DataBus] data_i_2, + output reg[`DataBus] data_o_2 ); @@ -18,31 +26,61 @@ module data_ram( always @ (posedge clk) begin - if (ce == `ChipDisable) + if (ce_1 == `ChipDisable) + begin + end + else if(we_1 == `WriteEnable) + begin + if (sel_1[3] == 1'b1) + data_mem3[addr_1[`DataMemNumLog2+1:2]] <= data_i_1[31:24]; + if (sel_1[2] == 1'b1) + data_mem2[addr_1[`DataMemNumLog2+1:2]] <= data_i_1[23:16]; + if (sel_1[1] == 1'b1) + data_mem1[addr_1[`DataMemNumLog2+1:2]] <= data_i_1[15:8]; + if (sel_1[0] == 1'b1) + data_mem0[addr_1[`DataMemNumLog2+1:2]] <= data_i_1[7:0]; + end + end + + always @ (posedge clk) + begin + if (ce_1 == `ChipDisable) + data_o_1 <= `ZeroWord; + else + data_o_1 <= {data_mem3[addr_1[`DataMemNumLog2+1:2]], + data_mem2[addr_1[`DataMemNumLog2+1:2]], + data_mem1[addr_1[`DataMemNumLog2+1:2]], + data_mem0[addr_1[`DataMemNumLog2+1:2]]}; + + end + + always @ (posedge clk) + begin + if (ce_2 == `ChipDisable) begin end - else if(we == `WriteEnable) + else if(we_2 == `WriteEnable) begin - if (sel[3] == 1'b1) - data_mem3[addr[`DataMemNumLog2+1:2]] <= data_i[31:24]; - if (sel[2] == 1'b1) - data_mem2[addr[`DataMemNumLog2+1:2]] <= data_i[23:16]; - if (sel[1] == 1'b1) - data_mem1[addr[`DataMemNumLog2+1:2]] <= data_i[15:8]; - if (sel[0] == 1'b1) - data_mem0[addr[`DataMemNumLog2+1:2]] <= data_i[7:0]; + if (sel_2[3] == 1'b1) + data_mem3[addr_2[`DataMemNumLog2+1:2]] <= data_i_2[31:24]; + if (sel_2[2] == 1'b1) + data_mem2[addr_2[`DataMemNumLog2+1:2]] <= data_i_2[23:16]; + if (sel_2[1] == 1'b1) + data_mem1[addr_2[`DataMemNumLog2+1:2]] <= data_i_2[15:8]; + if (sel_2[0] == 1'b1) + data_mem0[addr_2[`DataMemNumLog2+1:2]] <= data_i_2[7:0]; end end always @ (posedge clk) begin - if (ce == `ChipDisable) - data_o <= `ZeroWord; + if (ce_2 == `ChipDisable) + data_o_2 <= `ZeroWord; else - data_o <= {data_mem3[addr[`DataMemNumLog2+1:2]], - data_mem2[addr[`DataMemNumLog2+1:2]], - data_mem1[addr[`DataMemNumLog2+1:2]], - data_mem0[addr[`DataMemNumLog2+1:2]]}; + data_o_2 <= {data_mem3[addr_2[`DataMemNumLog2+1:2]], + data_mem2[addr_2[`DataMemNumLog2+1:2]], + data_mem1[addr_2[`DataMemNumLog2+1:2]], + data_mem0[addr_2[`DataMemNumLog2+1:2]]}; end diff --git a/src/ram.v b/src/ram.v index dd33d0b..06378f5 100644 --- a/src/ram.v +++ b/src/ram.v @@ -5,8 +5,10 @@ module ram ( input reset, input wire branch_flag_i, input wire ce, - input wire[`InstAddrBus] raddr, - output reg[`InstBus] rdata, + input wire[`InstAddrBus] raddr_1, + input wire[`InstAddrBus] raddr_2, + output reg[`InstBus] rdata_1, + output reg[`InstBus] rdata_2, input wire[`RegBus] waddr, input wire[`RegBus] wdata, input wire wen @@ -14,8 +16,10 @@ module ram ( reg[`InstBus] mem[0:`InstMemNum-1]; - wire [`InstAddrBus] tmp_addr; - assign tmp_addr = raddr - 32'h1c000000; + wire [`InstAddrBus] tmp_addr_1; + wire [`InstAddrBus] tmp_addr_2; + assign tmp_addr_1 = raddr_1 - 32'h1c000000; + assign tmp_addr_2 = raddr_2 - 32'h1c000000; initial $readmemh ("D:/cpu-test/latest/mycpu/la_code/inst_rom.data", mem); @@ -23,10 +27,19 @@ module ram ( always @ (posedge clock) begin if (ce == `ChipDisable) - rdata <= `ZeroWord; - else if(branch_flag_i) rdata<=`ZeroWord; + rdata_1 <= `ZeroWord; + else if(branch_flag_i) rdata_1<=`ZeroWord; else - rdata <= mem[tmp_addr[`InstMemNumLog2+1:2]]; + rdata_1 <= mem[tmp_addr_1[`InstMemNumLog2+1:2]]; + end + + always @ (posedge clock) + begin + if (ce == `ChipDisable) + rdata_2 <= `ZeroWord; + else if(branch_flag_i) rdata_2<=`ZeroWord; + else + rdata_2 <= mem[tmp_addr_2[`InstMemNumLog2+1:2]]; end endmodule diff --git a/src/vsrc/cpu_top.v b/src/vsrc/cpu_top.v index 7423729..0ea9842 100644 --- a/src/vsrc/cpu_top.v +++ b/src/vsrc/cpu_top.v @@ -13,36 +13,54 @@ module cpu_top ( input wire clk, input wire rst, - input wire[`RegBus] dram_data_i, - input wire[`RegBus] ram_rdata_i, - output wire[`RegBus] ram_raddr_o, + input wire[`RegBus] dram_data_i_1, + input wire[`RegBus] dram_data_i_2, + input wire[`RegBus] ram_rdata_i_1, + input wire[`RegBus] ram_rdata_i_2, + + output wire[`RegBus] ram_raddr_o_1, + output wire[`RegBus] ram_raddr_o_2, output wire[`RegBus] ram_wdata_o, output wire[`RegBus] ram_waddr_o, output wire ram_wen_o, output wire ram_en_o, - output wire[`RegBus] dram_addr_o, - output wire[`RegBus] dram_data_o, - output wire dram_we_o, - output wire[3:0] dram_sel_o, - output wire dram_ce_o, - - output wire[`RegBus] debug_commit_pc, - output wire debug_commit_valid, - output wire[`InstBus] debug_commit_instr, - output wire debug_commit_wreg, - output wire[`RegAddrBus] debug_commit_reg_waddr, - output wire[`RegBus] debug_commit_reg_wdata, + output wire[`RegBus] dram_addr_o_1, + output wire[`RegBus] dram_data_o_1, + output wire dram_we_o_1, + output wire[3:0] dram_sel_o_1, + output wire dram_ce_o_1, + + output wire[`RegBus] dram_addr_o_2, + output wire[`RegBus] dram_data_o_2, + output wire dram_we_o_2, + output wire[3:0] dram_sel_o_2, + output wire dram_ce_o_2, + + output wire[`RegBus] debug_commit_pc_1, + output wire debug_commit_valid_1, + output wire[`InstBus] debug_commit_instr_1, + output wire debug_commit_wreg_1, + output wire[`RegAddrBus] debug_commit_reg_waddr_1, + output wire[`RegBus] debug_commit_reg_wdata_1, + output wire[`RegBus] debug_commit_pc_2, + output wire debug_commit_valid_2, + output wire[`InstBus] debug_commit_instr_2, + output wire debug_commit_wreg_2, + output wire[`RegAddrBus] debug_commit_reg_waddr_2, + output wire[`RegBus] debug_commit_reg_wdata_2, output wire[1023:0] debug_reg, output wire Instram_branch_flag ); - wire[`InstAddrBus] pc; + wire[`InstAddrBus] pc_1; + wire[`InstAddrBus] pc_2; wire chip_enable; assign ram_en_o = chip_enable; - assign ram_raddr_o = pc; + assign ram_raddr_o_1 = pc_1; + assign ram_raddr_o_2 = pc_2; wire branch_flag; assign Instram_branch_flag=branch_flag; @@ -50,363 +68,691 @@ module cpu_top ( wire[`RegBus] link_addr; wire flush; wire[`RegBus] new_pc; - wire[6:0] stall; // [pc_reg,if_buffer_1, if_id, id_ex, ex_mem, mem_wb, ctrl] + wire[6:0] stall1; // [pc_reg,if_buffer_1, if_id, id_ex, ex_mem, mem_wb, ctrl] + wire[6:0] stall2; pc_reg u_pc_reg( .clk(clk), .rst(rst), - .pc(pc), + .pc_1(pc_1), + .pc_2(pc_2), .ce(chip_enable), .branch_flag_i(branch_flag), .branch_target_address(branch_target_address), .flush(flush), .new_pc(new_pc), - .stall(stall[0]) + .stall1(stall1[0]), + .stall2(stall2[0]) ); - wire [`InstAddrBus]pc2; - wire if_inst_valid; + wire [`InstAddrBus]pc_buffer_1; + wire [`InstAddrBus]pc_buffer_2; + wire if_inst_valid_1; + wire if_inst_valid_2; + if_buffer if_buffer_1( .clk(clk), .rst(rst), - .pc_i(pc), + .pc_i(pc_1), + .branch_flag_i(branch_flag), + .pc_valid(if_inst_valid_1), + .pc_o(pc_buffer_1), + .flush(flush), + .stall(stall1[1]) + ); + + if_buffer if_buffer_2( + .clk(clk), + .rst(rst), + .pc_i(pc_2), .branch_flag_i(branch_flag), - .pc_valid(if_inst_valid), - .pc_o(pc2), + .pc_valid(if_inst_valid_2), + .pc_o(pc_buffer_2), .flush(flush), - .stall(stall[1]) + .stall(stall2[1]) ); - wire[`InstAddrBus] id_pc; - wire[`InstBus] id_inst; + wire[`InstAddrBus] id_pc_1; + wire[`InstBus] id_inst_1; + wire[`InstAddrBus] id_pc_2; + wire[`InstBus] id_inst_2; // wire if_id_instr_invalid; - if_id u_if_id( + if_id u_if_id_1( .clk(clk), .rst(rst), - .if_pc_i(pc2), - .if_inst_i(ram_rdata_i), - .id_pc_o(id_pc), - .id_inst_o(id_inst), + .if_pc_i(pc_buffer_1), + .if_inst_i(ram_rdata_i_1), + .id_pc_o(id_pc_1), + .id_inst_o(id_inst_1), .if_inst_valid(if_inst_valid), .branch_flag_i(branch_flag), .flush(flush), - .stall(stall[2]) + .stall(stall1[2]) + ); + + if_id u_if_id_2( + .clk(clk), + .rst(rst), + .if_pc_i(pc_buffer_2), + .if_inst_i(ram_rdata_i_2), + .id_pc_o(id_pc_1), + .id_inst_o(id_inst_2), + .if_inst_valid(if_inst_valid), + .branch_flag_i(branch_flag), + .flush(flush), + .stall(stall2[2]) ); - wire[`AluOpBus] id_aluop; - wire[`AluSelBus] id_alusel; - wire[`RegBus] id_reg1; - wire[`RegBus] id_reg2; - wire[`RegAddrBus] id_reg_waddr; - wire id_wreg; - wire id_inst_valid; - wire[`InstAddrBus] id_inst_pc; - wire[`RegBus] id_inst_o; + wire[`AluOpBus] id_aluop_1; + wire[`AluSelBus] id_alusel_1; + wire[`RegBus] id_reg1_1; + wire[`RegBus] id_reg2_1; + wire[`RegAddrBus] id_reg_waddr_1; + wire id_wreg_1; + wire id_inst_valid_1; + wire[`InstAddrBus] id_inst_pc_1; + wire[`RegBus] id_inst_o_1; - wire reg1_read; - wire reg2_read; - wire[`RegAddrBus] reg1_addr; - wire[`RegAddrBus] reg2_addr; - wire[`RegBus] reg1_data; - wire[`RegBus] reg2_data; + wire reg1_read_1; + wire reg2_read_1; + wire[`RegAddrBus] reg1_addr_1; + wire[`RegAddrBus] reg2_addr_1; + wire[`RegBus] reg1_data_1; + wire[`RegBus] reg2_data_1; - wire ex_wreg_o; - wire[`RegAddrBus] ex_reg_waddr_o; - wire[`RegBus] ex_reg_wdata; - wire[`AluOpBus] ex_aluop_o; + wire ex_wreg_o_1; + wire[`RegAddrBus] ex_reg_waddr_o_1; + wire[`RegBus] ex_reg_wdata_1; + wire[`AluOpBus] ex_aluop_o_1; - wire mem_wreg_o; - wire[`RegAddrBus] mem_reg_waddr_o; - wire[`RegBus] mem_reg_wdata_o; + wire mem_wreg_o_1; + wire[`RegAddrBus] mem_reg_waddr_o_1; + wire[`RegBus] mem_reg_wdata_o_1; - wire stallreq_from_id; - wire stallreq_from_ex; + wire stallreq_from_id_1; + wire stallreq_from_ex_1; - wire[1:0] id_excepttype_o; - wire[`RegBus] id_current_inst_address_o; + wire[1:0] id_excepttype_o_1; + wire[`RegBus] id_current_inst_address_o_1; - id u_id( + id u_id_1( .rst(rst), - .pc_i(id_pc), - .inst_i(id_inst), + .pc_i(id_pc_1), + .inst_i(id_inst_1), - .reg1_data_i (reg1_data ), - .reg2_data_i (reg2_data ), + .reg1_data_i (reg1_data_1 ), + .reg2_data_i (reg2_data_1 ), - .ex_wreg_i (ex_wreg_o ), - .ex_waddr_i (ex_reg_waddr_o), - .ex_wdata_i (ex_reg_wdata), - .ex_aluop_i (ex_aluop_o), + .ex_wreg_i (ex_wreg_o_1 ), + .ex_waddr_i (ex_reg_waddr_o_1), + .ex_wdata_i (ex_reg_wdata_1), + .ex_aluop_i (ex_aluop_o_1), - .mem_wreg_i (mem_wreg_o), - .mem_waddr_i (mem_reg_waddr_o), - .mem_wdata_i (mem_reg_wdata_o), + .mem_wreg_i (mem_wreg_o_1), + .mem_waddr_i (mem_reg_waddr_o_1), + .mem_wdata_i (mem_reg_wdata_o_1), - .reg1_read_o (reg1_read ), - .reg2_read_o (reg2_read ), + .reg1_read_o (reg1_read_1 ), + .reg2_read_o (reg2_read_1 ), - .reg1_addr_o (reg1_addr ), - .reg2_addr_o (reg2_addr ), + .reg1_addr_o (reg1_addr_1 ), + .reg2_addr_o (reg2_addr_1 ), - .aluop_o (id_aluop ), - .alusel_o (id_alusel ), - .reg1_o (id_reg1 ), - .reg2_o (id_reg2 ), - .reg_waddr_o (id_reg_waddr ), - .wreg_o (id_wreg ), - .inst_valid(id_inst_valid), - .inst_pc(id_inst_pc), - .inst_o(id_inst_o), + .aluop_o (id_aluop_1 ), + .alusel_o (id_alusel_1 ), + .reg1_o (id_reg1_1 ), + .reg2_o (id_reg2_1 ), + .reg_waddr_o (id_reg_waddr_1 ), + .wreg_o (id_wreg_1 ), + .inst_valid(id_inst_valid_1), + .inst_pc(id_inst_pc_1), + .inst_o(id_inst_o_1), .branch_flag_o(branch_flag), .branch_target_address_o(branch_target_address), .link_addr_o(link_addr), - .stallreq(stallreq_from_id), + .stallreq(stallreq_from_id_1), - .excepttype_o(id_excepttype_o), - .current_inst_address_o(id_current_inst_address_o) + .excepttype_o(id_excepttype_o_1), + .current_inst_address_o(id_current_inst_address_o_1) ); - wire[`AluOpBus] ex_aluop; - wire[`AluSelBus] ex_alusel; - wire[`RegBus] ex_reg1; - wire[`RegBus] ex_reg2; - wire[`RegAddrBus] ex_reg_waddr_i; - wire ex_wreg_i; - wire ex_inst_valid_i; - wire[`InstAddrBus] ex_inst_pc_i; - wire[`RegBus] ex_link_address; - wire[`RegBus] ex_inst_i; - wire[1:0] ex_excepttype_i; - wire[`RegBus] ex_current_inst_address_i; - - id_ex id_ex0( + wire[`AluOpBus] id_aluop_2; + wire[`AluSelBus] id_alusel_2; + wire[`RegBus] id_reg1_2; + wire[`RegBus] id_reg2_2; + wire[`RegAddrBus] id_reg_waddr_2; + wire id_wreg_2; + wire id_inst_valid_2; + wire[`InstAddrBus] id_inst_pc_2; + wire[`RegBus] id_inst_o_2; + + wire reg1_read_2; + wire reg2_read_2; + wire[`RegAddrBus] reg1_addr_2; + wire[`RegAddrBus] reg2_addr_2; + wire[`RegBus] reg1_data_2; + wire[`RegBus] reg2_data_2; + + wire ex_wreg_o_2; + wire[`RegAddrBus] ex_reg_waddr_o_2; + wire[`RegBus] ex_reg_wdata_2; + wire[`AluOpBus] ex_aluop_o_2; + + wire mem_wreg_o_2; + wire[`RegAddrBus] mem_reg_waddr_o_2; + wire[`RegBus] mem_reg_wdata_o_2; + + wire stallreq_from_id_2; + wire stallreq_from_ex_2; + + wire[1:0] id_excepttype_o_2; + wire[`RegBus] id_current_inst_address_o_2; + + id u_id_2( + .rst(rst), + .pc_i(id_pc_2), + .inst_i(id_inst_2), + + .reg1_data_i (reg1_data_2 ), + .reg2_data_i (reg2_data_2 ), + + .ex_wreg_i (ex_wreg_o_2 ), + .ex_waddr_i (ex_reg_waddr_o_2), + .ex_wdata_i (ex_reg_wdata_2), + .ex_aluop_i (ex_aluop_o_2), + + .mem_wreg_i (mem_wreg_o_2), + .mem_waddr_i (mem_reg_waddr_o_2), + .mem_wdata_i (mem_reg_wdata_o_2), + + .reg1_read_o (reg1_read_2 ), + .reg2_read_o (reg2_read_2 ), + + .reg1_addr_o (reg1_addr_2 ), + .reg2_addr_o (reg2_addr_2 ), + + .aluop_o (id_aluop_2 ), + .alusel_o (id_alusel_2 ), + .reg1_o (id_reg1_2 ), + .reg2_o (id_reg2_2 ), + .reg_waddr_o (id_reg_waddr_2 ), + .wreg_o (id_wreg_2 ), + .inst_valid(id_inst_valid_2), + .inst_pc(id_inst_pc_2), + .inst_o(id_inst_o_2), + + .branch_flag_o(branch_flag), + .branch_target_address_o(branch_target_address), + .link_addr_o(link_addr), + + .stallreq(stallreq_from_id_2), + + .excepttype_o(id_excepttype_o_2), + .current_inst_address_o(id_current_inst_address_o_2) + ); + + wire[`AluOpBus] ex_aluop_1; + wire[`AluSelBus] ex_alusel_1; + wire[`RegBus] ex_reg1_1; + wire[`RegBus] ex_reg2_1; + wire[`RegAddrBus] ex_reg_waddr_i_1; + wire ex_wreg_i_1; + wire ex_inst_valid_i_1; + wire[`InstAddrBus] ex_inst_pc_i_1; + wire[`RegBus] ex_link_address_1; + wire[`RegBus] ex_inst_i_1; + wire[1:0] ex_excepttype_i_1; + wire[`RegBus] ex_current_inst_address_i_1; + + id_ex id_ex_1( .clk(clk), .rst(rst), - .stall(stall[3]), - - .id_aluop(id_aluop), - .id_alusel(id_alusel), - .id_reg1(id_reg1), - .id_reg2(id_reg2), - .id_wd(id_reg_waddr), - .id_wreg(id_wreg), - .id_inst_pc(id_inst_pc), - .id_inst_valid(id_inst_valid), + .stall(stall1[3]), + + .id_aluop(id_aluop_1), + .id_alusel(id_alusel_1), + .id_reg1(id_reg1_1), + .id_reg2(id_reg2_1), + .id_wd(id_reg_waddr_1), + .id_wreg(id_wreg_1), + .id_inst_pc(id_inst_pc_1), + .id_inst_valid(id_inst_valid_1), .id_link_address(link_addr), - .id_inst(id_inst_o), + .id_inst(id_inst_o_1), .flush(flush), - .id_excepttype(id_excepttype_o), - .id_current_inst_address(id_current_inst_address_o), - - .ex_aluop(ex_aluop), - .ex_alusel(ex_alusel), - .ex_reg1(ex_reg1), - .ex_reg2(ex_reg2), - .ex_wd(ex_reg_waddr_i), - .ex_wreg(ex_wreg_i), - .ex_inst_pc(ex_inst_pc_i), - .ex_inst_valid(ex_inst_valid_i), - .ex_link_address(ex_link_address), - .ex_inst(ex_inst_i), - .ex_excepttype(ex_excepttype_i), - .ex_current_inst_address(ex_current_inst_address_i) + .id_excepttype(id_excepttype_o_1), + .id_current_inst_address(id_current_inst_address_o_1), + + .ex_aluop(ex_aluop_1), + .ex_alusel(ex_alusel_1), + .ex_reg1(ex_reg1_1), + .ex_reg2(ex_reg2_1), + .ex_wd(ex_reg_waddr_i_1), + .ex_wreg(ex_wreg_i_1), + .ex_inst_pc(ex_inst_pc_i_1), + .ex_inst_valid(ex_inst_valid_i_1), + .ex_link_address(ex_link_address_1), + .ex_inst(ex_inst_i_1), + .ex_excepttype(ex_excepttype_i_1), + .ex_current_inst_address(ex_current_inst_address_i_1) ); + wire[`AluOpBus] ex_aluop_2; + wire[`AluSelBus] ex_alusel_2; + wire[`RegBus] ex_reg1_2; + wire[`RegBus] ex_reg2_2; + wire[`RegAddrBus] ex_reg_waddr_i_2; + wire ex_wreg_i_2; + wire ex_inst_valid_i_2; + wire[`InstAddrBus] ex_inst_pc_i_2; + wire[`RegBus] ex_link_address_2; + wire[`RegBus] ex_inst_i_2; + wire[1:0] ex_excepttype_i_2; + wire[`RegBus] ex_current_inst_address_i_2; + + id_ex id_ex_2( + .clk(clk), + .rst(rst), + .stall(stall2[3]), + + .id_aluop(id_aluop_2), + .id_alusel(id_alusel_2), + .id_reg1(id_reg1_2), + .id_reg2(id_reg2_2), + .id_wd(id_reg_waddr_2), + .id_wreg(id_wreg_2), + .id_inst_pc(id_inst_pc_2), + .id_inst_valid(id_inst_valid_2), + .id_link_address(link_addr_2), + .id_inst(id_inst_o_2), + .flush(flush), + .id_excepttype(id_excepttype_o_2), + .id_current_inst_address(id_current_inst_address_o_2), + + .ex_aluop(ex_aluop_2), + .ex_alusel(ex_alusel_2), + .ex_reg1(ex_reg1_2), + .ex_reg2(ex_reg2_2), + .ex_wd(ex_reg_waddr_i_2), + .ex_wreg(ex_wreg_i_2), + .ex_inst_pc(ex_inst_pc_i_2), + .ex_inst_valid(ex_inst_valid_i_2), + .ex_link_address(ex_link_address_2), + .ex_inst(ex_inst_i_2), + .ex_excepttype(ex_excepttype_i_2), + .ex_current_inst_address(ex_current_inst_address_i_2) + ); + + + wire ex_inst_valid_o_1; + wire[`InstAddrBus] ex_inst_pc_o_1; + wire[`RegBus] ex_addr_o_1; + wire[`RegBus] ex_reg2_o_1; + wire[1:0] ex_excepttype_o_1; + wire[`RegBus] ex_current_inst_address_o_1; + + ex u_ex_1( + .rst(rst), + + .aluop_i(ex_aluop_1), + .alusel_i(ex_alusel_1), + .reg1_i(ex_reg1_1), + .reg2_i(ex_reg2_1), + .wd_i(ex_reg_waddr_i_1), + .wreg_i(ex_wreg_i_1), + .inst_valid_i(ex_inst_valid_i_1), + .inst_pc_i(ex_inst_pc_i_1), + .inst_i(ex_inst_i_1), + .link_addr_i(ex_link_address_1), + .excepttype_i(ex_excepttype_i_1), + .current_inst_address_i(ex_current_inst_address_i_1), + + .wd_o(ex_reg_waddr_o_1), + .wreg_o(ex_wreg_o_1), + .wdata_o(ex_reg_wdata_1), + .inst_valid_o(ex_inst_valid_o_1), + .inst_pc_o(ex_inst_pc_o_1), + .aluop_o(ex_aluop_o_1), + .mem_addr_o(ex_addr_o_1), + .reg2_o(ex_reg2_o_1), + .excepttype_o(ex_excepttype_o_1), + .current_inst_address_o(ex_current_inst_address_o_1), + + .stallreq(stallreq_from_ex_1) + ); - wire ex_inst_valid_o; - wire[`InstAddrBus] ex_inst_pc_o; - wire[`RegBus] ex_addr_o; - wire[`RegBus] ex_reg2_o; - wire[1:0] ex_excepttype_o; - wire[`RegBus] ex_current_inst_address_o; + wire ex_inst_valid_o_2; + wire[`InstAddrBus] ex_inst_pc_o_2; + wire[`RegBus] ex_addr_o_2; + wire[`RegBus] ex_reg2_o_2; + wire[1:0] ex_excepttype_o_2; + wire[`RegBus] ex_current_inst_address_o_2; - ex u_ex( + ex u_ex_2( .rst(rst), - .aluop_i(ex_aluop), - .alusel_i(ex_alusel), - .reg1_i(ex_reg1), - .reg2_i(ex_reg2), - .wd_i(ex_reg_waddr_i), - .wreg_i(ex_wreg_i), - .inst_valid_i(ex_inst_valid_i), - .inst_pc_i(ex_inst_pc_i), - .inst_i(ex_inst_i), - .link_addr_i(ex_link_address), - .excepttype_i(ex_excepttype_i), - .current_inst_address_i(ex_current_inst_address_i), - - .wd_o(ex_reg_waddr_o), - .wreg_o(ex_wreg_o), - .wdata_o(ex_reg_wdata), - .inst_valid_o(ex_inst_valid_o), - .inst_pc_o(ex_inst_pc_o), - .aluop_o(ex_aluop_o), - .mem_addr_o(ex_addr_o), - .reg2_o(ex_reg2_o), - .excepttype_o(ex_excepttype_o), - .current_inst_address_o(ex_current_inst_address_o), - - .stallreq(stallreq_from_ex) + .aluop_i(ex_aluop_2), + .alusel_i(ex_alusel_2), + .reg1_i(ex_reg1_2), + .reg2_i(ex_reg2_2), + .wd_i(ex_reg_waddr_i_2), + .wreg_i(ex_wreg_i_2), + .inst_valid_i(ex_inst_valid_i_2), + .inst_pc_i(ex_inst_pc_i_2), + .inst_i(ex_inst_i_2), + .link_addr_i(ex_link_address_2), + .excepttype_i(ex_excepttype_i_2), + .current_inst_address_i(ex_current_inst_address_i_2), + + .wd_o(ex_reg_waddr_o_2), + .wreg_o(ex_wreg_o_2), + .wdata_o(ex_reg_wdata_2), + .inst_valid_o(ex_inst_valid_o_2), + .inst_pc_o(ex_inst_pc_o_2), + .aluop_o(ex_aluop_o_2), + .mem_addr_o(ex_addr_o_2), + .reg2_o(ex_reg2_o_2), + .excepttype_o(ex_excepttype_o_2), + .current_inst_address_o(ex_current_inst_address_o_2), + + .stallreq(stallreq_from_ex_1_2) ); - wire mem_wreg_i; - wire[`RegAddrBus] mem_reg_waddr_i; - wire[`RegBus] mem_reg_wdata_i; + wire mem_wreg_i_1; + wire[`RegAddrBus] mem_reg_waddr_i_1; + wire[`RegBus] mem_reg_wdata_i_1; - wire mem_inst_valid; - wire[`InstAddrBus] mem_inst_pc; + wire mem_inst_valid_1; + wire[`InstAddrBus] mem_inst_pc_1; - wire[`AluOpBus] mem_aluop_i; - wire[`RegBus] mem_addr_i; - wire[`RegBus] mem_reg2_i; - wire[1:0] mem_excepttype_i; - wire[`RegBus] mem_current_inst_address_i; + wire[`AluOpBus] mem_aluop_i_1; + wire[`RegBus] mem_addr_i_1; + wire[`RegBus] mem_reg2_i_1; + wire[1:0] mem_excepttype_i_1; + wire[`RegBus] mem_current_inst_address_i_1; - ex_mem u_ex_mem( + ex_mem u_ex_mem_1( .clk(clk ), .rst(rst ), - .stall(stall[4]), - - .ex_wd (ex_reg_waddr_o ), - .ex_wreg (ex_wreg_o ), - .ex_wdata (ex_reg_wdata ), - .ex_inst_pc(ex_inst_pc_o), - .ex_inst_valid(ex_inst_valid_o), - .ex_aluop(ex_aluop_o), - .ex_mem_addr(ex_addr_o), - .ex_reg2(ex_reg2_o), + .stall(stall1[4]), + + .ex_wd (ex_reg_waddr_o_1 ), + .ex_wreg (ex_wreg_o_1 ), + .ex_wdata (ex_reg_wdata_1 ), + .ex_inst_pc(ex_inst_pc_o_1), + .ex_inst_valid(ex_inst_valid_o_1), + .ex_aluop(ex_aluop_o_1), + .ex_mem_addr(ex_addr_o_1), + .ex_reg2(ex_reg2_o_1), .flush(flush), - .ex_excepttype(ex_excepttype_o), - .ex_current_inst_address(ex_current_inst_address_o), - - .mem_wd(mem_reg_waddr_i ), - .mem_wreg(mem_wreg_i ), - .mem_wdata(mem_reg_wdata_i ), - .mem_inst_valid(mem_inst_valid), - .mem_inst_pc(mem_inst_pc), - .mem_aluop(mem_aluop_i), - .mem_mem_addr(mem_addr_i), - .mem_reg2(mem_reg2_i), - .mem_excepttype(mem_excepttype_i), - .mem_current_inst_address(mem_current_inst_address_i) + .ex_excepttype(ex_excepttype_o_1), + .ex_current_inst_address(ex_current_inst_address_o_1), + + .mem_wd(mem_reg_waddr_i_1 ), + .mem_wreg(mem_wreg_i_1 ), + .mem_wdata(mem_reg_wdata_i_1 ), + .mem_inst_valid(mem_inst_valid_1), + .mem_inst_pc(mem_inst_pc_1), + .mem_aluop(mem_aluop_i_1), + .mem_mem_addr(mem_addr_i_1), + .mem_reg2(mem_reg2_i_1), + .mem_excepttype(mem_excepttype_i_1), + .mem_current_inst_address(mem_current_inst_address_i_1) ); - wire LLbit_o; - wire wb_LLbit_we_i; - wire wb_LLbit_value_i; - wire mem_LLbit_we_o; - wire mem_LLbit_value_o; - wire[1:0] mem_excepttype_o; - wire[`RegBus] mem_current_inst_address_o; - mem u_mem( + wire mem_wreg_i_2; + wire[`RegAddrBus] mem_reg_waddr_i_2; + wire[`RegBus] mem_reg_wdata_i_2; + + wire mem_inst_valid_2; + wire[`InstAddrBus] mem_inst_pc_2; + + wire[`AluOpBus] mem_aluop_i_2; + wire[`RegBus] mem_addr_i_2; + wire[`RegBus] mem_reg2_i_2; + wire[1:0] mem_excepttype_i_2; + wire[`RegBus] mem_current_inst_address_i_2; + + + ex_mem u_ex_mem_2( + .clk(clk ), + .rst(rst ), + .stall(stall2[4]), + + .ex_wd (ex_reg_waddr_o_2 ), + .ex_wreg (ex_wreg_o_2 ), + .ex_wdata (ex_reg_wdata_2 ), + .ex_inst_pc(ex_inst_pc_o_2), + .ex_inst_valid(ex_inst_valid_o_2), + .ex_aluop(ex_aluop_o_2), + .ex_mem_addr(ex_addr_o_2), + .ex_reg2(ex_reg2_o_2), + .flush(flush), + .ex_excepttype(ex_excepttype_o_2), + .ex_current_inst_address(ex_current_inst_address_o_2), + + .mem_wd(mem_reg_waddr_i_2 ), + .mem_wreg(mem_wreg_i_2 ), + .mem_wdata(mem_reg_wdata_i_2 ), + .mem_inst_valid(mem_inst_valid_2), + .mem_inst_pc(mem_inst_pc_2), + .mem_aluop(mem_aluop_i_2), + .mem_mem_addr(mem_addr_i_2), + .mem_reg2(mem_reg2_i_2), + .mem_excepttype(mem_excepttype_i_2), + .mem_current_inst_address(mem_current_inst_address_i_2) + ); + + wire LLbit_o_1; + wire wb_LLbit_we_i_1; + wire wb_LLbit_value_i_1; + wire mem_LLbit_we_o_1; + wire mem_LLbit_value_o_1; + wire[1:0] mem_excepttype_o_1; + wire[`RegBus] mem_current_inst_address_o_1; + + mem u_mem_1( .rst (rst ), - .wd_i (mem_reg_waddr_i ), - .wreg_i (mem_wreg_i ), - .wdata_i (mem_reg_wdata_i), - .aluop_i(mem_aluop_i), - .mem_addr_i(mem_addr_i), - .reg2_i(mem_reg2_i), + .wd_i (mem_reg_waddr_i_1 ), + .wreg_i (mem_wreg_i_1 ), + .wdata_i (mem_reg_wdata_i_1), + .aluop_i(mem_aluop_i_1), + .mem_addr_i(mem_addr_i_1), + .reg2_i(mem_reg2_i_1), - .mem_data_i(dram_data_i), + .mem_data_i(dram_data_i_1), - .LLbit_i(LLbit_o), - .wb_LLbit_we_i(wb_LLbit_we_i), - .wb_LLbit_value_i(wb_LLbit_value_i), + .LLbit_i(LLbit_o_1), + .wb_LLbit_we_i(wb_LLbit_we_i_1), + .wb_LLbit_value_i(wb_LLbit_value_i_1), - .excepttype_i(mem_excepttype_i), - .current_inst_address_i(mem_current_inst_address_i), + .excepttype_i(mem_excepttype_i_1), + .current_inst_address_i(mem_current_inst_address_i_1), - .wd_o (mem_reg_waddr_o), - .wreg_o (mem_wreg_o ), - .wdata_o (mem_reg_wdata_o ), + .wd_o (mem_reg_waddr_o_1), + .wreg_o (mem_wreg_o_1 ), + .wdata_o (mem_reg_wdata_o_1 ), - .mem_addr_o(dram_addr_o), - .mem_we_o(dram_we_o), - .mem_sel_o(dram_sel_o), - .mem_data_o(dram_data_o), - .mem_ce_o(dram_ce_o), + .mem_addr_o(dram_addr_o_1), + .mem_we_o(dram_we_o_1), + .mem_sel_o(dram_sel_o_1), + .mem_data_o(dram_data_o_1), + .mem_ce_o(dram_ce_o_1), - .LLbit_we_o(mem_LLbit_we_o), - .LLbit_value_o(mem_LLbit_value_o), + .LLbit_we_o(mem_LLbit_we_o_1), + .LLbit_value_o(mem_LLbit_value_o_1), - .excepttype_o(mem_excepttype_o), - .current_inst_address_o(mem_current_inst_address_o) + .excepttype_o(mem_excepttype_o_1), + .current_inst_address_o(mem_current_inst_address_o_1) ); + + wire LLbit_o_2; + wire wb_LLbit_we_i_2; + wire wb_LLbit_value_i_2; + wire mem_LLbit_we_o_2; + wire mem_LLbit_value_o_2; + wire[1:0] mem_excepttype_o_2; + wire[`RegBus] mem_current_inst_address_o_2 ; + + mem u_mem_2( + .rst (rst ), + + .wd_i (mem_reg_waddr_i_2 ), + .wreg_i (mem_wreg_i_2 ), + .wdata_i (mem_reg_wdata_i_2), + .aluop_i(mem_aluop_i_2), + .mem_addr_i(mem_addr_i_2), + .reg2_i(mem_reg2_i_2), + + .mem_data_i(dram_data_i_2), + .LLbit_i(LLbit_o_2), + .wb_LLbit_we_i(wb_LLbit_we_i_2), + .wb_LLbit_value_i(wb_LLbit_value_i_2), - wire wb_wreg; - wire[`RegAddrBus] wb_reg_waddr; - wire[`RegBus] wb_reg_wdata; + .excepttype_i(mem_excepttype_i_2), + .current_inst_address_i(mem_current_inst_address_i_2), - assign debug_commit_wreg = wb_wreg; - assign debug_commit_reg_waddr = wb_reg_waddr; - assign debug_commit_reg_wdata = wb_reg_wdata; + .wd_o (mem_reg_waddr_o_2), + .wreg_o (mem_wreg_o_2 ), + .wdata_o (mem_reg_wdata_o_2 ), + .mem_addr_o(dram_addr_o_2), + .mem_we_o(dram_we_o_2), + .mem_sel_o(dram_sel_o_2), + .mem_data_o(dram_data_o_2), + .mem_ce_o(dram_ce_o_2), + + .LLbit_we_o(mem_LLbit_we_o_2), + .LLbit_value_o(mem_LLbit_value_o_2), + + .excepttype_o(mem_excepttype_o_2), + .current_inst_address_o(mem_current_inst_address_o_2) + + ); - mem_wb mem_wb0( + wire wb_wreg_1; + wire[`RegAddrBus] wb_reg_waddr_1; + wire[`RegBus] wb_reg_wdata_1; + + assign debug_commit_wreg_1 = wb_wreg_1; + assign debug_commit_reg_waddr_1 = wb_reg_waddr_1; + assign debug_commit_reg_wdata_1 = wb_reg_wdata_1; + + + + mem_wb mem_wb_1( + .clk(clk), + .rst(rst), + .stall(stall1[5]), + + .mem_wd(mem_reg_waddr_o_1), + .mem_wreg(mem_wreg_o_1), + .mem_wdata(mem_reg_wdata_o_1), + .mem_inst_pc (mem_inst_pc_1 ), + .mem_instr ( ), + .mem_inst_valid (mem_inst_valid_1 ), + + .mem_LLbit_we(mem_LLbit_we_o_1), + .mem_LLbit_value(mem_LLbit_value_o_1), + + .flush(flush), + + .wb_wd(wb_reg_waddr_1), + .wb_wreg(wb_wreg_1), + .wb_wdata(wb_reg_wdata_1), + + .wb_LLbit_we(wb_LLbit_we_i_1), + .wb_LLbit_value(wb_LLbit_value_i_1), + + .debug_commit_pc (debug_commit_pc_1 ), + .debug_commit_valid (debug_commit_valid_1 ), + .debug_commit_instr (debug_commit_instr_1 ) + ); + + wire wb_wreg_2; + wire[`RegAddrBus] wb_reg_waddr_2; + wire[`RegBus] wb_reg_wdata_2; + + assign debug_commit_wreg_2 = wb_wreg_2; + assign debug_commit_reg_waddr_2 = wb_reg_waddr_2; + assign debug_commit_reg_wdata_2 = wb_reg_wdata_2; + + mem_wb mem_wb_2( .clk(clk), .rst(rst), - .stall(stall[5]), + .stall(stall2[5]), - .mem_wd(mem_reg_waddr_o), - .mem_wreg(mem_wreg_o), - .mem_wdata(mem_reg_wdata_o), - .mem_inst_pc (mem_inst_pc ), + .mem_wd(mem_reg_waddr_o_2), + .mem_wreg(mem_wreg_o_2), + .mem_wdata(mem_reg_wdata_o_2), + .mem_inst_pc (mem_inst_pc_2 ), .mem_instr ( ), - .mem_inst_valid (mem_inst_valid ), + .mem_inst_valid (mem_inst_valid_2 ), - .mem_LLbit_we(mem_LLbit_we_o), - .mem_LLbit_value(mem_LLbit_value_o), + .mem_LLbit_we(mem_LLbit_we_o_2), + .mem_LLbit_value(mem_LLbit_value_o_2), .flush(flush), - .wb_wd(wb_reg_waddr), - .wb_wreg(wb_wreg), - .wb_wdata(wb_reg_wdata), + .wb_wd(wb_reg_waddr_2), + .wb_wreg(wb_wreg_2), + .wb_wdata(wb_reg_wdata_2), - .wb_LLbit_we(wb_LLbit_we_i), - .wb_LLbit_value(wb_LLbit_value_i), + .wb_LLbit_we(wb_LLbit_we_i_2), + .wb_LLbit_value(wb_LLbit_value_i_2), - .debug_commit_pc (debug_commit_pc ), - .debug_commit_valid (debug_commit_valid ), - .debug_commit_instr (debug_commit_instr ) + .debug_commit_pc (debug_commit_pc_2 ), + .debug_commit_valid (debug_commit_valid_2 ), + .debug_commit_instr (debug_commit_instr_2 ) ); regfile u_regfile( .clk(clk ), .rst(rst ), - .we (wb_wreg), - .waddr (wb_reg_waddr), - .wdata (wb_reg_wdata), - - .re1 (reg1_read), - .raddr1 (reg1_addr), - .rdata1 (reg1_data), - .re2 (reg2_read), - .raddr2 (reg2_addr), - .rdata2 (reg2_data), + .we_1 (wb_wreg_1), + .waddr_1 (wb_reg_waddr_1), + .wdata_1 (wb_reg_wdata_1), + .we_2 (wb_wreg_2), + .waddr_2 (wb_reg_waddr_2), + .wdata_2 (wb_reg_wdata_2), + + .re1_1 (reg1_read_1), + .raddr1_1 (reg1_addr_1), + .rdata1_1 (reg1_data_1), + .re2_1 (reg2_read_1), + .raddr2_1 (reg2_addr_1), + .rdata2_1 (reg2_data_1), + .re1_2 (reg1_read_2), + .raddr1_2 (reg1_addr_2), + .rdata1_2 (reg1_data_2), + .re2_2 (reg2_read_2), + .raddr2_2 (reg2_addr_2), + .rdata2_2 (reg2_data_2), .debug_reg (debug_reg) ); ctrl u_ctrl( .clk (clk ), .rst (rst ), - .stall(stall), - .stallreq_from_id(stallreq_from_id), - .stallreq_from_ex(stallreq_from_ex), + .stall1(stall1), + .stallreq_from_id_1(stallreq_from_id_1), + .stallreq_from_ex_1(stallreq_from_ex_1), + .stall2(stall2), + .stallreq_from_id_2(stallreq_from_id_2), + .stallreq_from_ex_2(stallreq_from_ex_2), .excepttype_i(mem_excepttype_o), .new_pc(new_pc), .flush(flush) diff --git a/src/vsrc/ctrl.v b/src/vsrc/ctrl.v index 12d6645..fb40704 100644 --- a/src/vsrc/ctrl.v +++ b/src/vsrc/ctrl.v @@ -2,12 +2,15 @@ module ctrl ( input wire clk, input wire rst, - input wire stallreq_from_id, - input wire stallreq_from_ex, + input wire stallreq_from_id_1, + input wire stallreq_from_ex_1, + input wire stallreq_from_id_2, + input wire stallreq_from_ex_2, input wire[1:0] excepttype_i, - output reg[6:0]stall, + output reg[6:0]stall1, + output reg[6:0]stall2, output reg[`RegBus] new_pc, output reg flush ); @@ -20,13 +23,11 @@ module ctrl ( begin flush <= 1'b0; new_pc <= `ZeroWord; - stall <= 7'b0000000; end else if(excepttype_i != 0) begin flush <= 1'b1; - stall <= 7'b0000000; case (excepttype_i) 2'b01: new_pc <= 32'h0000000c; @@ -37,25 +38,35 @@ module ctrl ( end endcase end - else if(stallreq_from_id == `Stop) - begin - flush <= 1'b0; - new_pc <= `ZeroWord; - stall <= 7'b0011111; - end - else if(stallreq_from_ex == `Stop) - begin - flush <= 1'b0; - new_pc <= `ZeroWord; - stall <= 7'b0011111; - end else begin flush <= 1'b0; new_pc <= `ZeroWord; - stall <= 7'b0000000; end + end + always @(posedge clk or negedge rst_n) + begin + if (!rst_n) + stall1 <= 7'b0000000; + else if(stallreq_from_ex_1 == `Stop) + stall1 <= 7'b0011111; + else if(stallreq_from_id_1 == `Stop) + stall1 <= 7'b0011111; + else + stall1 <= 7'b0000000; + end + + always @(posedge clk or negedge rst_n) + begin + if (!rst_n) + stall2 <= 7'b0000000; + else if(stallreq_from_ex_2 == `Stop) + stall2 <= 7'b0011111; + else if(stallreq_from_id_2 == `Stop) + stall2 <= 7'b0011111; + else + stall2 <= 7'b0000000; end diff --git a/src/vsrc/pc_reg.v b/src/vsrc/pc_reg.v index 69df8a2..557b933 100644 --- a/src/vsrc/pc_reg.v +++ b/src/vsrc/pc_reg.v @@ -2,7 +2,8 @@ module pc_reg ( input wire clk, input wire rst, - input wire stall, + input wire stall1, + input wire stall2, input wire branch_flag_i, input wire[`RegBus] branch_target_address, @@ -10,26 +11,46 @@ module pc_reg ( input wire flush, input wire[`RegBus] new_pc, - output reg[`InstAddrBus] pc, + output reg[`InstAddrBus] pc_1, + output reg[`InstAddrBus] pc_2, output reg ce ); always @(posedge clk) begin if(ce == `ChipDisable) - pc <= 32'h1c000000; + pc_1 <= 32'h1c000000; else if(flush == 1'b1) - pc <= new_pc; - else if(stall == `Stop) // Hold output + pc_1 <= new_pc; + else if(stall1 == `Stop) // Hold output begin - pc <= pc; + pc_1 <= pc_1; end else begin if(branch_flag_i == `Branch) - pc <= branch_target_address; + pc_1 <= branch_target_address; else - pc <= pc + 32'h4; + pc_1 <= pc_1 + 32'h8; + end + end + + always @(posedge clk) + begin + if(ce == `ChipDisable) + pc_2 <= 32'h1c000004; + else if(flush == 1'b1) + pc_2 <= new_pc + 4'h4; + else if(stall2 == `Stop) // Hold output + begin + pc_2 <= pc_2; + end + else + begin + if(branch_flag_i == `Branch) + pc_2 <= branch_target_address + 4'h4; + else + pc_2 <= pc_2 + 32'h8; end end diff --git a/src/vsrc/regfile.v b/src/vsrc/regfile.v index 5fd1b4a..16f7925 100644 --- a/src/vsrc/regfile.v +++ b/src/vsrc/regfile.v @@ -3,17 +3,26 @@ module regfile ( input wire clk, input wire rst, - input wire we, - input wire [`RegAddrBus] waddr, - input wire [`RegBus] wdata, + input wire we_1, + input wire [`RegAddrBus] waddr_1, + input wire [`RegBus] wdata_1, + input wire we_2, + input wire [`RegAddrBus] waddr_2, + input wire [`RegBus] wdata_2, - input wire re1, - input wire [`RegAddrBus] raddr1, - output reg [`RegBus] rdata1, + input wire re1_1, + input wire [`RegAddrBus] raddr1_1, + output reg [`RegBus] rdata1_1, + input wire re1_2, + input wire [`RegAddrBus] raddr1_2, + output reg [`RegBus] rdata1_2, - input wire re2, - input wire [`RegAddrBus] raddr2, - output reg [`RegBus] rdata2, + input wire re2_1, + input wire [`RegAddrBus] raddr2_1, + output reg [`RegBus] rdata2_1, + input wire re2_2, + input wire [`RegAddrBus] raddr2_2, + output reg [`RegBus] rdata2_2, output wire[1023:0] debug_reg ); @@ -56,37 +65,68 @@ always @ (posedge clk)begin regs[2] <= `ZeroWord; regs[1] <= `ZeroWord; regs[0] <= `ZeroWord; - end else if ((we == `WriteEnable) && !(waddr == `RegNumLog2'h0)) - regs[waddr] <= wdata; - + end else begin + if ((we_1 == `WriteEnable) && !(waddr_1 == `RegNumLog2'h0)) + regs[waddr_1] <= wdata_1; + if ((we_2 == `WriteEnable) && !(waddr_2 == `RegNumLog2'h0)) + regs[waddr_2] <= wdata_2; + end end always @ (*) begin if (rst == `RstEnable) - rdata1 = `ZeroWord; - else if (raddr1 == `RegNumLog2'h0) - rdata1 = `ZeroWord; - else if ((raddr1 == waddr) && (we == `WriteEnable) && (re1 == `ReadEnable)) - rdata1 = wdata; - else if (re1 == `ReadEnable) - rdata1 = regs[raddr1]; + rdata1_1 = `ZeroWord; + else if (raddr1_1 == `RegNumLog2'h0) + rdata1_1 = `ZeroWord; + else if ((raddr1_1 == waddr_1) && (we_1 == `WriteEnable) && (re1_1 == `ReadEnable)) + rdata1_1 = wdata_1; + else if (re1_1 == `ReadEnable) + rdata1_1 = regs[raddr1_1]; + else + rdata1_1 = `ZeroWord; + end + + always @ (*) + begin + if (rst == `RstEnable) + rdata1_2 = `ZeroWord; + else if (raddr1_2 == `RegNumLog2'h0) + rdata1_2 = `ZeroWord; + else if ((raddr1_2 == waddr_1) && (we_1 == `WriteEnable) && (re1_2 == `ReadEnable)) + rdata1_2 = wdata_1; + else if (re1_2 == `ReadEnable) + rdata1_2 = regs[raddr1_2]; + else + rdata1_2= `ZeroWord; + end + + always @ (*) + begin + if (rst == `RstEnable) + rdata2_1 = `ZeroWord; + else if (raddr2_1 == `RegNumLog2'h0) + rdata2_1 = `ZeroWord; + else if ((raddr2_1 == waddr_2) && (we_2 == `WriteEnable) && (re2_1 == `ReadEnable)) + rdata2_1 = wdata_2; + else if (re2_1 == `ReadEnable) + rdata2_1 = regs[raddr2_1]; else - rdata1 = `ZeroWord; + rdata2_1 = `ZeroWord; end always @ (*) begin if (rst == `RstEnable) - rdata2 = `ZeroWord; - else if (raddr2 == `RegNumLog2'h0) - rdata2 = `ZeroWord; - else if ((raddr2 == waddr) && (we == `WriteEnable) && (re2 == `ReadEnable)) - rdata2 = wdata; - else if (re2 == `ReadEnable) - rdata2 = regs[raddr2]; + rdata2_2 = `ZeroWord; + else if (raddr2_2 == `RegNumLog2'h0) + rdata2_2 = `ZeroWord; + else if ((raddr2_2 == waddr_2) && (we_2 == `WriteEnable) && (re2_2 == `ReadEnable)) + rdata2_2 = wdata_2; + else if (re2_1 == `ReadEnable) + rdata2_2 = regs[raddr2_2]; else - rdata2 = `ZeroWord; + rdata2_2 = `ZeroWord; end endmodule From cdd02e39fa9751bdcbc4fcc768b3ec913fb63c67 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Sun, 3 Apr 2022 19:59:43 +0800 Subject: [PATCH 008/114] fix: fix difftest --- .gitignore | 1 + src/SimTop.v | 6 +++--- src/vsrc/ctrl.v | 4 ++-- src/vsrc/pipeline/4_mem/mem_wb.v | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 07cf18a..07966ec 100644 --- a/.gitignore +++ b/.gitignore @@ -30,4 +30,5 @@ src/lock-emu src/time.log la32-nemu-interpreter-so test/*.bin +test/*.s build/ \ No newline at end of file diff --git a/src/SimTop.v b/src/SimTop.v index 52655a6..31d213e 100644 --- a/src/SimTop.v +++ b/src/SimTop.v @@ -17,7 +17,7 @@ module SimTop( wire chip_enable; wire[`RegBus] ram_raddr; - wire[`RegBus] ram_rdata; + reg[`RegBus] ram_rdata; wire[`RegBus] ramhelper_rdata; wire[`RegBus] ram_waddr; wire[`RegBus] ram_wdata; @@ -139,7 +139,7 @@ module SimTop( else begin cycleCnt <= cycleCnt + 1; - instrCnt <= instrCnt + debug_commit_valid_1; + instrCnt <= instrCnt + debug_commit_valid; debug_commit_instr_1 <= debug_commit_instr; debug_commit_valid_1 <= debug_commit_valid & chip_enable; debug_commit_pc_1 <= debug_commit_pc; @@ -176,7 +176,7 @@ module SimTop( .coreid(coreid), .index(index), .valid(debug_commit_valid_1), // Non-zero means valid, checked per-cycle, if valid, instr count as as commit - .pc(debug_commit_pc), + .pc(debug_commit_pc_1), .instr(debug_commit_instr_1), .skip(), .is_TLBFILL(), diff --git a/src/vsrc/ctrl.v b/src/vsrc/ctrl.v index 12d6645..cd7142a 100644 --- a/src/vsrc/ctrl.v +++ b/src/vsrc/ctrl.v @@ -41,13 +41,13 @@ module ctrl ( begin flush <= 1'b0; new_pc <= `ZeroWord; - stall <= 7'b0011111; + stall <= 7'b0111111; end else if(stallreq_from_ex == `Stop) begin flush <= 1'b0; new_pc <= `ZeroWord; - stall <= 7'b0011111; + stall <= 7'b0111111; end else begin diff --git a/src/vsrc/pipeline/4_mem/mem_wb.v b/src/vsrc/pipeline/4_mem/mem_wb.v index 14a29dd..18fbb1f 100644 --- a/src/vsrc/pipeline/4_mem/mem_wb.v +++ b/src/vsrc/pipeline/4_mem/mem_wb.v @@ -61,7 +61,7 @@ module mem_wb ( begin debug_commit_pc <= `ZeroWord; debug_commit_instr <= `ZeroWord; - debug_commit_valid <= `InstInvalid; + debug_commit_valid <= ~`InstInvalid; end else begin From bbdbcc52db4d222515ff0d21dfe45209765e6469 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Sun, 3 Apr 2022 20:31:08 +0800 Subject: [PATCH 009/114] fix: fix addi.w, slt, sltu, etc. --- src/vsrc/pipeline/2_decode/id.v | 6 +++--- src/vsrc/pipeline/3_execution/ex.v | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/vsrc/pipeline/2_decode/id.v b/src/vsrc/pipeline/2_decode/id.v index 2ffcfa6..9d52494 100644 --- a/src/vsrc/pipeline/2_decode/id.v +++ b/src/vsrc/pipeline/2_decode/id.v @@ -449,7 +449,7 @@ module id( alusel_o = `EXE_RES_ARITH; reg1_read_o = 1'b1; reg2_read_o = 1'b0; - imm = {20'h0, imm_12}; + imm = {{20{imm_12[11]}}, imm_12}; // Signed Extension reg_waddr_o = op1; inst_valid = `InstValid; end @@ -460,7 +460,7 @@ module id( alusel_o = `EXE_RES_ARITH; reg1_read_o = 1'b1; reg2_read_o = 1'b0; - imm = {20'h0, imm_12}; + imm = {{20{imm_12[11]}}, imm_12}; // Signed Extension reg_waddr_o = op1; inst_valid = `InstValid; end @@ -471,7 +471,7 @@ module id( alusel_o = `EXE_RES_ARITH; reg1_read_o = 1'b1; reg2_read_o = 1'b0; - imm = {20'h0, imm_12}; + imm = {{20{imm_12[11]}}, imm_12}; // Signed Extension reg_waddr_o = op1; inst_valid = `InstValid; end diff --git a/src/vsrc/pipeline/3_execution/ex.v b/src/vsrc/pipeline/3_execution/ex.v index 3e54728..1d9e8d7 100644 --- a/src/vsrc/pipeline/3_execution/ex.v +++ b/src/vsrc/pipeline/3_execution/ex.v @@ -112,10 +112,10 @@ module ex ( wire[`RegBus] reg1_i_mux; wire[`RegBus] result_compare; - assign reg2_i_mux = (aluop_i == `EXE_SLT_OP) ? (~reg2_i)+1 : reg2_i; - assign reg1_i_mux = (aluop_i == `EXE_SLT_OP) ? (~reg1_i)+1 : reg1_i; + assign reg2_i_mux = (aluop_i == `EXE_SLT_OP) ? {~reg2_i[`RegWidth-1], reg2_i[`RegWidth-2:0]} : reg2_i; // shifted encoding when signed comparison + assign reg1_i_mux = (aluop_i == `EXE_SLT_OP) ? {~reg1_i[`RegWidth-1], reg1_i[`RegWidth-2:0]} : reg1_i; assign result_compare = reg1_i + reg2_i_mux; - assign reg1_lt_reg2 = (reg1_i < reg2_i); + assign reg1_lt_reg2 = (reg1_i_mux < reg2_i_mux); //乘法模块 From 33f43065ff10b3e30c71c006b1645e8bda7167ac Mon Sep 17 00:00:00 2001 From: Rookie <74707760+Rookie-Cai-niao@users.noreply.github.com> Date: Mon, 4 Apr 2022 11:21:38 +0800 Subject: [PATCH 010/114] a new branch for dualissue --- src/vsrc/pipeline/pipeline_top.v | 325 +++++++++++++++++++++++++++++++ 1 file changed, 325 insertions(+) create mode 100644 src/vsrc/pipeline/pipeline_top.v diff --git a/src/vsrc/pipeline/pipeline_top.v b/src/vsrc/pipeline/pipeline_top.v new file mode 100644 index 0000000..99c431b --- /dev/null +++ b/src/vsrc/pipeline/pipeline_top.v @@ -0,0 +1,325 @@ +`include "../defines.v" +`include "1_fetch/if_id.v" +`include "2_decode/id.v" +`include "2_decode/id_ex.v" +`include "3_execution/ex.v" +`include "3_execution/ex_mem.v" +`include "4_mem/mem.v" +`include "4_mem/mem_wb.v" + +module cpu_top ( + input wire clk, + input wire rst, + input wire[`RegBus] dram_data_i, + input wire[`RegBus] ram_rdata_i, + + output wire[`RegBus] ram_raddr_o, + output wire[`RegBus] ram_wdata_o, + output wire[`RegBus] ram_waddr_o, + output wire ram_wen_o, + output wire ram_en_o, + + output wire[`RegBus] dram_addr_o, + output wire[`RegBus] dram_data_o, + output wire dram_we_o, + output wire[3:0] dram_sel_o, + output wire dram_ce_o, + + output wire[`RegBus] debug_commit_pc, + output wire debug_commit_valid, + output wire[`InstBus] debug_commit_instr, + output wire debug_commit_wreg, + output wire[`RegAddrBus] debug_commit_reg_waddr, + output wire[`RegBus] debug_commit_reg_wdata, + output wire[1023:0] debug_reg, + output wire Instram_branch_flag + ); + + wire[`InstAddrBus] pc; + wire chip_enable; + + assign ram_en_o = chip_enable; + assign ram_raddr_o = pc; + + wire branch_flag; + assign Instram_branch_flag=branch_flag; + wire[`RegBus] branch_target_address; + wire[`RegBus] link_addr; + + wire [`InstAddrBus]pc2; + if_buffer if_buffer_1( + .clk(clk), + .rst(rst), + .pc_i(pc), + .branch_flag_i(branch_flag), + .pc_valid(if_inst_valid), + .pc_o(pc2) + ); + + + wire[`InstAddrBus] id_pc; + wire[`InstBus] id_inst; + wire if_inst_valid; + + // wire if_id_instr_invalid; + if_id u_if_id( + .clk(clk), + .rst(rst), + .if_pc_i(pc2), + .if_inst_i(ram_rdata_i), + .id_pc_o(id_pc), + .id_inst_o(id_inst), + .if_inst_valid(if_inst_valid), + .branch_flag_i(branch_flag) + ); + + wire[`AluOpBus] id_aluop; + wire[`AluSelBus] id_alusel; + wire[`RegBus] id_reg1; + wire[`RegBus] id_reg2; + wire[`RegAddrBus] id_reg_waddr; + wire id_wreg; + wire id_inst_valid; + wire[`InstAddrBus] id_inst_pc; + wire[`RegBus] id_inst_o; + + wire reg1_read; + wire reg2_read; + wire[`RegAddrBus] reg1_addr; + wire[`RegAddrBus] reg2_addr; + wire[`RegBus] reg1_data; + wire[`RegBus] reg2_data; + + wire ex_wreg_o; + wire[`RegAddrBus] ex_reg_waddr_o; + wire[`RegBus] ex_reg_wdata; + wire[`AluOpBus] ex_aluop_o; + + wire mem_wreg_o; + wire[`RegAddrBus] mem_reg_waddr_o; + wire[`RegBus] mem_reg_wdata_o; + + wire stallreq_from_id; + + + id u_id( + .rst(rst), + .pc_i(id_pc), + .inst_i(id_inst), + + .reg1_data_i (reg1_data ), + .reg2_data_i (reg2_data ), + + .ex_wreg_i (ex_wreg_o ), + .ex_waddr_i (ex_reg_waddr_o), + .ex_wdata_i (ex_reg_wdata), + .ex_aluop_i (ex_aluop_o), + + .mem_wreg_i (mem_wreg_o), + .mem_waddr_i (mem_reg_waddr_o), + .mem_wdata_i (mem_reg_wdata_o), + + .reg1_read_o (reg1_read ), + .reg2_read_o (reg2_read ), + + .reg1_addr_o (reg1_addr ), + .reg2_addr_o (reg2_addr ), + + .aluop_o (id_aluop ), + .alusel_o (id_alusel ), + .reg1_o (id_reg1 ), + .reg2_o (id_reg2 ), + .reg_waddr_o (id_reg_waddr ), + .wreg_o (id_wreg ), + .inst_valid(id_inst_valid), + .inst_pc(id_inst_pc), + .inst_o(id_inst_o), + + .branch_flag_o(branch_flag), + .branch_target_address_o(branch_target_address), + .link_addr_o(link_addr), + + .stallreq(stallreq_from_id) + ); + + wire[`AluOpBus] ex_aluop; + wire[`AluSelBus] ex_alusel; + wire[`RegBus] ex_reg1; + wire[`RegBus] ex_reg2; + wire[`RegAddrBus] ex_reg_waddr_i; + wire ex_wreg_i; + wire ex_inst_valid_i; + wire[`InstAddrBus] ex_inst_pc_i; + wire[`RegBus] ex_link_address; + wire[`RegBus] ex_inst_i; + + id_ex id_ex0( + .clk(clk), + .rst(rst), + + .id_aluop(id_aluop), + .id_alusel(id_alusel), + .id_reg1(id_reg1), + .id_reg2(id_reg2), + .id_wd(id_reg_waddr), + .id_wreg(id_wreg), + .id_inst_pc(id_inst_pc), + .id_inst_valid(id_inst_valid), + .id_link_address(link_addr), + .id_inst(id_inst_o), + + .ex_aluop(ex_aluop), + .ex_alusel(ex_alusel), + .ex_reg1(ex_reg1), + .ex_reg2(ex_reg2), + .ex_wd(ex_reg_waddr_i), + .ex_wreg(ex_wreg_i), + .ex_inst_pc(ex_inst_pc_i), + .ex_inst_valid(ex_inst_valid_i), + .ex_link_address(ex_link_address), + .ex_inst(ex_inst_i) + ); + + + wire ex_inst_valid_o; + wire[`InstAddrBus] ex_inst_pc_o; + wire[`RegBus] ex_addr_o; + wire[`RegBus] ex_reg2_o; + + ex u_ex( + .rst(rst), + + .aluop_i(ex_aluop), + .alusel_i(ex_alusel), + .reg1_i(ex_reg1), + .reg2_i(ex_reg2), + .wd_i(ex_reg_waddr_i), + .wreg_i(ex_wreg_i), + .inst_valid_i(ex_inst_valid_i), + .inst_pc_i(ex_inst_pc_i), + .inst_i(ex_inst_i), + .link_addr_i(ex_link_address), + + .wd_o(ex_reg_waddr_o), + .wreg_o(ex_wreg_o), + .wdata_o(ex_reg_wdata), + .inst_valid_o(ex_inst_valid_o), + .inst_pc_o(ex_inst_pc_o), + .aluop_o(ex_aluop_o), + .mem_addr_o(ex_addr_o), + .reg2_o(ex_reg2_o) + ); + + + wire mem_wreg_i; + wire[`RegAddrBus] mem_reg_waddr_i; + wire[`RegBus] mem_reg_wdata_i; + + wire mem_inst_valid; + wire[`InstAddrBus] mem_inst_pc; + + wire[`AluOpBus] mem_aluop_i; + wire[`RegBus] mem_addr_i; + wire[`RegBus] mem_reg2_i; + + ex_mem u_ex_mem( + .clk(clk ), + .rst(rst ), + + .ex_wd (ex_reg_waddr_o ), + .ex_wreg (ex_wreg_o ), + .ex_wdata (ex_reg_wdata ), + .ex_inst_pc(ex_inst_pc_o), + .ex_inst_valid(ex_inst_valid_o), + .ex_aluop(ex_aluop_o), + .ex_mem_addr(ex_addr_o), + .ex_reg2(ex_reg2_o), + + .mem_wd(mem_reg_waddr_i ), + .mem_wreg(mem_wreg_i ), + .mem_wdata(mem_reg_wdata_i ), + .mem_inst_valid(mem_inst_valid), + .mem_inst_pc(mem_inst_pc), + .mem_aluop(mem_aluop_i), + .mem_mem_addr(mem_addr_i), + .mem_reg2(mem_reg2_i) + ); + + wire LLbit_o; + wire wb_LLbit_we_i; + wire wb_LLbit_value_i; + wire mem_LLbit_we_o; + wire mem_LLbit_value_o; + + mem u_mem( + .rst (rst ), + + .wd_i (mem_reg_waddr_i ), + .wreg_i (mem_wreg_i ), + .wdata_i (mem_reg_wdata_i), + .aluop_i(mem_aluop_i), + .mem_addr_i(mem_addr_i), + .reg2_i(mem_reg2_i), + + .mem_data_i(dram_data_i), + + .LLbit_i(LLbit_o), + .wb_LLbit_we_i(wb_LLbit_we_i), + .wb_LLbit_value_i(wb_LLbit_value_i), + + + .wd_o (mem_reg_waddr_o), + .wreg_o (mem_wreg_o ), + .wdata_o (mem_reg_wdata_o ), + + .mem_addr_o(dram_addr_o), + .mem_we_o(dram_we_o), + .mem_sel_o(dram_sel_o), + .mem_data_o(dram_data_o), + .mem_ce_o(dram_ce_o), + + .LLbit_we_o(mem_LLbit_we_o), + .LLbit_value_o(mem_LLbit_value_o) + + ); + + + wire wb_wreg; + wire[`RegAddrBus] wb_reg_waddr; + wire[`RegBus] wb_reg_wdata; + + assign debug_commit_wreg = wb_wreg; + assign debug_commit_reg_waddr = wb_reg_waddr; + assign debug_commit_reg_wdata = wb_reg_wdata; + + + + mem_wb mem_wb0( + .clk(clk), + .rst(rst), + + .mem_wd(mem_reg_waddr_o), + .mem_wreg(mem_wreg_o), + .mem_wdata(mem_reg_wdata_o), + .mem_inst_pc (mem_inst_pc ), + .mem_instr ( ), + .mem_inst_valid (mem_inst_valid ), + + .mem_LLbit_we(mem_LLbit_we_o), + .mem_LLbit_value(mem_LLbit_value_o), + + .wb_wd(wb_reg_waddr), + .wb_wreg(wb_wreg), + .wb_wdata(wb_reg_wdata), + + .wb_LLbit_we(wb_LLbit_we_i), + .wb_LLbit_value(wb_LLbit_value_i), + + .debug_commit_pc (debug_commit_pc ), + .debug_commit_valid (debug_commit_valid ), + .debug_commit_instr (debug_commit_instr ) + ); + + + +endmodule \ No newline at end of file From 981bc10a098806ad5a6b8fae62e8ad639ebee8e2 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Mon, 4 Apr 2022 16:39:27 +0800 Subject: [PATCH 011/114] feat: init TAGE bpu code --- src/vsrc/branch_predictor/btb.v | 58 +++++++++ src/vsrc/branch_predictor/defines.v | 24 ++++ src/vsrc/branch_predictor/gshared_predictor.v | 96 +++++++++++++++ src/vsrc/branch_predictor/tage_predictor.v | 113 ++++++++++++++++++ 4 files changed, 291 insertions(+) create mode 100644 src/vsrc/branch_predictor/btb.v create mode 100644 src/vsrc/branch_predictor/defines.v create mode 100644 src/vsrc/branch_predictor/gshared_predictor.v create mode 100644 src/vsrc/branch_predictor/tage_predictor.v diff --git a/src/vsrc/branch_predictor/btb.v b/src/vsrc/branch_predictor/btb.v new file mode 100644 index 0000000..bb65c97 --- /dev/null +++ b/src/vsrc/branch_predictor/btb.v @@ -0,0 +1,58 @@ +// Branch Target Buffer +`include "branch_predictor/defines.v" +`include "../defines.v" + + +module btb ( + input wire clk, + input wire rst, + input wire [`RegBus] query_pc_i, + + // Update signals + input wire update_valid, + input wire [`RegBus] update_pc_i, + input wire [`RegBus] update_branch_target_i, + + output wire [`RegBus] branch_target_address_o, + output wire btb_hit + ); + + + /** A entry in BTB looks like this: + [tag[`BTB_TAG_LENGTH], target[30]] + - target: target[31:2], lower 2bit is usually 0 + */ + reg [`BTB_ENTRY_BUS] btb_entries[`BTB_DEPTH]; + + + // Query logic //////////////////////////////////// + + // pc_i[2+2x`BTB_DEPTH_LOG2:2] is first hashed into `BTB_DEPTH_LOG2 as an index + // use a 2-stage XOR for now + wire[`BTB_DEPTH_LOG2-1:0] query_hashed_index = (query_pc_i[`BTB_DEPTH_LOG2+1:2] ^ query_pc_i[`BTB_DEPTH_LOG2+`BTB_DEPTH_LOG2+1:`BTB_DEPTH_LOG2+2]) ^ query_pc_i[`BTB_DEPTH_LOG2+1:2]; + + // Extract the entry + wire[`BTB_ENTRY_BUS] btb_entry = btb_entries[query_hashed_index]; + + // Mark hit flag, use the lower bits of query_pc_i as tag + assign btb_hit = (btb_entry[`BTB_ENTRY_LENGTH-1:`BTB_ENTRY_LENGTH-`BTB_TAG_LENGTH] == query_pc_i[`BTB_TAG_LENGTH+1:2]); + + // Output branch_target_address_o if btb_hit + assign branch_target_address_o = btb_hit ? {btb_entry[`BTB_ENTRY_LENGTH-`BTB_TAG_LENGTH-1:0],2'b0} : 32'b0; + + + // Update logic ///////////////////////////////// + + // Also hashed in the same way as query_hashed_index + wire[`BTB_DEPTH_LOG2-1:0] update_hashed_index = (update_pc_i[`BTB_DEPTH_LOG2+1:2] ^ update_pc_i[`BTB_DEPTH_LOG2+`BTB_DEPTH_LOG2+1:`BTB_DEPTH_LOG2+2]) ^ update_pc_i[`BTB_DEPTH_LOG2+1:2]; + + // update each cycle + always @(posedge clk) + begin + if (update_valid) + begin + btb_entries[update_hashed_index] <= {btb_entry[`BTB_ENTRY_LENGTH-1:`BTB_ENTRY_LENGTH-`BTB_TAG_LENGTH],update_branch_target_i[`RegWidth-1:2]}; + end + end + +endmodule diff --git a/src/vsrc/branch_predictor/defines.v b/src/vsrc/branch_predictor/defines.v new file mode 100644 index 0000000..4743dd0 --- /dev/null +++ b/src/vsrc/branch_predictor/defines.v @@ -0,0 +1,24 @@ +`ifndef DEFINES_V + +// BTB parameters +`define BTB_DEPTH 64 +`define BTB_DEPTH_LOG2 6 +`define BTB_TAG_LENGTH 12 +`define BTB_ENTRY_LENGTH `BTB_TAG_LENGTH + 30 // tag[], target[30] +`define BTB_ENTRY_BUS `BTB_ENTRY_LENGTH-1:0 + +// PHT parameters (Pattern History Table) +`define PHT_DEPTH 64 +`define PHT_DEPTH_LOG2 6 + + +// GHR parameters (Global History Register) +`define GHR_DEPTH 40 +`define GHR_BUS `GHR_DEPTH-1:0 +`define MAX_GHT_LENGTH 512 +`define MAX_GHT_LENGTH_LOG2 9 + +// Parameters +`define FEEDBACK_LATENCY 2 + +`endif diff --git a/src/vsrc/branch_predictor/gshared_predictor.v b/src/vsrc/branch_predictor/gshared_predictor.v new file mode 100644 index 0000000..1e75362 --- /dev/null +++ b/src/vsrc/branch_predictor/gshared_predictor.v @@ -0,0 +1,96 @@ +// Gshared predictor as base predictor +`include "../defines.v" +`include "branch_predictor/defines.v" + + +module gshared_predictor #( + parameter GLOBAL_HISTORY_LENGTH = 4 + ) ( + input wire clk, + input wire rst, + input wire [`GHR_BUS] global_history_i, + input wire [`RegBus] pc_i, + + // Update signals + input wire branch_valid, + input wire branch_taken, + + output wire taken + ); + + // PHT, each entry is a bimodal predictor + reg[1:0] PHT[`PHT_DEPTH]; + + wire [`MAX_GHT_LENGTH-1:0] global_history_hashing[`MAX_GHT_LENGTH_LOG2]; + // Concat GHT input to desired length + assign global_history_hashing[0] = {{(`MAX_GHT_LENGTH - GLOBAL_HISTORY_LENGTH){1'b0}}, global_history_i[GLOBAL_HISTORY_LENGTH-1:0]}; + // Fold GHT input from `MAX_GHT_LENGTH to 1 + genvar i; + generate + for (i = `MAX_GHT_LENGTH_LOG2-1; i >1; i = i-1) + begin + wire [`MAX_GHT_LENGTH-1:0] global_history_hashing_folder = global_history_hashing[`MAX_GHT_LENGTH_LOG2-1-i]; + + wire [`MAX_GHT_LENGTH-1:0] op1 = {{(`MAX_GHT_LENGTH-2**i){1'b0}},global_history_hashing_folder[2**i-1:0]}; + wire [`MAX_GHT_LENGTH-1:0] op2 ={{(`MAX_GHT_LENGTH-2**i){1'b0}},global_history_hashing_folder[2**i*2-1:2**i]}; + + assign global_history_hashing[`MAX_GHT_LENGTH_LOG2-i] = op1 ^ op2; + end + endgenerate + // Select 8 as index + wire [7:0] hashed_ght_input = global_history_hashing[`MAX_GHT_LENGTH - 4][7:0]; + + // hash with pc, and concatenate to `PHT_DEPTH_LOG2 + wire [`PHT_DEPTH_LOG2-1:0] query_hashed_index = {hashed_ght_input ^ pc_i[9:2]}[`PHT_DEPTH_LOG2-1:0]; + + // Query logic ////////////////////////////////// + wire [1:0] query_entry = PHT[query_hashed_index]; + assign taken = (query_entry == 2'b11) | (query_entry == 2'b01); + + // Update logic ////////////////////////////////// + + // This buffer is used to store the hashed index for update + reg[`PHT_DEPTH_LOG2-1:0] hashed_index_buffer [`FEEDBACK_LATENCY]; + always @(posedge clk) + begin + hashed_index_buffer[0] <= query_hashed_index; + end + genvar index_id; + generate + for (index_id = 1; index_id < `FEEDBACK_LATENCY; index_id = index_id + 1) + begin + always @(posedge clk) + begin + hashed_index_buffer[index_id] <= hashed_index_buffer[index_id - 1]; + end + end + endgenerate + + // Select index from buffer and update + wire [`PHT_DEPTH_LOG2-1:0] update_index = hashed_index_buffer[`FEEDBACK_LATENCY-1]; + always @(posedge clk) + begin + if (branch_valid) + begin + case (PHT[update_index]) // 00,10 | 01,11 + 2'b00: + begin + PHT[update_index] <= branch_taken ? 2'b10: 2'b00; + end + 2'b10: + begin + PHT[update_index] <= branch_taken ? 2'b01: 2'b00; + end + 2'b01: + begin + PHT[update_index] <= branch_taken ? 2'b11: 2'b10; + end + 2'b11: + begin + PHT[update_index] <= branch_taken ? 2'b11: 2'b01; + end + endcase + end + end + +endmodule diff --git a/src/vsrc/branch_predictor/tage_predictor.v b/src/vsrc/branch_predictor/tage_predictor.v new file mode 100644 index 0000000..55dfaa6 --- /dev/null +++ b/src/vsrc/branch_predictor/tage_predictor.v @@ -0,0 +1,113 @@ +// TAGE predictor +// This is the main predictor + +`include "../defines.v" +`include "branch_predictor/defines.v" + + +module tage_predictor ( + input wire clk, + input wire rst, + input wire [`RegBus] pc_i, + + // Update signals + input wire branch_valid_i, + input wire branch_taken_i, + input wire [`RegBus] branch_pc_i, + input wire [`RegBus] branch_target_address_i, + + // Prediction + output wire [`RegBus] predicted_branch_target_o, + output wire predict_valid + ); + + // Global History Register + reg [`GHR_BUS] GHR; + always @(posedge clk) + begin + if (branch_valid_i) + begin + // Shift left for every valid branch + GHR <= {GHR[`GHR_DEPTH-2:0],branch_taken_i}; + end + end + + + // BTB + wire btb_hit; + btb u_btb( + .clk (clk ), + .rst (rst ), + .query_pc_i (pc_i ), + .update_valid (branch_valid_i ), + .update_pc_i (branch_pc_i ), + .update_branch_target_i (branch_target_address_i ), + .branch_target_address_o (predicted_branch_target_o ), + .btb_hit (btb_hit ) + ); + + + + // Tagged Predictors + wire t1_taken; + wire t2_taken; + wire t3_taken; + wire t4_taken; + + gshared_predictor + #( + .GLOBAL_HISTORY_LENGTH (5) + ) + t1( + .clk (clk ), + .rst (rst ), + .global_history_i (GHR ), + .pc_i (pc_i ), + .branch_valid (branch_valid_i ), + .branch_taken (branch_taken_i ), + .taken (t1_taken ) + ); + + gshared_predictor + #( + .GLOBAL_HISTORY_LENGTH (10) + ) + t2( + .clk (clk ), + .rst (rst ), + .global_history_i (GHR ), + .pc_i (pc_i ), + .branch_valid (branch_valid_i ), + .branch_taken (branch_taken_i ), + .taken (t2_taken ) + ); + + gshared_predictor + #( + .GLOBAL_HISTORY_LENGTH (20) + ) + t3( + .clk (clk ), + .rst (rst ), + .global_history_i (GHR ), + .pc_i (pc_i ), + .branch_valid (branch_valid_i ), + .branch_taken (branch_taken_i ), + .taken (t3_taken ) + ); + + gshared_predictor + #( + .GLOBAL_HISTORY_LENGTH (40) + ) + t4( + .clk (clk ), + .rst (rst ), + .global_history_i (GHR ), + .pc_i (pc_i ), + .branch_valid (branch_valid_i ), + .branch_taken (branch_taken_i ), + .taken (t4_taken ) + ); + +endmodule //tage_predictor From 674f5cdb815267baa12bf21606436b702a0c7f0f Mon Sep 17 00:00:00 2001 From: Rookie <74707760+Rookie-Cai-niao@users.noreply.github.com> Date: Thu, 7 Apr 2022 21:12:17 +0800 Subject: [PATCH 012/114] add dualissue data related --- src/SimTop.v | 6 ++ src/data_ram.v | 59 +++++++++------ src/vsrc/cpu_top.v | 94 +++++++++++++++++------- src/vsrc/cs_reg.v | 94 ++++++++++++++++++++++++ src/vsrc/csr_defines.v | 100 ++++++++++++++++++++++++++ src/vsrc/pipeline/1_fetch/if_buffer.v | 44 ++++++++++++ src/vsrc/pipeline/2_decode/id.v | 89 ++++++++++++++++------- src/vsrc/pipeline/4_mem/mem.v | 4 ++ src/vsrc/regfile.v | 20 ++++-- 9 files changed, 432 insertions(+), 78 deletions(-) create mode 100644 src/vsrc/cs_reg.v create mode 100644 src/vsrc/csr_defines.v create mode 100644 src/vsrc/pipeline/1_fetch/if_buffer.v diff --git a/src/SimTop.v b/src/SimTop.v index 5408cc9..3bda228 100644 --- a/src/SimTop.v +++ b/src/SimTop.v @@ -31,6 +31,7 @@ module SimTop( wire[3:0] dram_sel_1; wire[`DataBus] dram_data_i_1; wire[`DataBus] dram_data_o_1; + wire[`InstAddrBus] dram_pc_1; wire dram_ce_2; wire dram_we_2; @@ -38,6 +39,7 @@ module SimTop( wire[3:0] dram_sel_2; wire[`DataBus] dram_data_i_2; wire[`DataBus] dram_data_o_2; + wire[`InstAddrBus] dram_pc_2; wire [`RegBus] debug_commit_pc_o_1; wire debug_commit_valid_o_1; @@ -74,12 +76,14 @@ module SimTop( .dram_we_o_1(dram_we_1), .dram_sel_o_1(dram_sel_1), .dram_ce_o_1(dram_ce_1), + .dram_pc_o_1(dram_pc_1), .dram_addr_o_2(dram_addr_2), .dram_data_o_2(dram_data_i_2), .dram_we_o_2(dram_we_2), .dram_sel_o_2(dram_sel_2), .dram_ce_o_2(dram_ce_2), + .dram_pc_o_2(dram_pc_2), .debug_commit_pc_1(debug_commit_pc_o_1 ), .debug_commit_valid_1(debug_commit_valid_o_1 ), @@ -129,12 +133,14 @@ module SimTop( .clk(clock), .ce_1(dram_ce_1), .we_1(dram_we_1), + .pc_1(dram_pc_1), .addr_1(dram_addr_1), .sel_1(dram_sel_1), .data_i_1(dram_data_i_1), .data_o_1(dram_data_o_1), .ce_2(dram_ce_2), .we_2(dram_we_2), + .pc_2(dram_pc_2), .addr_2(dram_addr_2), .sel_2(dram_sel_2), .data_i_2(dram_data_i_2), diff --git a/src/data_ram.v b/src/data_ram.v index 8c8ff8b..becfed2 100644 --- a/src/data_ram.v +++ b/src/data_ram.v @@ -5,6 +5,7 @@ module data_ram( input wire ce_1, input wire we_1, + input wire[`InstAddrBus] pc_1, input wire[`DataAddrBus] addr_1, input wire[3:0] sel_1, input wire[`DataBus] data_i_1, @@ -12,6 +13,7 @@ module data_ram( input wire ce_2, input wire we_2, + input wire[`InstAddrBus] pc_2, input wire[`DataAddrBus] addr_2, input wire[3:0] sel_2, input wire[`DataBus] data_i_2, @@ -26,33 +28,36 @@ module data_ram( always @ (posedge clk) begin - if (ce_1 == `ChipDisable) + if (ce_1 == `ChipEnable) begin + if(we_1 == `WriteEnable) + begin + if (sel_1[3] == 1'b1) + data_mem3[addr_1[`DataMemNumLog2+1:2]] <= data_i_1[31:24]; + if (sel_1[2] == 1'b1) + data_mem2[addr_1[`DataMemNumLog2+1:2]] <= data_i_1[23:16]; + if (sel_1[1] == 1'b1) + data_mem1[addr_1[`DataMemNumLog2+1:2]] <= data_i_1[15:8]; + if (sel_1[0] == 1'b1) + data_mem0[addr_1[`DataMemNumLog2+1:2]] <= data_i_1[7:0]; + end end - else if(we_1 == `WriteEnable) + if(ce_2 == `ChipEnable) begin - if (sel_1[3] == 1'b1) - data_mem3[addr_1[`DataMemNumLog2+1:2]] <= data_i_1[31:24]; - if (sel_1[2] == 1'b1) - data_mem2[addr_1[`DataMemNumLog2+1:2]] <= data_i_1[23:16]; - if (sel_1[1] == 1'b1) - data_mem1[addr_1[`DataMemNumLog2+1:2]] <= data_i_1[15:8]; - if (sel_1[0] == 1'b1) - data_mem0[addr_1[`DataMemNumLog2+1:2]] <= data_i_1[7:0]; + if(we_2 == `WriteEnable) + begin + if (sel_2[3] == 1'b1) + data_mem3[addr_2[`DataMemNumLog2+1:2]] <= data_i_2[31:24]; + if (sel_2[2] == 1'b1) + data_mem2[addr_2[`DataMemNumLog2+1:2]] <= data_i_2[23:16]; + if (sel_2[1] == 1'b1) + data_mem1[addr_2[`DataMemNumLog2+1:2]] <= data_i_2[15:8]; + if (sel_2[0] == 1'b1) + data_mem0[addr_2[`DataMemNumLog2+1:2]] <= data_i_2[7:0]; + end end end - always @ (posedge clk) - begin - if (ce_1 == `ChipDisable) - data_o_1 <= `ZeroWord; - else - data_o_1 <= {data_mem3[addr_1[`DataMemNumLog2+1:2]], - data_mem2[addr_1[`DataMemNumLog2+1:2]], - data_mem1[addr_1[`DataMemNumLog2+1:2]], - data_mem0[addr_1[`DataMemNumLog2+1:2]]}; - - end always @ (posedge clk) begin @@ -72,6 +77,18 @@ module data_ram( end end + always @ (posedge clk) + begin + if (ce_1 == `ChipDisable) + data_o_1 <= `ZeroWord; + else + data_o_1 <= {data_mem3[addr_1[`DataMemNumLog2+1:2]], + data_mem2[addr_1[`DataMemNumLog2+1:2]], + data_mem1[addr_1[`DataMemNumLog2+1:2]], + data_mem0[addr_1[`DataMemNumLog2+1:2]]}; + + end + always @ (posedge clk) begin if (ce_2 == `ChipDisable) diff --git a/src/vsrc/cpu_top.v b/src/vsrc/cpu_top.v index 0ea9842..2ac7270 100644 --- a/src/vsrc/cpu_top.v +++ b/src/vsrc/cpu_top.v @@ -31,12 +31,14 @@ module cpu_top ( output wire dram_we_o_1, output wire[3:0] dram_sel_o_1, output wire dram_ce_o_1, + output wire[`InstAddrBus] dram_pc_o_1, output wire[`RegBus] dram_addr_o_2, output wire[`RegBus] dram_data_o_2, output wire dram_we_o_2, output wire[3:0] dram_sel_o_2, output wire dram_ce_o_2, + output wire[`InstAddrBus] dram_pc_o_2, output wire[`RegBus] debug_commit_pc_1, output wire debug_commit_valid_1, @@ -177,23 +179,49 @@ module cpu_top ( wire[1:0] id_excepttype_o_1; wire[`RegBus] id_current_inst_address_o_1; + wire ex_wreg_o_2; + wire[`RegAddrBus] ex_reg_waddr_o_2; + wire[`RegBus] ex_reg_wdata_2; + wire[`AluOpBus] ex_aluop_o_2; + + wire mem_wreg_o_2; + wire[`RegAddrBus] mem_reg_waddr_o_2; + wire[`RegBus] mem_reg_wdata_o_2; + + wire[`RegAddrBus] reg1_addr_2; + wire[`RegAddrBus] reg2_addr_2; + id u_id_1( .rst(rst), .pc_i(id_pc_1), .inst_i(id_inst_1), + .pc_i_other(id_pc_2), + .reg1_data_i (reg1_data_1 ), .reg2_data_i (reg2_data_1 ), - .ex_wreg_i (ex_wreg_o_1 ), - .ex_waddr_i (ex_reg_waddr_o_1), - .ex_wdata_i (ex_reg_wdata_1), - .ex_aluop_i (ex_aluop_o_1), + .reg1_addr_i_other(reg1_addr_2), + .reg2_addr_i_other(reg2_addr_2), - .mem_wreg_i (mem_wreg_o_1), - .mem_waddr_i (mem_reg_waddr_o_1), - .mem_wdata_i (mem_reg_wdata_o_1), + .ex_wreg_i_1 (ex_wreg_o_1 ), + .ex_waddr_i_1 (ex_reg_waddr_o_1), + .ex_wdata_i_1 (ex_reg_wdata_1), + .ex_aluop_i_1 (ex_aluop_o_1), + + .ex_wreg_i_2 (ex_wreg_o_2 ), + .ex_waddr_i_2 (ex_reg_waddr_o_2), + .ex_wdata_i_2 (ex_reg_wdata_2), + .ex_aluop_i_2 (ex_aluop_o_2), + + .mem_wreg_i_1 (mem_wreg_o_1), + .mem_waddr_i_1 (mem_reg_waddr_o_1), + .mem_wdata_i_1 (mem_reg_wdata_o_1), + + .mem_wreg_i_2 (mem_wreg_o_2), + .mem_waddr_i_2 (mem_reg_waddr_o_2), + .mem_wdata_i_2 (mem_reg_wdata_o_2), .reg1_read_o (reg1_read_1 ), .reg2_read_o (reg2_read_1 ), @@ -233,19 +261,10 @@ module cpu_top ( wire reg1_read_2; wire reg2_read_2; - wire[`RegAddrBus] reg1_addr_2; - wire[`RegAddrBus] reg2_addr_2; wire[`RegBus] reg1_data_2; wire[`RegBus] reg2_data_2; - wire ex_wreg_o_2; - wire[`RegAddrBus] ex_reg_waddr_o_2; - wire[`RegBus] ex_reg_wdata_2; - wire[`AluOpBus] ex_aluop_o_2; - - wire mem_wreg_o_2; - wire[`RegAddrBus] mem_reg_waddr_o_2; - wire[`RegBus] mem_reg_wdata_o_2; + wire stallreq_from_id_2; wire stallreq_from_ex_2; @@ -258,17 +277,31 @@ module cpu_top ( .pc_i(id_pc_2), .inst_i(id_inst_2), + .pc_i_other(id_pc_1), + .reg1_data_i (reg1_data_2 ), .reg2_data_i (reg2_data_2 ), - .ex_wreg_i (ex_wreg_o_2 ), - .ex_waddr_i (ex_reg_waddr_o_2), - .ex_wdata_i (ex_reg_wdata_2), - .ex_aluop_i (ex_aluop_o_2), + .reg1_addr_i_other(reg1_addr_1), + .reg2_addr_i_other(reg2_addr_1), + + .ex_wreg_i_1 (ex_wreg_o_2 ), + .ex_waddr_i_1 (ex_reg_waddr_o_2), + .ex_wdata_i_1 (ex_reg_wdata_2), + .ex_aluop_i_1 (ex_aluop_o_2), + + .ex_wreg_i_2 (ex_wreg_o_1 ), + .ex_waddr_i_2 (ex_reg_waddr_o_1), + .ex_wdata_i_2 (ex_reg_wdata_1), + .ex_aluop_i_2 (ex_aluop_o_1), - .mem_wreg_i (mem_wreg_o_2), - .mem_waddr_i (mem_reg_waddr_o_2), - .mem_wdata_i (mem_reg_wdata_o_2), + .mem_wreg_i_1 (mem_wreg_o_2), + .mem_waddr_i_1 (mem_reg_waddr_o_2), + .mem_wdata_i_1 (mem_reg_wdata_o_2), + + .mem_wreg_i_2 (mem_wreg_o_1), + .mem_waddr_i_2 (mem_reg_waddr_o_1), + .mem_wdata_i_2 (mem_reg_wdata_o_1), .reg1_read_o (reg1_read_2 ), .reg2_read_o (reg2_read_2 ), @@ -557,10 +590,12 @@ module cpu_top ( wire mem_LLbit_value_o_1; wire[1:0] mem_excepttype_o_1; wire[`RegBus] mem_current_inst_address_o_1; + wire[`InstAddrBus] wb_inst_pc_1; mem u_mem_1( .rst (rst ), + .inst_pc_i(mem_inst_pc_1), .wd_i (mem_reg_waddr_i_1 ), .wreg_i (mem_wreg_i_1 ), .wdata_i (mem_reg_wdata_i_1), @@ -577,7 +612,7 @@ module cpu_top ( .excepttype_i(mem_excepttype_i_1), .current_inst_address_i(mem_current_inst_address_i_1), - + .inst_pc_o(wb_inst_pc_1), .wd_o (mem_reg_waddr_o_1), .wreg_o (mem_wreg_o_1 ), .wdata_o (mem_reg_wdata_o_1 ), @@ -603,10 +638,12 @@ module cpu_top ( wire mem_LLbit_value_o_2; wire[1:0] mem_excepttype_o_2; wire[`RegBus] mem_current_inst_address_o_2 ; + wire[`InstAddrBus] wb_inst_pc_2; mem u_mem_2( .rst (rst ), + .inst_pc_i(mem_inst_pc_2), .wd_i (mem_reg_waddr_i_2 ), .wreg_i (mem_wreg_i_2 ), .wdata_i (mem_reg_wdata_i_2), @@ -623,7 +660,7 @@ module cpu_top ( .excepttype_i(mem_excepttype_i_2), .current_inst_address_i(mem_current_inst_address_i_2), - + .inst_pc_o(wb_inst_pc_2), .wd_o (mem_reg_waddr_o_2), .wreg_o (mem_wreg_o_2 ), .wdata_o (mem_reg_wdata_o_2 ), @@ -641,6 +678,9 @@ module cpu_top ( .current_inst_address_o(mem_current_inst_address_o_2) ); + + assign dram_pc_o_1 = wb_inst_pc_1; + assign dram_pc_o_2 = wb_inst_pc_2; wire wb_wreg_1; wire[`RegAddrBus] wb_reg_waddr_1; @@ -723,9 +763,11 @@ module cpu_top ( .rst(rst ), .we_1 (wb_wreg_1), + .pc_i_1 (), .waddr_1 (wb_reg_waddr_1), .wdata_1 (wb_reg_wdata_1), .we_2 (wb_wreg_2), + .pc_i_2 (), .waddr_2 (wb_reg_waddr_2), .wdata_2 (wb_reg_wdata_2), diff --git a/src/vsrc/cs_reg.v b/src/vsrc/cs_reg.v new file mode 100644 index 0000000..f3e00ae --- /dev/null +++ b/src/vsrc/cs_reg.v @@ -0,0 +1,94 @@ +`include "defines.v" +`include "csr_defines.v" +module cs_reg ( + input wire clk, + input wire rst, + + input wire[`AluOpBus] aluop_i, + input wire[13:0] csr_num, + input wire[1:0]exception_i, + + input wire we, + input wire[`RegBus] wdata, + + output reg[`RegBus] rdata +); + +reg [31:0] csr_crmd; +reg [31:0] csr_prmd; +reg [31:0] csr_ectl; +reg [31:0] csr_estat; +reg [31:0] csr_era; +reg [31:0] csr_badv; +reg [31:0] csr_eentry; +reg [31:0] csr_tlbidx; +reg [31:0] csr_tlbehi; +reg [31:0] csr_tlbelo0; +reg [31:0] csr_tlbelo1; +reg [31:0] csr_asid; +reg [31:0] csr_cpuid; +reg [31:0] csr_pgdl; +reg [31:0] csr_pgdh; + + +//crmd +always @(posedge clk) begin + if (rst) begin + csr_crmd[`PLV] <= 2'b0; + csr_crmd[`IE] <= 1'b0; + csr_crmd[`DA] <= 1'b1; + csr_crmd[`PG] <= 1'b0; + csr_crmd[`DATF] <= 2'b0; + csr_crmd[`DATM] <= 2'b0; + csr_crmd[31:9] <= 23'b0; + end + else if (excp_flush) begin + csr_crmd[`PLV] <= 2'b0; + csr_crmd[`IE] <= 1'b0; + if (excp_tlbrefill) begin + csr_crmd [`DA] <= 1'b1; + csr_crmd [`PG] <= 1'b0; + end + end + else if(exception_i)begin + csr_crmd[`PLV] <= csr_prmd[`PPLV]; + csr_crmd[`IE] <= csr_prmd[`PIE]; + if(eret_tlbrefill_excp)begin + csr_crmd[`DA] <= 1'b0; + csr_crmd[`PG] <= 1'b1; + end + end + else if (we == 1'b1 && csr_num == `CRMD) begin + csr_crmd[`PLV] <= wdata[`PLV]; + csr_crmd[`IE] <= wdata[`IE]; + csr_crmd[`DA] <= wdata[`DA]; + csr_crmd[`PG] <= wdata[`PG]; + csr_crmd[`DATF] <= wdata[`DATF]; + csr_crmd[`DATM] <= wdata[`DATM]; + end +end + +//prmd +always @(posedge clk) begin + if (rst) begin + csr_prmd[31:3] <= 29'b0; + end + else if (exception_i) begin + csr_prmd[`PPLV] <= csr_crmd[`PLV]; + csr_prmd[`PIE] <= csr_crmd[`IE]; + end + else if (we == 1'b1 && csr_num == `PRMD) begin + csr_prmd[`PPLV] <= wdata[`PPLV]; + csr_prmd[`PIE] <= wdata[`PIE]; + end +end + +//ectl +always @(posedge clk) begin + if (rst) + csr_ectl <= 32'b0; + else if(we == 1'b1 && csr_num == `ECTL) + csr_ectl[`LIE] <= wdata[`LIE]; +end + +endmodule \ No newline at end of file diff --git a/src/vsrc/csr_defines.v b/src/vsrc/csr_defines.v new file mode 100644 index 0000000..8234a79 --- /dev/null +++ b/src/vsrc/csr_defines.v @@ -0,0 +1,100 @@ +//CRMD +`define PLV 1:0 +`define IE 2 +`define DA 3 +`define PG 4 +`define DATF 6:5 +`define DATM 8:7 + +//PRMD +`define PPLV 1:0 +`define PIE 2 + +//ECTL +`define LIE 12:0 + +//ESTAT +`define IS 12:0 +`define ECODE 21:16 +`define ESUBCODE 30:22 + +//TLBIDX +`define INDEX 4:0 +`define PS 29:24 +`define NE 31 + +//TLBEHI +`define VPPN 31:13 + +//TLBELO +`define TLB_V 0 +`define TLB_D 1 +`define TLB_PLV 3:2 +`define TLB_MAT 5:4 +`define TLB_G 6 +`define TLB_PPN 31:8 +`define TLB_PPN_EN 27:8 + +//ASID +`define TLB_ASID 9:0 + +//CPUID +`define COREID 8:0 + +//LLBCTL +`define ROLLB 0 +`define WCLLB 1 +`define KLO 2 + +//TCFG +`define EN 0 +`define PERIODIC 1 +`define INITVAL 31:2 + +//TICLR +`define CLR 0 + +//TLBRENTRY +`define TLBRENTRY_PA 31:6 + +//DMW +`define PLV0 0 +`define PLV3 3 +`define DMW_MAT 5:4 +`define PSEG 27:25 +`define VSEG 31:29 + +//PGDL PGDH PGD +`define BASE 31:12 + +`define CRMD 14'h0 +`define PRMD 14'h1 +`define ECTL 14'h4 +`define ESTAT 14'h5 +`define ERA 14'h6 +`define BADV 14'h7 +`define EENTRY 14'hc +`define TLBIDX 14'h10 +`define TLBEHI 14'h11 +`define TLBELO014'h12 +`define TLBELO114'h13 +`define ASID 14'h18 +`define PGDL 14'h19 +`define PGDH 14'h1a +`define PGD 14'h1b +`define CPUID 14'h20 +`define SAVE0 14'h30 +`define SAVE1 14'h31 +`define SAVE2 14'h32 +`define SAVE3 14'h33 +`define TID 14'h40 +`define TCFG 14'h41 +`define TVAL 14'h42 +`define CNTC 14'h43 +`define TICLR 14'h44 +`define LLBCTL 14'h60 +`define TLBRENTRY 14'h88 +`define DMW0 14'h180 +`define DMW1 14'h181 +`define BRK 14'h100 +`define DISABLE_CACHE 14'h101 \ No newline at end of file diff --git a/src/vsrc/pipeline/1_fetch/if_buffer.v b/src/vsrc/pipeline/1_fetch/if_buffer.v new file mode 100644 index 0000000..052e01a --- /dev/null +++ b/src/vsrc/pipeline/1_fetch/if_buffer.v @@ -0,0 +1,44 @@ +//to keep PC and inst_o corresponding +`include "../../defines.v" +module if_buffer ( + input wire clk, + input wire rst, + input wire [`InstAddrBus] pc_i, + input wire flush, + input wire stall, + + input wire branch_flag_i, + output reg [`InstAddrBus] pc_o, + output reg pc_valid + ); + + always @(posedge clk) + begin + if(rst) + begin + pc_o <= `ZeroWord; + pc_valid <= `InstInvalid; + end + else if(branch_flag_i == `Branch) + begin + pc_o <= `ZeroWord; + pc_valid <= `InstInvalid; + end + else if(flush == 1'b1) + begin + pc_o <= `ZeroWord; + pc_valid <= `InstInvalid; + end + else if(stall == `Stop) // Stall, hold output + begin + pc_o <= pc_o; + pc_valid <= pc_valid; + end + else + begin + pc_o <= pc_i; + pc_valid <= `InstValid; + end + end + +endmodule diff --git a/src/vsrc/pipeline/2_decode/id.v b/src/vsrc/pipeline/2_decode/id.v index 2ffcfa6..107c72f 100644 --- a/src/vsrc/pipeline/2_decode/id.v +++ b/src/vsrc/pipeline/2_decode/id.v @@ -6,20 +6,39 @@ module id( input wire[`InstAddrBus] pc_i, input wire[`InstBus] inst_i, + // <- ANOTHER_IF + input wire[`InstAddrBus] pc_i_other, + // <- Regfile input wire[`RegBus] reg1_data_i, input wire[`RegBus] reg2_data_i, + // <- ANOTHER_ID + input wire[`RegAddrBus] reg1_addr_i_other, + input wire[`RegAddrBus] reg2_addr_i_other, + // <- EXE - input wire ex_wreg_i, - input wire[`RegAddrBus] ex_waddr_i, - input wire[`RegBus] ex_wdata_i, - input wire[`AluOpBus] ex_aluop_i, + input wire ex_wreg_i_1, + input wire[`RegAddrBus] ex_waddr_i_1, + input wire[`RegBus] ex_wdata_i_1, + input wire[`AluOpBus] ex_aluop_i_1, + + + // <- ANOTHER_EXE + input wire ex_wreg_i_2, + input wire[`RegAddrBus] ex_waddr_i_2, + input wire[`RegBus] ex_wdata_i_2, + input wire[`AluOpBus] ex_aluop_i_2, // <- Mem - input wire mem_wreg_i, - input wire[`RegAddrBus] mem_waddr_i, - input wire[`RegBus] mem_wdata_i, + input wire mem_wreg_i_1, + input wire[`RegAddrBus] mem_waddr_i_1, + input wire[`RegBus] mem_wdata_i_1, + + // <- ANOTHER_Mem + input wire mem_wreg_i_2, + input wire[`RegAddrBus] mem_waddr_i_2, + input wire[`RegBus] mem_wdata_i_2, // -> Regfile output reg reg1_read_o, @@ -83,14 +102,22 @@ module id( reg stallreq_for_reg2_loadrelate; wire pre_inst_is_load; - assign pre_inst_is_load = ((ex_aluop_i == `EXE_LD_B_OP) || - (ex_aluop_i == `EXE_LD_H_OP) || - (ex_aluop_i == `EXE_LD_W_OP) || - (ex_aluop_i == `EXE_LD_BU_OP) || - (ex_aluop_i == `EXE_LD_HU_OP) || - (ex_aluop_i == `EXE_ST_B_OP) || - (ex_aluop_i == `EXE_ST_H_OP) || - (ex_aluop_i == `EXE_ST_W_OP) ) ? 1'b1 : 1'b0; + assign pre_inst_is_load = (((ex_aluop_i_1 == `EXE_LD_B_OP) || + (ex_aluop_i_1 == `EXE_LD_H_OP) || + (ex_aluop_i_1 == `EXE_LD_W_OP) || + (ex_aluop_i_1 == `EXE_LD_BU_OP) || + (ex_aluop_i_1 == `EXE_LD_HU_OP) || + (ex_aluop_i_1 == `EXE_ST_B_OP) || + (ex_aluop_i_1 == `EXE_ST_H_OP) || + (ex_aluop_i_1 == `EXE_ST_W_OP) || + (ex_aluop_i_2 == `EXE_LD_B_OP) || + (ex_aluop_i_2 == `EXE_LD_H_OP) || + (ex_aluop_i_2 == `EXE_LD_W_OP) || + (ex_aluop_i_2 == `EXE_LD_BU_OP) || + (ex_aluop_i_2 == `EXE_LD_HU_OP) || + (ex_aluop_i_2 == `EXE_ST_B_OP) || + (ex_aluop_i_2 == `EXE_ST_H_OP) || + (ex_aluop_i_2 == `EXE_ST_W_OP)) && (pc_i + 4 == pc_i_other)) ? 1'b1 : 1'b0; reg excepttype_is_syscall; reg excepttype_is_break; @@ -104,7 +131,7 @@ module id( stallreq_for_reg1_loadrelate = `NoStop; if(rst == `RstEnable) reg1_o = `ZeroWord; - else if(pre_inst_is_load == 1'b1 && ex_waddr_i == reg1_addr_o && reg1_read_o == 1'b1) + else if(pre_inst_is_load == 1'b1 && ex_waddr_i_1 == reg1_addr_o && reg1_read_o == 1'b1) stallreq_for_reg1_loadrelate = `Stop; end @@ -113,11 +140,13 @@ module id( stallreq_for_reg2_loadrelate = `NoStop; if(rst == `RstEnable) reg2_o = `ZeroWord; - else if(pre_inst_is_load == 1'b1 && ex_waddr_i == reg2_addr_o && reg2_read_o == 1'b1) + else if(pre_inst_is_load == 1'b1 && ex_waddr_i_1 == reg2_addr_o && reg2_read_o == 1'b1) stallreq_for_reg2_loadrelate = `Stop; end - assign stallreq = stallreq_for_reg1_loadrelate | stallreq_for_reg2_loadrelate; + //如果这条指令与另一条相邻且存在依赖就直接暂停 + assign stallreq = stallreq_for_reg1_loadrelate | stallreq_for_reg2_loadrelate | + ((pc_i == pc_i_other - 4) && ((reg1_addr_o == reg1_addr_i_other) | (reg2_addr_o == reg2_addr_i_other))); always @(*) begin @@ -785,10 +814,14 @@ module id( reg1_o = `ZeroWord; else if ((reg1_read_o == 1'b1) && (reg1_addr_o == 0)) reg1_o = `ZeroWord; - else if((reg1_read_o == 1'b1) && (ex_wreg_i == 1'b1) && (ex_waddr_i == reg1_addr_o)) - reg1_o = ex_wdata_i; - else if((reg1_read_o == 1'b1) && (mem_wreg_i == 1'b1) && (mem_waddr_i == reg1_addr_o)) - reg1_o = mem_wdata_i; + else if((reg1_read_o == 1'b1) && (ex_wreg_i_2 == 1'b1) && (ex_waddr_i_2 == reg1_addr_o)) + reg1_o = ex_wdata_i_2; + else if((reg1_read_o == 1'b1) && (mem_wreg_i_2 == 1'b1) && (mem_waddr_i_2 == reg1_addr_o)) + reg1_o = mem_wdata_i_2; + else if((reg1_read_o == 1'b1) && (ex_wreg_i_1 == 1'b1) && (ex_waddr_i_1 == reg1_addr_o)) + reg1_o = ex_wdata_i_1; + else if((reg1_read_o == 1'b1) && (mem_wreg_i_1 == 1'b1) && (mem_waddr_i_1 == reg1_addr_o)) + reg1_o = mem_wdata_i_1; else if (reg1_read_o == 1'b1) reg1_o = reg1_data_i; else if (reg1_read_o == 1'b0) @@ -803,10 +836,14 @@ module id( reg2_o = `ZeroWord; else if ((reg2_read_o == 1'b1) && (reg2_addr_o == 0)) reg2_o = `ZeroWord; - else if((reg2_read_o == 1'b1) && (ex_wreg_i == 1'b1) && (ex_waddr_i == reg2_addr_o)) - reg2_o = ex_wdata_i; - else if((reg2_read_o == 1'b1) && (mem_wreg_i == 1'b1) && (mem_waddr_i == reg2_addr_o)) - reg2_o = mem_wdata_i; + else if((reg2_read_o == 1'b1) && (ex_wreg_i_2 == 1'b1) && (ex_waddr_i_2 == reg2_addr_o)) + reg2_o = ex_wdata_i_2; + else if((reg2_read_o == 1'b1) && (mem_wreg_i_2 == 1'b1) && (mem_waddr_i_2 == reg2_addr_o)) + reg2_o = mem_wdata_i_2; + else if((reg2_read_o == 1'b1) && (ex_wreg_i_1 == 1'b1) && (ex_waddr_i_1 == reg2_addr_o)) + reg2_o = ex_wdata_i_1; + else if((reg2_read_o == 1'b1) && (mem_wreg_i_1 == 1'b1) && (mem_waddr_i_1 == reg2_addr_o)) + reg2_o = mem_wdata_i_1; else if (reg2_read_o == 1'b1) reg2_o = reg2_data_i; else if (reg2_read_o == 1'b0) diff --git a/src/vsrc/pipeline/4_mem/mem.v b/src/vsrc/pipeline/4_mem/mem.v index 13674ee..74fc7f8 100644 --- a/src/vsrc/pipeline/4_mem/mem.v +++ b/src/vsrc/pipeline/4_mem/mem.v @@ -3,6 +3,7 @@ module mem ( input wire rst, + input wire[`InstAddrBus] inst_pc_i, input wire[`RegAddrBus] wd_i, input wire wreg_i, input wire[`RegBus] wdata_i, @@ -19,6 +20,7 @@ module mem ( input wire[2:0] excepttype_i, input wire[`RegBus] current_inst_address_i, + output reg[`InstAddrBus] inst_pc_o, output reg[`RegAddrBus] wd_o, output reg wreg_o, output reg[`RegBus] wdata_o, @@ -71,6 +73,7 @@ module mem ( mem_ce_o = `ChipDisable; LLbit_we_o = 1'b0; LLbit_value_o = 1'b0; + inst_pc_o = `ZeroWord; end else begin @@ -83,6 +86,7 @@ module mem ( mem_sel_o = 4'b1111; LLbit_we_o = 1'b0; LLbit_value_o = 1'b0; + inst_pc_o = inst_pc_i; case (aluop_i) `EXE_LD_B_OP: begin diff --git a/src/vsrc/regfile.v b/src/vsrc/regfile.v index 16f7925..48be861 100644 --- a/src/vsrc/regfile.v +++ b/src/vsrc/regfile.v @@ -3,9 +3,11 @@ module regfile ( input wire clk, input wire rst, + input wire[`InstAddrBus] pc_i_1, input wire we_1, input wire [`RegAddrBus] waddr_1, input wire [`RegBus] wdata_1, + input wire[`InstAddrBus] pc_i_2, input wire we_2, input wire [`RegAddrBus] waddr_2, input wire [`RegBus] wdata_2, @@ -65,11 +67,19 @@ always @ (posedge clk)begin regs[2] <= `ZeroWord; regs[1] <= `ZeroWord; regs[0] <= `ZeroWord; - end else begin - if ((we_1 == `WriteEnable) && !(waddr_1 == `RegNumLog2'h0)) - regs[waddr_1] <= wdata_1; - if ((we_2 == `WriteEnable) && !(waddr_2 == `RegNumLog2'h0)) - regs[waddr_2] <= wdata_2; + end else begin //同时写入一个位置,将后面的写入 + if ((we_1 == `WriteEnable) && (we_2 == `WriteEnable) && waddr_1 == waddr_2)begin + if(pc_i_1 > pc_i_2) + regs[waddr_1] <= wdata_1; + else + regs[waddr_1] <= wdata_2; + end + else begin + if ((we_1 == `WriteEnable) && !(waddr_1 == `RegNumLog2'h0)) + regs[waddr_1] <= wdata_1; + if ((we_2 == `WriteEnable) && !(waddr_2 == `RegNumLog2'h0)) + regs[waddr_2] <= wdata_2; + end end end From 0f3a433f576d1e9be2e8ac3ec9aca3ad286b2bc0 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Sun, 10 Apr 2022 22:32:28 +0800 Subject: [PATCH 013/114] feat: add testbench --- .gitignore | 5 +- src/vsrc/branch_predictor/Makefile | 8 ++ src/vsrc/branch_predictor/gshared_predictor.v | 1 + src/vsrc/branch_predictor/tage_predictor.v | 9 ++ src/vsrc/branch_predictor/testbench.cpp | 111 ++++++++++++++++++ 5 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 src/vsrc/branch_predictor/Makefile create mode 100644 src/vsrc/branch_predictor/testbench.cpp diff --git a/.gitignore b/.gitignore index 07966ec..efc1d91 100644 --- a/.gitignore +++ b/.gitignore @@ -31,4 +31,7 @@ src/time.log la32-nemu-interpreter-so test/*.bin test/*.s -build/ \ No newline at end of file +build/ + +# Branch Predictor Test data +src/vsrc/branch_predictor/data diff --git a/src/vsrc/branch_predictor/Makefile b/src/vsrc/branch_predictor/Makefile new file mode 100644 index 0000000..929d0ee --- /dev/null +++ b/src/vsrc/branch_predictor/Makefile @@ -0,0 +1,8 @@ + + +VERILATOR_FLAGS = +define+DUMP_WAVEFORM=1 --trace + +verilate: *.v + verilator $(VERILATOR_FLAGS) tage_predictor.v --exe testbench.cpp --cc -I../ | true # Ignore errors + @make -C obj_dir -f Vtage_predictor.mk 2>&1 >/dev/null + ./obj_dir/Vtage_predictor +trace \ No newline at end of file diff --git a/src/vsrc/branch_predictor/gshared_predictor.v b/src/vsrc/branch_predictor/gshared_predictor.v index 1e75362..758e310 100644 --- a/src/vsrc/branch_predictor/gshared_predictor.v +++ b/src/vsrc/branch_predictor/gshared_predictor.v @@ -24,6 +24,7 @@ module gshared_predictor #( wire [`MAX_GHT_LENGTH-1:0] global_history_hashing[`MAX_GHT_LENGTH_LOG2]; // Concat GHT input to desired length assign global_history_hashing[0] = {{(`MAX_GHT_LENGTH - GLOBAL_HISTORY_LENGTH){1'b0}}, global_history_i[GLOBAL_HISTORY_LENGTH-1:0]}; + // Fold GHT input from `MAX_GHT_LENGTH to 1 genvar i; generate diff --git a/src/vsrc/branch_predictor/tage_predictor.v b/src/vsrc/branch_predictor/tage_predictor.v index 55dfaa6..952d8e5 100644 --- a/src/vsrc/branch_predictor/tage_predictor.v +++ b/src/vsrc/branch_predictor/tage_predictor.v @@ -21,6 +21,15 @@ module tage_predictor ( output wire predict_valid ); +`ifdef DUMP_WAVEFORM + + initial + begin + $dumpfile("logs/wave.vcd"); + $dumpvars(0, tage_predictor); + end +`endif + // Global History Register reg [`GHR_BUS] GHR; always @(posedge clk) diff --git a/src/vsrc/branch_predictor/testbench.cpp b/src/vsrc/branch_predictor/testbench.cpp new file mode 100644 index 0000000..635713d --- /dev/null +++ b/src/vsrc/branch_predictor/testbench.cpp @@ -0,0 +1,111 @@ +#include "Vtage_predictor.h" +#include +#include +#include +#include +#include +#include + +#define BRANCH_LATENCY (5) + +// Work around +double sc_time_stamp() { return 0; } + +static std::string test_filename = "data/gcc-10K.txt"; + +struct instruction_entry +{ + uint64_t pc; + bool taken; +}; + +// Parse test file +std::vector parse_test_file(std::string filename) +{ + std::ifstream test_file(filename); + + if (!test_file.is_open()) + { + std::cerr << "Open Input File: " << filename << " Failed." << std::endl; + std::exit(EXIT_FAILURE); + } + + std::vector entries; + + // Read loop + while (!test_file.eof()) + { + uint64_t pc; + char taken_char; + test_file >> std::hex >> pc; + test_file >> taken_char; + + entries.push_back({pc, taken_char == 'T'}); + } + + test_file.close(); + return entries; +} + +int main(int argc, char const *argv[]) +{ + // Enable tracing aka waveform + const std::unique_ptr context{new VerilatedContext}; + context->debug(0); + context->traceEverOn(true); + context->commandArgs(argc, argv); + Verilated::mkdir("logs"); + + // initialize + std::unique_ptr sopc(new Vtage_predictor{context.get()}); + sopc->clk = 1; + sopc->rst = 1; + + // Parse input test file + auto entries = parse_test_file(test_filename); + std::cout << "Procceeding with test instructions: " << entries.size() << std::endl; + std::cout << "First instruction: 0x" << std::hex << entries[0].pc << " " << entries[0].taken << std::endl; + + // Delay queue + std::queue delay_queue_taken; + std::queue delay_queue_valid; + for (size_t i = 0; i < BRANCH_LATENCY; i++) + { + delay_queue_taken.push({}); + delay_queue_valid.push(false); + } + + // Reset + sopc->clk = 0; + sopc->eval(); + context->timeInc(1); + sopc->clk = 1; + sopc->rst = 0; + sopc->eval(); + context->timeInc(1); + + // Simulation loop + for (size_t i = 0; i < 1000; i++) + { + + sopc->pc_i = entries[i].pc; + sopc->branch_valid_i = delay_queue_valid.front(); + delay_queue_valid.pop(); + sopc->branch_taken_i = delay_queue_taken.front().taken; + sopc->branch_pc_i = delay_queue_taken.front().pc; + delay_queue_taken.pop(); + delay_queue_valid.push(true); + delay_queue_taken.push(entries[i]); + + // Evaluate cycle + sopc->clk = 0; + sopc->eval(); + context->timeInc(1); + sopc->clk = 1; + sopc->eval(); + context->timeInc(1); + } + sopc->final(); + + return 0; +} \ No newline at end of file From be9dfe1b2977b88800306f9df4b1c910d29d8c82 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Mon, 11 Apr 2022 15:25:34 +0800 Subject: [PATCH 014/114] feat: finish bpu testbench - use 64kbit PHT to get 92% acc on single gshared bpu without tag --- src/vsrc/branch_predictor/Makefile | 8 +- src/vsrc/branch_predictor/defines.v | 6 +- src/vsrc/branch_predictor/folder_func.v | 39 +++++++++ src/vsrc/branch_predictor/gshared_predictor.v | 87 +++++++++++-------- src/vsrc/branch_predictor/tage_predictor.v | 3 + src/vsrc/branch_predictor/testbench.cpp | 43 +++++++-- src/vsrc/branch_predictor/utils/xor_func.v | 13 +++ 7 files changed, 150 insertions(+), 49 deletions(-) create mode 100644 src/vsrc/branch_predictor/folder_func.v create mode 100644 src/vsrc/branch_predictor/utils/xor_func.v diff --git a/src/vsrc/branch_predictor/Makefile b/src/vsrc/branch_predictor/Makefile index 929d0ee..f271bd4 100644 --- a/src/vsrc/branch_predictor/Makefile +++ b/src/vsrc/branch_predictor/Makefile @@ -1,8 +1,12 @@ -VERILATOR_FLAGS = +define+DUMP_WAVEFORM=1 --trace +VERILATOR_FLAGS = +define+DUMP_WAVEFORM=1 +#--trace verilate: *.v verilator $(VERILATOR_FLAGS) tage_predictor.v --exe testbench.cpp --cc -I../ | true # Ignore errors @make -C obj_dir -f Vtage_predictor.mk 2>&1 >/dev/null - ./obj_dir/Vtage_predictor +trace \ No newline at end of file + ./obj_dir/Vtage_predictor +trace + +clean: + rm -rf obj_dir/ \ No newline at end of file diff --git a/src/vsrc/branch_predictor/defines.v b/src/vsrc/branch_predictor/defines.v index 4743dd0..3baa5c5 100644 --- a/src/vsrc/branch_predictor/defines.v +++ b/src/vsrc/branch_predictor/defines.v @@ -8,8 +8,8 @@ `define BTB_ENTRY_BUS `BTB_ENTRY_LENGTH-1:0 // PHT parameters (Pattern History Table) -`define PHT_DEPTH 64 -`define PHT_DEPTH_LOG2 6 +`define PHT_DEPTH 65536 +`define PHT_DEPTH_LOG2 16 // GHR parameters (Global History Register) @@ -19,6 +19,6 @@ `define MAX_GHT_LENGTH_LOG2 9 // Parameters -`define FEEDBACK_LATENCY 2 +`define FEEDBACK_LATENCY 4 `endif diff --git a/src/vsrc/branch_predictor/folder_func.v b/src/vsrc/branch_predictor/folder_func.v new file mode 100644 index 0000000..ae1d7b8 --- /dev/null +++ b/src/vsrc/branch_predictor/folder_func.v @@ -0,0 +1,39 @@ +`include "branch_predictor/utils/xor_func.v" + +module folder_func #( + parameter INPUT_LENGTH = 10, + parameter OUTPUT_LENGTH = 8, + parameter MAX_FOLD_ROUND = 3 + ) ( + input wire [INPUT_LENGTH-1:0] var_i, + output wire [OUTPUT_LENGTH-1:0] var_o + ); + + + wire[2**MAX_FOLD_ROUND*OUTPUT_LENGTH-1:0] workspace[MAX_FOLD_ROUND]; + + // Extend the input to working length + assign workspace[0] = {{2**MAX_FOLD_ROUND*OUTPUT_LENGTH-INPUT_LENGTH{1'b0}},var_i}; + // assign workspace[0] = {var_i}; + + // Fold the input from workspace[0] to workspace[MAX_FOLD_ROUND-1] + // using XOR + generate + genvar i; + for (i = 1; i < MAX_FOLD_ROUND; i = i + 1) + begin + xor_func + #( + .HALF_DATA_WIDTH (2**(MAX_FOLD_ROUND-i)*OUTPUT_LENGTH) + ) + u_xor_func( + .i (workspace[i-1][2**(MAX_FOLD_ROUND-i+1)*OUTPUT_LENGTH-1:0]), + .o (workspace[i][2**(MAX_FOLD_ROUND-i+1)*OUTPUT_LENGTH-1:0]) + ); + end + endgenerate + + assign var_o = workspace[MAX_FOLD_ROUND-1][OUTPUT_LENGTH-1: + 0]; + +endmodule diff --git a/src/vsrc/branch_predictor/gshared_predictor.v b/src/vsrc/branch_predictor/gshared_predictor.v index 758e310..4c7e790 100644 --- a/src/vsrc/branch_predictor/gshared_predictor.v +++ b/src/vsrc/branch_predictor/gshared_predictor.v @@ -1,6 +1,7 @@ // Gshared predictor as base predictor `include "../defines.v" `include "branch_predictor/defines.v" +`include "branch_predictor/folder_func.v" module gshared_predictor #( @@ -18,31 +19,30 @@ module gshared_predictor #( output wire taken ); + // Reset + wire rst_n = ~rst; + // PHT, each entry is a bimodal predictor reg[1:0] PHT[`PHT_DEPTH]; + wire[1:0] debug_PHT[`PHT_DEPTH]; - wire [`MAX_GHT_LENGTH-1:0] global_history_hashing[`MAX_GHT_LENGTH_LOG2]; - // Concat GHT input to desired length - assign global_history_hashing[0] = {{(`MAX_GHT_LENGTH - GLOBAL_HISTORY_LENGTH){1'b0}}, global_history_i[GLOBAL_HISTORY_LENGTH-1:0]}; - - // Fold GHT input from `MAX_GHT_LENGTH to 1 - genvar i; - generate - for (i = `MAX_GHT_LENGTH_LOG2-1; i >1; i = i-1) - begin - wire [`MAX_GHT_LENGTH-1:0] global_history_hashing_folder = global_history_hashing[`MAX_GHT_LENGTH_LOG2-1-i]; - - wire [`MAX_GHT_LENGTH-1:0] op1 = {{(`MAX_GHT_LENGTH-2**i){1'b0}},global_history_hashing_folder[2**i-1:0]}; - wire [`MAX_GHT_LENGTH-1:0] op2 ={{(`MAX_GHT_LENGTH-2**i){1'b0}},global_history_hashing_folder[2**i*2-1:2**i]}; - assign global_history_hashing[`MAX_GHT_LENGTH_LOG2-i] = op1 ^ op2; - end - endgenerate // Select 8 as index - wire [7:0] hashed_ght_input = global_history_hashing[`MAX_GHT_LENGTH - 4][7:0]; + wire [`PHT_DEPTH_LOG2-1:0] hashed_ght_input; + folder_func + #( + .INPUT_LENGTH (GLOBAL_HISTORY_LENGTH), + .OUTPUT_LENGTH (`PHT_DEPTH_LOG2), + .MAX_FOLD_ROUND (4) + ) + u_folder_func( + .var_i (global_history_i[GLOBAL_HISTORY_LENGTH-1:0]), + .var_o (hashed_ght_input) + ); + // hash with pc, and concatenate to `PHT_DEPTH_LOG2 - wire [`PHT_DEPTH_LOG2-1:0] query_hashed_index = {hashed_ght_input ^ pc_i[9:2]}[`PHT_DEPTH_LOG2-1:0]; + wire [`PHT_DEPTH_LOG2-1:0] query_hashed_index = {hashed_ght_input ^ pc_i[2+`PHT_DEPTH_LOG2-1:2]}[`PHT_DEPTH_LOG2-1:0]; // Query logic ////////////////////////////////// wire [1:0] query_entry = PHT[query_hashed_index]; @@ -69,28 +69,39 @@ module gshared_predictor #( // Select index from buffer and update wire [`PHT_DEPTH_LOG2-1:0] update_index = hashed_index_buffer[`FEEDBACK_LATENCY-1]; - always @(posedge clk) + always @(posedge clk or negedge rst_n) begin - if (branch_valid) + if (!rst_n) + begin + // Reset all PHT to 01 + for (integer i = 0; i < `PHT_DEPTH; i = i + 1) + begin + PHT[i] = 2'b01; + end + end + else begin - case (PHT[update_index]) // 00,10 | 01,11 - 2'b00: - begin - PHT[update_index] <= branch_taken ? 2'b10: 2'b00; - end - 2'b10: - begin - PHT[update_index] <= branch_taken ? 2'b01: 2'b00; - end - 2'b01: - begin - PHT[update_index] <= branch_taken ? 2'b11: 2'b10; - end - 2'b11: - begin - PHT[update_index] <= branch_taken ? 2'b11: 2'b01; - end - endcase + if (branch_valid) + begin + case (PHT[update_index]) // 00,10 | 01,11 + 2'b00: + begin + PHT[update_index] <= branch_taken ? 2'b10: 2'b00; + end + 2'b10: + begin + PHT[update_index] <= branch_taken ? 2'b01: 2'b00; + end + 2'b01: + begin + PHT[update_index] <= branch_taken ? 2'b11: 2'b10; + end + 2'b11: + begin + PHT[update_index] <= branch_taken ? 2'b11: 2'b01; + end + endcase + end end end diff --git a/src/vsrc/branch_predictor/tage_predictor.v b/src/vsrc/branch_predictor/tage_predictor.v index 952d8e5..dbbcf1e 100644 --- a/src/vsrc/branch_predictor/tage_predictor.v +++ b/src/vsrc/branch_predictor/tage_predictor.v @@ -18,6 +18,7 @@ module tage_predictor ( // Prediction output wire [`RegBus] predicted_branch_target_o, + output wire predict_branch_taken_o, output wire predict_valid ); @@ -119,4 +120,6 @@ module tage_predictor ( .taken (t4_taken ) ); + assign predict_branch_taken_o = t4_taken; + endmodule //tage_predictor diff --git a/src/vsrc/branch_predictor/testbench.cpp b/src/vsrc/branch_predictor/testbench.cpp index 635713d..2b91477 100644 --- a/src/vsrc/branch_predictor/testbench.cpp +++ b/src/vsrc/branch_predictor/testbench.cpp @@ -11,7 +11,7 @@ // Work around double sc_time_stamp() { return 0; } -static std::string test_filename = "data/gcc-10K.txt"; +static std::string test_filename = "data/gcc-8M.txt"; struct instruction_entry { @@ -64,7 +64,7 @@ int main(int argc, char const *argv[]) // Parse input test file auto entries = parse_test_file(test_filename); std::cout << "Procceeding with test instructions: " << entries.size() << std::endl; - std::cout << "First instruction: 0x" << std::hex << entries[0].pc << " " << entries[0].taken << std::endl; + std::cout << "First instruction: 0x" << std::hex << entries[0].pc << " " << entries[0].taken << std::dec << std::endl; // Delay queue std::queue delay_queue_taken; @@ -84,10 +84,16 @@ int main(int argc, char const *argv[]) sopc->eval(); context->timeInc(1); + std::vector prediction_taken; + // Simulation loop - for (size_t i = 0; i < 1000; i++) + for (size_t i = 0; i < entries.size(); i++) { + sopc->clk = 0; + sopc->eval(); + context->timeInc(1); + sopc->pc_i = entries[i].pc; sopc->branch_valid_i = delay_queue_valid.front(); delay_queue_valid.pop(); @@ -98,14 +104,39 @@ int main(int argc, char const *argv[]) delay_queue_taken.push(entries[i]); // Evaluate cycle - sopc->clk = 0; - sopc->eval(); - context->timeInc(1); sopc->clk = 1; sopc->eval(); context->timeInc(1); + + // Retrieve prediction + prediction_taken.push_back(sopc->predict_branch_taken_o); } sopc->final(); + // Statistics + uint64_t correct = 0; + uint64_t target_taken = 0; + uint64_t predicted_taken = 0; + for (size_t i = 0; i < prediction_taken.size(); i++) + { + if (entries[i].taken == prediction_taken[i]) + { + correct++; + } + if (entries[i].taken) + { + target_taken++; + } + if (prediction_taken[i]) + { + predicted_taken++; + } + } + std::cout << "Correct Taken: " << target_taken << '\n'; + std::cout << "Predicted Taken: " << predicted_taken << '\n'; + std::cout << "Correct: " << correct << '\n'; + std::cout << "Wrong: " << prediction_taken.size() - correct << '\n'; + std::cout << "Correct Rate: " << (double)correct / prediction_taken.size() << std::endl; + return 0; } \ No newline at end of file diff --git a/src/vsrc/branch_predictor/utils/xor_func.v b/src/vsrc/branch_predictor/utils/xor_func.v new file mode 100644 index 0000000..0e68368 --- /dev/null +++ b/src/vsrc/branch_predictor/utils/xor_func.v @@ -0,0 +1,13 @@ +// xor_func accept input, fold and xor, then extend to original length + +module xor_func #( + parameter HALF_DATA_WIDTH = 4 + ) ( + input wire [HALF_DATA_WIDTH*2-1:0] i, + output wire [HALF_DATA_WIDTH*2-1:0] o + ); + + + assign o = {{HALF_DATA_WIDTH{1'b0}},i[HALF_DATA_WIDTH*2-1:HALF_DATA_WIDTH] ^ i[HALF_DATA_WIDTH-1:0]}; + +endmodule From fe127282517d502816ece89a6bad0b791c9b49b3 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Mon, 11 Apr 2022 18:57:56 +0800 Subject: [PATCH 015/114] feat: implement tag - achieve 96% on gcc-8M --- src/vsrc/branch_predictor/defines.v | 3 +- src/vsrc/branch_predictor/gshared_predictor.v | 61 ++++++++++++++----- src/vsrc/branch_predictor/tage_predictor.v | 53 +++++++++++++--- src/vsrc/branch_predictor/testbench.cpp | 14 ++++- 4 files changed, 107 insertions(+), 24 deletions(-) diff --git a/src/vsrc/branch_predictor/defines.v b/src/vsrc/branch_predictor/defines.v index 3baa5c5..752fa0f 100644 --- a/src/vsrc/branch_predictor/defines.v +++ b/src/vsrc/branch_predictor/defines.v @@ -10,10 +10,11 @@ // PHT parameters (Pattern History Table) `define PHT_DEPTH 65536 `define PHT_DEPTH_LOG2 16 +`define PHT_TAG_WIDTH 8 // GHR parameters (Global History Register) -`define GHR_DEPTH 40 +`define GHR_DEPTH 200 `define GHR_BUS `GHR_DEPTH-1:0 `define MAX_GHT_LENGTH 512 `define MAX_GHT_LENGTH_LOG2 9 diff --git a/src/vsrc/branch_predictor/gshared_predictor.v b/src/vsrc/branch_predictor/gshared_predictor.v index 4c7e790..07703d1 100644 --- a/src/vsrc/branch_predictor/gshared_predictor.v +++ b/src/vsrc/branch_predictor/gshared_predictor.v @@ -16,18 +16,19 @@ module gshared_predictor #( input wire branch_valid, input wire branch_taken, - output wire taken + output wire taken, + output wire tag_hit ); // Reset wire rst_n = ~rst; - // PHT, each entry is a bimodal predictor - reg[1:0] PHT[`PHT_DEPTH]; - wire[1:0] debug_PHT[`PHT_DEPTH]; + // PHT + // - entry: {2bits bimodal, xbits tag} + reg[`PHT_TAG_WIDTH+1:0] PHT[`PHT_DEPTH]; - // Select 8 as index + // Fold GHT input to a fix length, the same as index range wire [`PHT_DEPTH_LOG2-1:0] hashed_ght_input; folder_func #( @@ -35,26 +36,50 @@ module gshared_predictor #( .OUTPUT_LENGTH (`PHT_DEPTH_LOG2), .MAX_FOLD_ROUND (4) ) - u_folder_func( + ght_hash( .var_i (global_history_i[GLOBAL_HISTORY_LENGTH-1:0]), .var_o (hashed_ght_input) ); + // Tag + // wire [`PHT_TAG_WIDTH-1:0] hashed_pc_tag = pc_i[2+`PHT_TAG_WIDTH-1:2]; + wire [`PHT_TAG_WIDTH-1:0] hashed_pc_tag; + folder_func + #( + .INPUT_LENGTH (`RegWidth), + .OUTPUT_LENGTH (`PHT_TAG_WIDTH), + .MAX_FOLD_ROUND (3) + ) + pc_hash( + .var_i(pc_i), + .var_o (hashed_pc_tag) + ); + + // hash with pc, and concatenate to `PHT_DEPTH_LOG2 - wire [`PHT_DEPTH_LOG2-1:0] query_hashed_index = {hashed_ght_input ^ pc_i[2+`PHT_DEPTH_LOG2-1:2]}[`PHT_DEPTH_LOG2-1:0]; + // the low 2bits of pc is usually 0, so use upper bits + wire [`PHT_DEPTH_LOG2-1:0] query_hashed_index = {hashed_ght_input ^ pc_i[2+`PHT_DEPTH_LOG2-1:2]}; // Query logic ////////////////////////////////// - wire [1:0] query_entry = PHT[query_hashed_index]; - assign taken = (query_entry == 2'b11) | (query_entry == 2'b01); + wire [1:0] query_result_bimodal = PHT[query_hashed_index][`PHT_TAG_WIDTH+1:`PHT_TAG_WIDTH]; + wire [`PHT_TAG_WIDTH-1:0] query_result_tag = PHT[query_hashed_index][`PHT_TAG_WIDTH-1:0]; + + assign taken = (query_result_bimodal == 2'b11) | (query_result_bimodal == 2'b01); + assign tag_hit = (hashed_pc_tag == query_result_tag); + // assign tag_hit = 1; + + // Update logic ////////////////////////////////// // This buffer is used to store the hashed index for update reg[`PHT_DEPTH_LOG2-1:0] hashed_index_buffer [`FEEDBACK_LATENCY]; + reg[`PHT_TAG_WIDTH-1:0] tag_buffer [`FEEDBACK_LATENCY]; always @(posedge clk) begin hashed_index_buffer[0] <= query_hashed_index; + tag_buffer[0] <= hashed_pc_tag; end genvar index_id; generate @@ -63,12 +88,14 @@ module gshared_predictor #( always @(posedge clk) begin hashed_index_buffer[index_id] <= hashed_index_buffer[index_id - 1]; + tag_buffer[index_id] <= tag_buffer[index_id - 1]; end end endgenerate // Select index from buffer and update wire [`PHT_DEPTH_LOG2-1:0] update_index = hashed_index_buffer[`FEEDBACK_LATENCY-1]; + wire [`PHT_TAG_WIDTH-1:0] update_tag = tag_buffer[`FEEDBACK_LATENCY-1]; always @(posedge clk or negedge rst_n) begin if (!rst_n) @@ -76,31 +103,35 @@ module gshared_predictor #( // Reset all PHT to 01 for (integer i = 0; i < `PHT_DEPTH; i = i + 1) begin - PHT[i] = 2'b01; + PHT[i] = {2'b01,{`PHT_TAG_WIDTH{1'b0}}}; end end else begin if (branch_valid) begin - case (PHT[update_index]) // 00,10 | 01,11 + case (PHT[update_index][`PHT_TAG_WIDTH+1:`PHT_TAG_WIDTH]) // 00,10 | 01,11 2'b00: begin - PHT[update_index] <= branch_taken ? 2'b10: 2'b00; + PHT[update_index][`PHT_TAG_WIDTH+1:`PHT_TAG_WIDTH] <= branch_taken ? 2'b10: 2'b00; end 2'b10: begin - PHT[update_index] <= branch_taken ? 2'b01: 2'b00; + PHT[update_index][`PHT_TAG_WIDTH+1:`PHT_TAG_WIDTH] <= branch_taken ? 2'b01: 2'b00; end 2'b01: begin - PHT[update_index] <= branch_taken ? 2'b11: 2'b10; + PHT[update_index][`PHT_TAG_WIDTH+1:`PHT_TAG_WIDTH] <= branch_taken ? 2'b11: 2'b10; end 2'b11: begin - PHT[update_index] <= branch_taken ? 2'b11: 2'b01; + PHT[update_index][`PHT_TAG_WIDTH+1:`PHT_TAG_WIDTH] <= branch_taken ? 2'b11: 2'b01; end endcase + if (PHT[update_index][`PHT_TAG_WIDTH-1:0] != update_tag) // Miss tag + begin // Do swap + PHT[update_index][`PHT_TAG_WIDTH-1:0]<= {update_tag}; + end end end end diff --git a/src/vsrc/branch_predictor/tage_predictor.v b/src/vsrc/branch_predictor/tage_predictor.v index dbbcf1e..02919d6 100644 --- a/src/vsrc/branch_predictor/tage_predictor.v +++ b/src/vsrc/branch_predictor/tage_predictor.v @@ -18,8 +18,11 @@ module tage_predictor ( // Prediction output wire [`RegBus] predicted_branch_target_o, - output wire predict_branch_taken_o, - output wire predict_valid + output reg predict_branch_taken_o, + output wire predict_valid, + + // Counter + output reg [5*32-1:0] perf_tag_hit_counter ); `ifdef DUMP_WAVEFORM @@ -60,9 +63,13 @@ module tage_predictor ( // Tagged Predictors wire t1_taken; + wire t1_hit; wire t2_taken; + wire t2_hit; wire t3_taken; + wire t3_hit; wire t4_taken; + wire t4_hit; gshared_predictor #( @@ -75,7 +82,8 @@ module tage_predictor ( .pc_i (pc_i ), .branch_valid (branch_valid_i ), .branch_taken (branch_taken_i ), - .taken (t1_taken ) + .taken (t1_taken ), + .tag_hit (t1_hit) ); gshared_predictor @@ -89,7 +97,8 @@ module tage_predictor ( .pc_i (pc_i ), .branch_valid (branch_valid_i ), .branch_taken (branch_taken_i ), - .taken (t2_taken ) + .taken (t2_taken ), + .tag_hit(t2_hit) ); gshared_predictor @@ -103,7 +112,8 @@ module tage_predictor ( .pc_i (pc_i ), .branch_valid (branch_valid_i ), .branch_taken (branch_taken_i ), - .taken (t3_taken ) + .taken (t3_taken ), + .tag_hit(t3_hit) ); gshared_predictor @@ -117,9 +127,38 @@ module tage_predictor ( .pc_i (pc_i ), .branch_valid (branch_valid_i ), .branch_taken (branch_taken_i ), - .taken (t4_taken ) + .taken (t4_taken ), + .tag_hit (t4_hit) ); - assign predict_branch_taken_o = t4_taken; + + always @(posedge clk) + begin + if (t4_hit) + begin + predict_branch_taken_o <= t4_taken; + perf_tag_hit_counter[31:0] <= perf_tag_hit_counter[31:0] +1; + end + else if(t3_hit) + begin + predict_branch_taken_o <= t3_taken; + perf_tag_hit_counter[2*32-1:32] <= perf_tag_hit_counter[2*32-1:32] +1; + end + else if(t2_hit) + begin + predict_branch_taken_o <= t2_taken; + // perf_tag_hit_counter[2] <= perf_tag_hit_counter[2] +1; + end + else if(t1_hit) + begin + predict_branch_taken_o <= t1_taken; + // perf_tag_hit_counter[3] <= perf_tag_hit_counter[3] +1; + end + else + begin + predict_branch_taken_o <= 1; + // perf_tag_hit_counter[4] <= perf_tag_hit_counter[4] +1; + end + end endmodule //tage_predictor diff --git a/src/vsrc/branch_predictor/testbench.cpp b/src/vsrc/branch_predictor/testbench.cpp index 2b91477..8c5771a 100644 --- a/src/vsrc/branch_predictor/testbench.cpp +++ b/src/vsrc/branch_predictor/testbench.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #define BRANCH_LATENCY (5) @@ -84,7 +85,7 @@ int main(int argc, char const *argv[]) sopc->eval(); context->timeInc(1); - std::vector prediction_taken; + std::deque prediction_taken; // Simulation loop for (size_t i = 0; i < entries.size(); i++) @@ -109,10 +110,21 @@ int main(int argc, char const *argv[]) context->timeInc(1); // Retrieve prediction + // std::cout << "predicted, truth: " << (uint32_t)sopc->predict_branch_taken_o << " " << entries[i].taken << std::endl; prediction_taken.push_back(sopc->predict_branch_taken_o); } + uint32_t perf_tag_hit_counter[5]; + std::memcpy(perf_tag_hit_counter, sopc->perf_tag_hit_counter, sizeof(uint32_t) * 5); + std::cout << perf_tag_hit_counter[4] << std::endl; + std::cout << perf_tag_hit_counter[3] << std::endl; + std::cout << perf_tag_hit_counter[2] << std::endl; + std::cout << perf_tag_hit_counter[1] << std::endl; + std::cout << perf_tag_hit_counter[0] << std::endl; sopc->final(); + // First predicto is invalid + prediction_taken.pop_front(); + // Statistics uint64_t correct = 0; uint64_t target_taken = 0; From 943750225349326527c2d690a01e85f63b6385d9 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Mon, 11 Apr 2022 20:29:18 +0800 Subject: [PATCH 016/114] test: add more realistic traces - Better than bimodal, but worse than Gshared --- src/vsrc/branch_predictor/Makefile | 6 ++++-- src/vsrc/branch_predictor/benchmark.sh | 11 +++++++++++ src/vsrc/branch_predictor/defines.v | 4 ++-- src/vsrc/branch_predictor/testbench.cpp | 15 ++++++++++++--- 4 files changed, 29 insertions(+), 7 deletions(-) create mode 100755 src/vsrc/branch_predictor/benchmark.sh diff --git a/src/vsrc/branch_predictor/Makefile b/src/vsrc/branch_predictor/Makefile index f271bd4..60ab681 100644 --- a/src/vsrc/branch_predictor/Makefile +++ b/src/vsrc/branch_predictor/Makefile @@ -1,12 +1,14 @@ +benchmark: verilate + ./benchmark.sh + -VERILATOR_FLAGS = +define+DUMP_WAVEFORM=1 +VERILATOR_FLAGS = -O3 +define+DUMP_WAVEFORM=1 #--trace verilate: *.v verilator $(VERILATOR_FLAGS) tage_predictor.v --exe testbench.cpp --cc -I../ | true # Ignore errors @make -C obj_dir -f Vtage_predictor.mk 2>&1 >/dev/null - ./obj_dir/Vtage_predictor +trace clean: rm -rf obj_dir/ \ No newline at end of file diff --git a/src/vsrc/branch_predictor/benchmark.sh b/src/vsrc/branch_predictor/benchmark.sh new file mode 100755 index 0000000..31132c2 --- /dev/null +++ b/src/vsrc/branch_predictor/benchmark.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +traces=$(find data/traces -type f | sort) + +for t in ${traces} +do + +rate=$(obj_dir/Vtage_predictor $t | grep "Rate") + +echo "${t} ${rate}" +done \ No newline at end of file diff --git a/src/vsrc/branch_predictor/defines.v b/src/vsrc/branch_predictor/defines.v index 752fa0f..dcf18a6 100644 --- a/src/vsrc/branch_predictor/defines.v +++ b/src/vsrc/branch_predictor/defines.v @@ -8,8 +8,8 @@ `define BTB_ENTRY_BUS `BTB_ENTRY_LENGTH-1:0 // PHT parameters (Pattern History Table) -`define PHT_DEPTH 65536 -`define PHT_DEPTH_LOG2 16 +`define PHT_DEPTH 1024 +`define PHT_DEPTH_LOG2 10 `define PHT_TAG_WIDTH 8 diff --git a/src/vsrc/branch_predictor/testbench.cpp b/src/vsrc/branch_predictor/testbench.cpp index 8c5771a..0e39c54 100644 --- a/src/vsrc/branch_predictor/testbench.cpp +++ b/src/vsrc/branch_predictor/testbench.cpp @@ -12,7 +12,7 @@ // Work around double sc_time_stamp() { return 0; } -static std::string test_filename = "data/gcc-8M.txt"; +static std::string test_filename = "data/traces/trace_01"; struct instruction_entry { @@ -41,7 +41,7 @@ std::vector parse_test_file(std::string filename) test_file >> std::hex >> pc; test_file >> taken_char; - entries.push_back({pc, taken_char == 'T'}); + entries.push_back({pc, taken_char == 'T' || taken_char == '1'}); } test_file.close(); @@ -63,7 +63,16 @@ int main(int argc, char const *argv[]) sopc->rst = 1; // Parse input test file - auto entries = parse_test_file(test_filename); + std::string input_filename; + if (argc > 1) + { + input_filename = std::string(argv[1]); + } + else + { + input_filename = test_filename; + } + auto entries = parse_test_file(input_filename); std::cout << "Procceeding with test instructions: " << entries.size() << std::endl; std::cout << "First instruction: 0x" << std::hex << entries[0].pc << " " << entries[0].taken << std::dec << std::endl; From 66753cc33a4c680c7a0c792930357d130cf43316 Mon Sep 17 00:00:00 2001 From: Rookie <74707760+Rookie-Cai-niao@users.noreply.github.com> Date: Mon, 11 Apr 2022 22:01:08 +0800 Subject: [PATCH 017/114] fix some data related bug --- src/data_ram.v | 48 ++++++++++--------- src/vsrc/cpu_top.v | 76 ++++++++++++++++++++---------- src/vsrc/ctrl.v | 36 +++++++------- src/vsrc/pipeline/2_decode/id.v | 15 ++---- src/vsrc/pipeline/2_decode/id_ex.v | 39 ++++++++++++++- src/vsrc/pipeline/4_mem/mem.v | 2 +- src/vsrc/regfile.v | 8 ++++ 7 files changed, 145 insertions(+), 79 deletions(-) diff --git a/src/data_ram.v b/src/data_ram.v index becfed2..2ac2074 100644 --- a/src/data_ram.v +++ b/src/data_ram.v @@ -28,11 +28,11 @@ module data_ram( always @ (posedge clk) begin - if (ce_1 == `ChipEnable) + if(we_1 == `WriteEnable && we_2 == `WriteEnable && addr_1 == addr_2) begin - if(we_1 == `WriteEnable) + if(pc_1 > pc_2) begin - if (sel_1[3] == 1'b1) + if (sel_1[3] == 1'b1) data_mem3[addr_1[`DataMemNumLog2+1:2]] <= data_i_1[31:24]; if (sel_1[2] == 1'b1) data_mem2[addr_1[`DataMemNumLog2+1:2]] <= data_i_1[23:16]; @@ -41,9 +41,31 @@ module data_ram( if (sel_1[0] == 1'b1) data_mem0[addr_1[`DataMemNumLog2+1:2]] <= data_i_1[7:0]; end + else + begin + if (sel_2[3] == 1'b1) + data_mem3[addr_2[`DataMemNumLog2+1:2]] <= data_i_2[31:24]; + if (sel_2[2] == 1'b1) + data_mem2[addr_2[`DataMemNumLog2+1:2]] <= data_i_2[23:16]; + if (sel_2[1] == 1'b1) + data_mem1[addr_2[`DataMemNumLog2+1:2]] <= data_i_2[15:8]; + if (sel_2[0] == 1'b1) + data_mem0[addr_2[`DataMemNumLog2+1:2]] <= data_i_2[7:0]; + end end - if(ce_2 == `ChipEnable) + else begin + if(we_1 == `WriteEnable) + begin + if (sel_1[3] == 1'b1) + data_mem3[addr_1[`DataMemNumLog2+1:2]] <= data_i_1[31:24]; + if (sel_1[2] == 1'b1) + data_mem2[addr_1[`DataMemNumLog2+1:2]] <= data_i_1[23:16]; + if (sel_1[1] == 1'b1) + data_mem1[addr_1[`DataMemNumLog2+1:2]] <= data_i_1[15:8]; + if (sel_1[0] == 1'b1) + data_mem0[addr_1[`DataMemNumLog2+1:2]] <= data_i_1[7:0]; + end if(we_2 == `WriteEnable) begin if (sel_2[3] == 1'b1) @@ -59,24 +81,6 @@ module data_ram( end - always @ (posedge clk) - begin - if (ce_2 == `ChipDisable) - begin - end - else if(we_2 == `WriteEnable) - begin - if (sel_2[3] == 1'b1) - data_mem3[addr_2[`DataMemNumLog2+1:2]] <= data_i_2[31:24]; - if (sel_2[2] == 1'b1) - data_mem2[addr_2[`DataMemNumLog2+1:2]] <= data_i_2[23:16]; - if (sel_2[1] == 1'b1) - data_mem1[addr_2[`DataMemNumLog2+1:2]] <= data_i_2[15:8]; - if (sel_2[0] == 1'b1) - data_mem0[addr_2[`DataMemNumLog2+1:2]] <= data_i_2[7:0]; - end - end - always @ (posedge clk) begin if (ce_1 == `ChipDisable) diff --git a/src/vsrc/cpu_top.v b/src/vsrc/cpu_top.v index 2ac7270..0af2e22 100644 --- a/src/vsrc/cpu_top.v +++ b/src/vsrc/cpu_top.v @@ -128,7 +128,7 @@ module cpu_top ( .if_inst_i(ram_rdata_i_1), .id_pc_o(id_pc_1), .id_inst_o(id_inst_1), - .if_inst_valid(if_inst_valid), + .if_inst_valid(if_inst_valid_1), .branch_flag_i(branch_flag), .flush(flush), .stall(stall1[2]) @@ -139,9 +139,9 @@ module cpu_top ( .rst(rst), .if_pc_i(pc_buffer_2), .if_inst_i(ram_rdata_i_2), - .id_pc_o(id_pc_1), + .id_pc_o(id_pc_2), .id_inst_o(id_inst_2), - .if_inst_valid(if_inst_valid), + .if_inst_valid(if_inst_valid_2), .branch_flag_i(branch_flag), .flush(flush), .stall(stall2[2]) @@ -191,20 +191,25 @@ module cpu_top ( wire[`RegAddrBus] reg1_addr_2; wire[`RegAddrBus] reg2_addr_2; + wire[`RegBus] link_addr_1; + wire[`RegBus] link_addr_2; + + wire[`RegAddrBus] id_reg_waddr_2; + + wire stallreq_to_next_1; + wire stallreq_to_next_2; + id u_id_1( .rst(rst), .pc_i(id_pc_1), .inst_i(id_inst_1), - .pc_i_other(id_pc_2), + .pc_i_other(pc_buffer_2), .reg1_data_i (reg1_data_1 ), .reg2_data_i (reg2_data_1 ), - .reg1_addr_i_other(reg1_addr_2), - .reg2_addr_i_other(reg2_addr_2), - .ex_wreg_i_1 (ex_wreg_o_1 ), .ex_waddr_i_1 (ex_reg_waddr_o_1), .ex_wdata_i_1 (ex_reg_wdata_1), @@ -241,9 +246,9 @@ module cpu_top ( .branch_flag_o(branch_flag), .branch_target_address_o(branch_target_address), - .link_addr_o(link_addr), + .link_addr_o(link_addr_1), - .stallreq(stallreq_from_id_1), + .stallreq(stallreq_to_next_1), .excepttype_o(id_excepttype_o_1), .current_inst_address_o(id_current_inst_address_o_1) @@ -253,7 +258,7 @@ module cpu_top ( wire[`AluSelBus] id_alusel_2; wire[`RegBus] id_reg1_2; wire[`RegBus] id_reg2_2; - wire[`RegAddrBus] id_reg_waddr_2; + wire id_wreg_2; wire id_inst_valid_2; wire[`InstAddrBus] id_inst_pc_2; @@ -272,19 +277,18 @@ module cpu_top ( wire[1:0] id_excepttype_o_2; wire[`RegBus] id_current_inst_address_o_2; + + id u_id_2( .rst(rst), .pc_i(id_pc_2), .inst_i(id_inst_2), - .pc_i_other(id_pc_1), + .pc_i_other(pc_buffer_1), .reg1_data_i (reg1_data_2 ), .reg2_data_i (reg2_data_2 ), - .reg1_addr_i_other(reg1_addr_1), - .reg2_addr_i_other(reg2_addr_1), - .ex_wreg_i_1 (ex_wreg_o_2 ), .ex_waddr_i_1 (ex_reg_waddr_o_2), .ex_wdata_i_1 (ex_reg_wdata_2), @@ -321,12 +325,13 @@ module cpu_top ( .branch_flag_o(branch_flag), .branch_target_address_o(branch_target_address), - .link_addr_o(link_addr), + .link_addr_o(link_addr_2), - .stallreq(stallreq_from_id_2), + .stallreq(stallreq_to_next_2), .excepttype_o(id_excepttype_o_2), .current_inst_address_o(id_current_inst_address_o_2) + ); wire[`AluOpBus] ex_aluop_1; @@ -355,7 +360,7 @@ module cpu_top ( .id_wreg(id_wreg_1), .id_inst_pc(id_inst_pc_1), .id_inst_valid(id_inst_valid_1), - .id_link_address(link_addr), + .id_link_address(link_addr_1), .id_inst(id_inst_o_1), .flush(flush), .id_excepttype(id_excepttype_o_1), @@ -372,7 +377,17 @@ module cpu_top ( .ex_link_address(ex_link_address_1), .ex_inst(ex_inst_i_1), .ex_excepttype(ex_excepttype_i_1), - .ex_current_inst_address(ex_current_inst_address_i_1) + .ex_current_inst_address(ex_current_inst_address_i_1), + + .reg1_addr_i(reg1_addr_1), + .reg2_addr_i(reg2_addr_1), + .pc_i_other(id_inst_pc_2), + .reg1_addr_i_other(reg1_addr_2), + .reg2_addr_i_other(reg2_addr_2), + .waddr_i_other(id_reg_waddr_2), + + .stallreq_from_id(stallreq_to_next_1), + .stallreq(stallreq_from_id_1) ); wire[`AluOpBus] ex_aluop_2; @@ -418,7 +433,17 @@ module cpu_top ( .ex_link_address(ex_link_address_2), .ex_inst(ex_inst_i_2), .ex_excepttype(ex_excepttype_i_2), - .ex_current_inst_address(ex_current_inst_address_i_2) + .ex_current_inst_address(ex_current_inst_address_i_2), + + .reg1_addr_i(reg1_addr_2), + .reg2_addr_i(reg2_addr_2), + .pc_i_other(id_inst_pc_1), + .reg1_addr_i_other(reg1_addr_1), + .reg2_addr_i_other(reg2_addr_2), + .waddr_i_other(id_reg_waddr_1), + + .stallreq_from_id(stallreq_to_next_2), + .stallreq(stallreq_from_id_2) ); @@ -493,7 +518,7 @@ module cpu_top ( .excepttype_o(ex_excepttype_o_2), .current_inst_address_o(ex_current_inst_address_o_2), - .stallreq(stallreq_from_ex_1_2) + .stallreq(stallreq_from_ex_2) ); @@ -588,7 +613,7 @@ module cpu_top ( wire wb_LLbit_value_i_1; wire mem_LLbit_we_o_1; wire mem_LLbit_value_o_1; - wire[1:0] mem_excepttype_o_1; + wire[1:0] mem_excepttype_o; wire[`RegBus] mem_current_inst_address_o_1; wire[`InstAddrBus] wb_inst_pc_1; @@ -626,7 +651,7 @@ module cpu_top ( .LLbit_we_o(mem_LLbit_we_o_1), .LLbit_value_o(mem_LLbit_value_o_1), - .excepttype_o(mem_excepttype_o_1), + .excepttype_o(mem_excepttype_o), .current_inst_address_o(mem_current_inst_address_o_1) ); @@ -636,7 +661,6 @@ module cpu_top ( wire wb_LLbit_value_i_2; wire mem_LLbit_we_o_2; wire mem_LLbit_value_o_2; - wire[1:0] mem_excepttype_o_2; wire[`RegBus] mem_current_inst_address_o_2 ; wire[`InstAddrBus] wb_inst_pc_2; @@ -674,7 +698,7 @@ module cpu_top ( .LLbit_we_o(mem_LLbit_we_o_2), .LLbit_value_o(mem_LLbit_value_o_2), - .excepttype_o(mem_excepttype_o_2), + .excepttype_o(mem_excepttype_o), .current_inst_address_o(mem_current_inst_address_o_2) ); @@ -750,8 +774,8 @@ module cpu_top ( .wb_wreg(wb_wreg_2), .wb_wdata(wb_reg_wdata_2), - .wb_LLbit_we(wb_LLbit_we_i_2), - .wb_LLbit_value(wb_LLbit_value_i_2), + .wb_LLbit_we(wb_LLbit_we_i), + .wb_LLbit_value(wb_LLbit_value_2), .debug_commit_pc (debug_commit_pc_2 ), .debug_commit_valid (debug_commit_valid_2 ), diff --git a/src/vsrc/ctrl.v b/src/vsrc/ctrl.v index fb40704..da829b8 100644 --- a/src/vsrc/ctrl.v +++ b/src/vsrc/ctrl.v @@ -17,22 +17,22 @@ module ctrl ( wire rst_n = ~rst; - always @(posedge clk or negedge rst_n) + always @(*) begin if (!rst_n) begin - flush <= 1'b0; - new_pc <= `ZeroWord; + flush = 1'b0; + new_pc = `ZeroWord; end else if(excepttype_i != 0) begin - flush <= 1'b1; + flush = 1'b1; case (excepttype_i) 2'b01: - new_pc <= 32'h0000000c; + new_pc = 32'h0000000c; 2'b10: - new_pc <= 32'h0000000c; + new_pc = 32'h0000000c; default: begin end @@ -40,33 +40,33 @@ module ctrl ( end else begin - flush <= 1'b0; - new_pc <= `ZeroWord; + flush = 1'b0; + new_pc = `ZeroWord; end end - always @(posedge clk or negedge rst_n) + always @(*) begin if (!rst_n) - stall1 <= 7'b0000000; + stall1 = 7'b0000000; else if(stallreq_from_ex_1 == `Stop) - stall1 <= 7'b0011111; + stall1 = 7'b0011111; else if(stallreq_from_id_1 == `Stop) - stall1 <= 7'b0011111; + stall1 = 7'b0011111; else - stall1 <= 7'b0000000; + stall1 = 7'b0000000; end - always @(posedge clk or negedge rst_n) + always @(*) begin if (!rst_n) - stall2 <= 7'b0000000; + stall2 = 7'b0000000; else if(stallreq_from_ex_2 == `Stop) - stall2 <= 7'b0011111; + stall2 = 7'b0011111; else if(stallreq_from_id_2 == `Stop) - stall2 <= 7'b0011111; + stall2 = 7'b0011111; else - stall2 <= 7'b0000000; + stall2 = 7'b0000000; end diff --git a/src/vsrc/pipeline/2_decode/id.v b/src/vsrc/pipeline/2_decode/id.v index 107c72f..e15a253 100644 --- a/src/vsrc/pipeline/2_decode/id.v +++ b/src/vsrc/pipeline/2_decode/id.v @@ -6,16 +6,11 @@ module id( input wire[`InstAddrBus] pc_i, input wire[`InstBus] inst_i, - // <- ANOTHER_IF - input wire[`InstAddrBus] pc_i_other, - // <- Regfile input wire[`RegBus] reg1_data_i, input wire[`RegBus] reg2_data_i, - // <- ANOTHER_ID - input wire[`RegAddrBus] reg1_addr_i_other, - input wire[`RegAddrBus] reg2_addr_i_other, + input wire[`InstAddrBus] pc_i_other, // <- EXE input wire ex_wreg_i_1, @@ -102,6 +97,7 @@ module id( reg stallreq_for_reg2_loadrelate; wire pre_inst_is_load; + assign pre_inst_is_load = (((ex_aluop_i_1 == `EXE_LD_B_OP) || (ex_aluop_i_1 == `EXE_LD_H_OP) || (ex_aluop_i_1 == `EXE_LD_W_OP) || @@ -109,7 +105,7 @@ module id( (ex_aluop_i_1 == `EXE_LD_HU_OP) || (ex_aluop_i_1 == `EXE_ST_B_OP) || (ex_aluop_i_1 == `EXE_ST_H_OP) || - (ex_aluop_i_1 == `EXE_ST_W_OP) || + (ex_aluop_i_1 == `EXE_ST_W_OP))||( (ex_aluop_i_2 == `EXE_LD_B_OP) || (ex_aluop_i_2 == `EXE_LD_H_OP) || (ex_aluop_i_2 == `EXE_LD_W_OP) || @@ -117,7 +113,7 @@ module id( (ex_aluop_i_2 == `EXE_LD_HU_OP) || (ex_aluop_i_2 == `EXE_ST_B_OP) || (ex_aluop_i_2 == `EXE_ST_H_OP) || - (ex_aluop_i_2 == `EXE_ST_W_OP)) && (pc_i + 4 == pc_i_other)) ? 1'b1 : 1'b0; + (ex_aluop_i_2 == `EXE_ST_W_OP)) && (pc_i == pc_i_other + 4)) ? 1'b1 : 1'b0; reg excepttype_is_syscall; reg excepttype_is_break; @@ -145,8 +141,7 @@ module id( end //如果这条指令与另一条相邻且存在依赖就直接暂停 - assign stallreq = stallreq_for_reg1_loadrelate | stallreq_for_reg2_loadrelate | - ((pc_i == pc_i_other - 4) && ((reg1_addr_o == reg1_addr_i_other) | (reg2_addr_o == reg2_addr_i_other))); + assign stallreq = stallreq_for_reg1_loadrelate | stallreq_for_reg2_loadrelate; always @(*) begin diff --git a/src/vsrc/pipeline/2_decode/id_ex.v b/src/vsrc/pipeline/2_decode/id_ex.v index e6bd840..62493cf 100644 --- a/src/vsrc/pipeline/2_decode/id_ex.v +++ b/src/vsrc/pipeline/2_decode/id_ex.v @@ -29,8 +29,43 @@ module id_ex ( output reg[`RegBus] ex_link_address, output reg[`RegBus] ex_inst, output reg[1:0]ex_excepttype, - output reg[`RegBus] ex_current_inst_address + output reg[`RegBus] ex_current_inst_address, + + input wire[`RegAddrBus] reg1_addr_i, + input wire[`RegAddrBus] reg2_addr_i, + input wire[`InstAddrBus] pc_i_other, + input wire[`RegAddrBus] reg1_addr_i_other, + input wire[`RegAddrBus] reg2_addr_i_other, + input wire[`RegAddrBus] waddr_i_other, + + input stallreq_from_id, + output reg stallreq ); + + wire stallreq1; + wire stallreq2; + wire stallreq3; + wire stallreq4; + wire stallreq5; + wire stallreq6; + wire stallreq7; + + assign sallreq1 = id_inst_pc == pc_i_other + 4; + assign sallreq3 = (reg1_addr_i == reg1_addr_i_other) && reg1_addr_i != 0; + assign sallreq4 = (reg2_addr_i == reg2_addr_i_other) && reg2_addr_i != 0; + assign sallreq5 = reg1_addr_i == waddr_i_other; + assign sallreq6 = reg2_addr_i == waddr_i_other; + assign sallreq7 = stallreq3 | stallreq4 | stallreq5 | stallreq6; + + //always @(*) begin + //stallreq = stallreq_from_id | stallreq1 | stallreq7; + //end + + always @(*) begin + stallreq = stallreq_from_id | ((id_inst_pc == pc_i_other + 4) && (((reg1_addr_i == reg1_addr_i_other) && reg1_addr_i != 0 ) | ((reg2_addr_i == reg2_addr_i_other) && reg2_addr_i != 0) + | (reg1_addr_i == waddr_i_other) | (reg2_addr_i == waddr_i_other))); + end + always @(posedge clk) begin @@ -64,7 +99,7 @@ module id_ex ( ex_excepttype <= 2'b00; ex_current_inst_address <= `ZeroWord; end - else if(stall == `Stop) + else if(stall == `Stop || stallreq == `Stop) begin end diff --git a/src/vsrc/pipeline/4_mem/mem.v b/src/vsrc/pipeline/4_mem/mem.v index 74fc7f8..3ed0041 100644 --- a/src/vsrc/pipeline/4_mem/mem.v +++ b/src/vsrc/pipeline/4_mem/mem.v @@ -17,7 +17,7 @@ module mem ( input wire wb_LLbit_we_i, input wire wb_LLbit_value_i, - input wire[2:0] excepttype_i, + input wire[1:0] excepttype_i, input wire[`RegBus] current_inst_address_i, output reg[`InstAddrBus] inst_pc_o, diff --git a/src/vsrc/regfile.v b/src/vsrc/regfile.v index 48be861..7408204 100644 --- a/src/vsrc/regfile.v +++ b/src/vsrc/regfile.v @@ -91,6 +91,8 @@ end rdata1_1 = `ZeroWord; else if ((raddr1_1 == waddr_1) && (we_1 == `WriteEnable) && (re1_1 == `ReadEnable)) rdata1_1 = wdata_1; + else if ((raddr1_1 == waddr_2) && (we_2 == `WriteEnable) && (re1_1 == `ReadEnable)) + rdata1_1 = wdata_2; else if (re1_1 == `ReadEnable) rdata1_1 = regs[raddr1_1]; else @@ -105,6 +107,8 @@ end rdata1_2 = `ZeroWord; else if ((raddr1_2 == waddr_1) && (we_1 == `WriteEnable) && (re1_2 == `ReadEnable)) rdata1_2 = wdata_1; + else if ((raddr1_2 == waddr_2) && (we_2 == `WriteEnable) && (re1_2 == `ReadEnable)) + rdata1_2 = wdata_2; else if (re1_2 == `ReadEnable) rdata1_2 = regs[raddr1_2]; else @@ -117,6 +121,8 @@ end rdata2_1 = `ZeroWord; else if (raddr2_1 == `RegNumLog2'h0) rdata2_1 = `ZeroWord; + else if ((raddr2_1 == waddr_1) && (we_1 == `WriteEnable) && (re2_1 == `ReadEnable)) + rdata2_1 = wdata_1; else if ((raddr2_1 == waddr_2) && (we_2 == `WriteEnable) && (re2_1 == `ReadEnable)) rdata2_1 = wdata_2; else if (re2_1 == `ReadEnable) @@ -131,6 +137,8 @@ end rdata2_2 = `ZeroWord; else if (raddr2_2 == `RegNumLog2'h0) rdata2_2 = `ZeroWord; + else if ((raddr2_2 == waddr_1) && (we_1 == `WriteEnable) && (re2_2 == `ReadEnable)) + rdata2_2 = wdata_1; else if ((raddr2_2 == waddr_2) && (we_2 == `WriteEnable) && (re2_2 == `ReadEnable)) rdata2_2 = wdata_2; else if (re2_1 == `ReadEnable) From dd5c25b2429bda7fbe9c5371484e5b2810f74c3f Mon Sep 17 00:00:00 2001 From: Easton Man Date: Tue, 12 Apr 2022 00:16:11 +0800 Subject: [PATCH 018/114] feat: switch to 3bit ctr - refactor top module with parameters --- src/vsrc/branch_predictor/Makefile | 3 + src/vsrc/branch_predictor/gshared_predictor.v | 31 ++-- src/vsrc/branch_predictor/tage_predictor.v | 138 ++++++------------ src/vsrc/branch_predictor/testbench.cpp | 4 +- 4 files changed, 62 insertions(+), 114 deletions(-) diff --git a/src/vsrc/branch_predictor/Makefile b/src/vsrc/branch_predictor/Makefile index 60ab681..adea18d 100644 --- a/src/vsrc/branch_predictor/Makefile +++ b/src/vsrc/branch_predictor/Makefile @@ -1,6 +1,9 @@ benchmark: verilate ./benchmark.sh + +test: verilate + ./obj_dir/Vtage_predictor VERILATOR_FLAGS = -O3 +define+DUMP_WAVEFORM=1 diff --git a/src/vsrc/branch_predictor/gshared_predictor.v b/src/vsrc/branch_predictor/gshared_predictor.v index 07703d1..cbfed42 100644 --- a/src/vsrc/branch_predictor/gshared_predictor.v +++ b/src/vsrc/branch_predictor/gshared_predictor.v @@ -24,8 +24,8 @@ module gshared_predictor #( wire rst_n = ~rst; // PHT - // - entry: {2bits bimodal, xbits tag} - reg[`PHT_TAG_WIDTH+1:0] PHT[`PHT_DEPTH]; + // - entry: {3bits bimodal, xbits tag} + reg[`PHT_TAG_WIDTH+2:0] PHT[`PHT_DEPTH]; // Fold GHT input to a fix length, the same as index range @@ -62,10 +62,10 @@ module gshared_predictor #( wire [`PHT_DEPTH_LOG2-1:0] query_hashed_index = {hashed_ght_input ^ pc_i[2+`PHT_DEPTH_LOG2-1:2]}; // Query logic ////////////////////////////////// - wire [1:0] query_result_bimodal = PHT[query_hashed_index][`PHT_TAG_WIDTH+1:`PHT_TAG_WIDTH]; + wire [2:0] query_result_bimodal = PHT[query_hashed_index][`PHT_TAG_WIDTH+2:`PHT_TAG_WIDTH]; wire [`PHT_TAG_WIDTH-1:0] query_result_tag = PHT[query_hashed_index][`PHT_TAG_WIDTH-1:0]; - assign taken = (query_result_bimodal == 2'b11) | (query_result_bimodal == 2'b01); + assign taken = (query_result_bimodal[2] == 1'b1); assign tag_hit = (hashed_pc_tag == query_result_tag); // assign tag_hit = 1; @@ -103,31 +103,30 @@ module gshared_predictor #( // Reset all PHT to 01 for (integer i = 0; i < `PHT_DEPTH; i = i + 1) begin - PHT[i] = {2'b01,{`PHT_TAG_WIDTH{1'b0}}}; + PHT[i] = {3'b100,{`PHT_TAG_WIDTH{1'b0}}}; end end else begin if (branch_valid) begin - case (PHT[update_index][`PHT_TAG_WIDTH+1:`PHT_TAG_WIDTH]) // 00,10 | 01,11 - 2'b00: - begin - PHT[update_index][`PHT_TAG_WIDTH+1:`PHT_TAG_WIDTH] <= branch_taken ? 2'b10: 2'b00; - end - 2'b10: + // 000,001,010,011 | 100,101,110,111 + + case(PHT[update_index][`PHT_TAG_WIDTH+2:`PHT_TAG_WIDTH]) + 3'b000: begin - PHT[update_index][`PHT_TAG_WIDTH+1:`PHT_TAG_WIDTH] <= branch_taken ? 2'b01: 2'b00; + PHT[update_index][`PHT_TAG_WIDTH+2:`PHT_TAG_WIDTH] <= branch_taken ? 3'b001 : 3'b000; end - 2'b01: + 3'b111: begin - PHT[update_index][`PHT_TAG_WIDTH+1:`PHT_TAG_WIDTH] <= branch_taken ? 2'b11: 2'b10; + PHT[update_index][`PHT_TAG_WIDTH+2:`PHT_TAG_WIDTH] <= branch_taken ? 3'b111 : 3'b110; end - 2'b11: + default: begin - PHT[update_index][`PHT_TAG_WIDTH+1:`PHT_TAG_WIDTH] <= branch_taken ? 2'b11: 2'b01; + PHT[update_index][`PHT_TAG_WIDTH+2:`PHT_TAG_WIDTH] <= branch_taken ? PHT[update_index][`PHT_TAG_WIDTH+2:`PHT_TAG_WIDTH] +1 : PHT[update_index][`PHT_TAG_WIDTH+2:`PHT_TAG_WIDTH] -1; end endcase + if (PHT[update_index][`PHT_TAG_WIDTH-1:0] != update_tag) // Miss tag begin // Do swap PHT[update_index][`PHT_TAG_WIDTH-1:0]<= {update_tag}; diff --git a/src/vsrc/branch_predictor/tage_predictor.v b/src/vsrc/branch_predictor/tage_predictor.v index 02919d6..3be2826 100644 --- a/src/vsrc/branch_predictor/tage_predictor.v +++ b/src/vsrc/branch_predictor/tage_predictor.v @@ -62,103 +62,49 @@ module tage_predictor ( // Tagged Predictors - wire t1_taken; - wire t1_hit; - wire t2_taken; - wire t2_hit; - wire t3_taken; - wire t3_hit; - wire t4_taken; - wire t4_hit; - - gshared_predictor - #( - .GLOBAL_HISTORY_LENGTH (5) - ) - t1( - .clk (clk ), - .rst (rst ), - .global_history_i (GHR ), - .pc_i (pc_i ), - .branch_valid (branch_valid_i ), - .branch_taken (branch_taken_i ), - .taken (t1_taken ), - .tag_hit (t1_hit) - ); - - gshared_predictor - #( - .GLOBAL_HISTORY_LENGTH (10) - ) - t2( - .clk (clk ), - .rst (rst ), - .global_history_i (GHR ), - .pc_i (pc_i ), - .branch_valid (branch_valid_i ), - .branch_taken (branch_taken_i ), - .taken (t2_taken ), - .tag_hit(t2_hit) - ); - - gshared_predictor - #( - .GLOBAL_HISTORY_LENGTH (20) - ) - t3( - .clk (clk ), - .rst (rst ), - .global_history_i (GHR ), - .pc_i (pc_i ), - .branch_valid (branch_valid_i ), - .branch_taken (branch_taken_i ), - .taken (t3_taken ), - .tag_hit(t3_hit) - ); - - gshared_predictor - #( - .GLOBAL_HISTORY_LENGTH (40) - ) - t4( - .clk (clk ), - .rst (rst ), - .global_history_i (GHR ), - .pc_i (pc_i ), - .branch_valid (branch_valid_i ), - .branch_taken (branch_taken_i ), - .taken (t4_taken ), - .tag_hit (t4_hit) - ); - - - always @(posedge clk) + wire[3:0] taken; + wire[3:0] tag_hit; + reg[1:0] accept_prediction_id; + localparam integer provider_ghr_length[4] = '{5,10,20,40}; + + generate + genvar provider_id; + for (provider_id = 0; provider_id <4; provider_id = provider_id +1) + begin + gshared_predictor + #( + .GLOBAL_HISTORY_LENGTH (provider_ghr_length[0]) + ) + t1( + .clk (clk ), + .rst (rst ), + .global_history_i (GHR ), + .pc_i (pc_i ), + .branch_valid (branch_valid_i ), + .branch_taken (branch_taken_i ), + .taken (taken[provider_id]), + .tag_hit (tag_hit[provider_id]) + ); + end + endgenerate + + + always @(*) begin - if (t4_hit) - begin - predict_branch_taken_o <= t4_taken; - perf_tag_hit_counter[31:0] <= perf_tag_hit_counter[31:0] +1; - end - else if(t3_hit) - begin - predict_branch_taken_o <= t3_taken; - perf_tag_hit_counter[2*32-1:32] <= perf_tag_hit_counter[2*32-1:32] +1; - end - else if(t2_hit) - begin - predict_branch_taken_o <= t2_taken; - // perf_tag_hit_counter[2] <= perf_tag_hit_counter[2] +1; - end - else if(t1_hit) - begin - predict_branch_taken_o <= t1_taken; - // perf_tag_hit_counter[3] <= perf_tag_hit_counter[3] +1; - end - else - begin - predict_branch_taken_o <= 1; - // perf_tag_hit_counter[4] <= perf_tag_hit_counter[4] +1; - end + casez (tag_hit) + 4'b1???: + accept_prediction_id = 3; + 4'b01??: + accept_prediction_id = 2; + 4'b001?: + accept_prediction_id = 1; + 4'b0001: + accept_prediction_id = 0; + default: + accept_prediction_id = 0; + endcase end + assign predict_branch_taken_o = taken[accept_prediction_id]; + endmodule //tage_predictor diff --git a/src/vsrc/branch_predictor/testbench.cpp b/src/vsrc/branch_predictor/testbench.cpp index 0e39c54..c83f929 100644 --- a/src/vsrc/branch_predictor/testbench.cpp +++ b/src/vsrc/branch_predictor/testbench.cpp @@ -12,7 +12,7 @@ // Work around double sc_time_stamp() { return 0; } -static std::string test_filename = "data/traces/trace_01"; +static std::string test_filename = "data/gcc-8M.txt"; struct instruction_entry { @@ -132,7 +132,7 @@ int main(int argc, char const *argv[]) sopc->final(); // First predicto is invalid - prediction_taken.pop_front(); + // prediction_taken.pop_front(); // Statistics uint64_t correct = 0; From 9b12bae121a2cfd323f9f27b1b2f61ed4bcc6862 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Tue, 12 Apr 2022 11:01:17 +0800 Subject: [PATCH 019/114] feat: implement base predictor --- src/vsrc/branch_predictor/base_predictor.v | 65 ++++++++++++++++++++++ src/vsrc/branch_predictor/tage_predictor.v | 54 ++++++++++++++---- 2 files changed, 109 insertions(+), 10 deletions(-) create mode 100644 src/vsrc/branch_predictor/base_predictor.v diff --git a/src/vsrc/branch_predictor/base_predictor.v b/src/vsrc/branch_predictor/base_predictor.v new file mode 100644 index 0000000..c487c8f --- /dev/null +++ b/src/vsrc/branch_predictor/base_predictor.v @@ -0,0 +1,65 @@ +// Base Predictor is a pure PC-indexed bimodal table + +module base_predictor #( + parameter TABLE_DEPTH_EXP2 = 10, + parameter CTR_WIDTH = 2, + parameter PC_WIDTH = 32 + ) ( + input wire clk, + input wire rst, + input wire [PC_WIDTH-1:0] pc_i, + + // Update signals + input wire update_valid, + input wire[PC_WIDTH:0] update_instr_info, + // update_instr_info + // [pc, taken] + + // Query output signals + output wire taken + ); + + // Table + reg[CTR_WIDTH-1:0] PHT[2**TABLE_DEPTH_EXP2]; + + // Reset signal + wire rst_n = ~rst; + + // Reset + always @(negedge rst_n) + begin + if (!rst_n) + begin + for (integer i= 0; i< 2**TABLE_DEPTH_EXP2; i = i + 1) + begin + PHT[i] = {1'b1, {CTR_WIDTH-1{1'b0}}}; + end + end + end + + // Query logic + wire[TABLE_DEPTH_EXP2-1:0] query_index = pc_i[2+TABLE_DEPTH_EXP2-1:2]; + wire[CTR_WIDTH-1:0] query_entry = PHT[query_index]; + + assign taken = (query_entry[CTR_WIDTH-1] == 1'b1); + + // Update logic + wire[PC_WIDTH-1:0] update_pc = update_instr_info[PC_WIDTH:1]; + wire[TABLE_DEPTH_EXP2-1:0] update_index = update_pc[TABLE_DEPTH_EXP2+1:2]; + wire update_taken = update_instr_info[0]; + always @(posedge clk) + begin + if (PHT[update_index] == {CTR_WIDTH{1'b1}}) + begin + PHT[update_index] <= update_taken? PHT[update_index] : PHT[update_index]-1; + end + else if(PHT[update_index] == {CTR_WIDTH{1'b0}}) + begin + PHT[update_index] <= update_taken? PHT[update_index] +1: PHT[update_index]; + end + else + begin + PHT[update_index] <= update_taken? PHT[update_index] +1: PHT[update_index]-1; + end + end +endmodule diff --git a/src/vsrc/branch_predictor/tage_predictor.v b/src/vsrc/branch_predictor/tage_predictor.v index 3be2826..e212a45 100644 --- a/src/vsrc/branch_predictor/tage_predictor.v +++ b/src/vsrc/branch_predictor/tage_predictor.v @@ -59,18 +59,37 @@ module tage_predictor ( .btb_hit (btb_hit ) ); + // Base Predictor + wire base_taken; + base_predictor + #( + .TABLE_DEPTH_EXP2 (12), + .CTR_WIDTH (2), + .PC_WIDTH (`RegWidth) + ) + u_base_predictor( + .clk (clk ), + .rst (rst ), + .pc_i (pc_i ), + .update_valid (branch_valid_i ), + .update_instr_info ({branch_pc_i, branch_taken_i}), + .taken (base_taken ) + ); + + // Tagged Predictors - wire[3:0] taken; + wire[3:0] tag_taken; wire[3:0] tag_hit; - reg[1:0] accept_prediction_id; + reg[2:0] accept_prediction_id; localparam integer provider_ghr_length[4] = '{5,10,20,40}; generate genvar provider_id; for (provider_id = 0; provider_id <4; provider_id = provider_id +1) begin + wire valid = (accept_prediction_id == provider_id) ? branch_valid_i : 0; gshared_predictor #( .GLOBAL_HISTORY_LENGTH (provider_ghr_length[0]) @@ -80,9 +99,9 @@ module tage_predictor ( .rst (rst ), .global_history_i (GHR ), .pc_i (pc_i ), - .branch_valid (branch_valid_i ), + .branch_valid (valid ), .branch_taken (branch_taken_i ), - .taken (taken[provider_id]), + .taken (tag_taken[provider_id]), .tag_hit (tag_hit[provider_id]) ); end @@ -93,18 +112,33 @@ module tage_predictor ( begin casez (tag_hit) 4'b1???: - accept_prediction_id = 3; + accept_prediction_id = 4; 4'b01??: - accept_prediction_id = 2; + accept_prediction_id = 3; 4'b001?: - accept_prediction_id = 1; + accept_prediction_id = 2; 4'b0001: - accept_prediction_id = 0; - default: + accept_prediction_id = 1; + default: // Use base predictor accept_prediction_id = 0; endcase end - + wire[4: + 0] taken = {tag_taken, base_taken}; assign predict_branch_taken_o = taken[accept_prediction_id]; + // Counter + generate + genvar i; + for (i=0; + i<5; + i=i+1) + begin + always @(posedge clk) + begin + perf_tag_hit_counter[i*32+31:i*32] <= perf_tag_hit_counter[i*32+31:i*32] + {31'b0,(i == accept_prediction_id)}; + end + end + endgenerate + endmodule //tage_predictor From c4002f3cfbe10053414cdfee7a3059704c9178a7 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Tue, 12 Apr 2022 11:08:54 +0800 Subject: [PATCH 020/114] fix: fix base predictor update policy --- src/vsrc/branch_predictor/base_predictor.v | 23 ++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/vsrc/branch_predictor/base_predictor.v b/src/vsrc/branch_predictor/base_predictor.v index c487c8f..6fce3c8 100644 --- a/src/vsrc/branch_predictor/base_predictor.v +++ b/src/vsrc/branch_predictor/base_predictor.v @@ -49,17 +49,20 @@ module base_predictor #( wire update_taken = update_instr_info[0]; always @(posedge clk) begin - if (PHT[update_index] == {CTR_WIDTH{1'b1}}) + if (update_valid) begin - PHT[update_index] <= update_taken? PHT[update_index] : PHT[update_index]-1; - end - else if(PHT[update_index] == {CTR_WIDTH{1'b0}}) - begin - PHT[update_index] <= update_taken? PHT[update_index] +1: PHT[update_index]; - end - else - begin - PHT[update_index] <= update_taken? PHT[update_index] +1: PHT[update_index]-1; + if (PHT[update_index] == {CTR_WIDTH{1'b1}}) + begin + PHT[update_index] <= update_taken? PHT[update_index] : PHT[update_index]-1; + end + else if(PHT[update_index] == {CTR_WIDTH{1'b0}}) + begin + PHT[update_index] <= update_taken? PHT[update_index] +1: PHT[update_index]; + end + else + begin + PHT[update_index] <= update_taken? PHT[update_index] +1: PHT[update_index]-1; + end end end endmodule From 59123996405cac87822f61e5cb7821c4178d1a8a Mon Sep 17 00:00:00 2001 From: Easton Man Date: Tue, 12 Apr 2022 16:25:10 +0800 Subject: [PATCH 021/114] refactor: tag predictor now do not depend on latency --- src/vsrc/branch_predictor/defines.v | 4 - src/vsrc/branch_predictor/folder_func.v | 3 +- src/vsrc/branch_predictor/gshared_predictor.v | 138 ++++++++++++------ src/vsrc/branch_predictor/tage_predictor.v | 39 +++-- src/vsrc/branch_predictor/testbench.cpp | 4 +- src/vsrc/branch_predictor/utils/fpa.v | 41 ++++++ 6 files changed, 155 insertions(+), 74 deletions(-) create mode 100644 src/vsrc/branch_predictor/utils/fpa.v diff --git a/src/vsrc/branch_predictor/defines.v b/src/vsrc/branch_predictor/defines.v index dcf18a6..76961f9 100644 --- a/src/vsrc/branch_predictor/defines.v +++ b/src/vsrc/branch_predictor/defines.v @@ -7,10 +7,6 @@ `define BTB_ENTRY_LENGTH `BTB_TAG_LENGTH + 30 // tag[], target[30] `define BTB_ENTRY_BUS `BTB_ENTRY_LENGTH-1:0 -// PHT parameters (Pattern History Table) -`define PHT_DEPTH 1024 -`define PHT_DEPTH_LOG2 10 -`define PHT_TAG_WIDTH 8 // GHR parameters (Global History Register) diff --git a/src/vsrc/branch_predictor/folder_func.v b/src/vsrc/branch_predictor/folder_func.v index ae1d7b8..504f4e0 100644 --- a/src/vsrc/branch_predictor/folder_func.v +++ b/src/vsrc/branch_predictor/folder_func.v @@ -33,7 +33,6 @@ module folder_func #( end endgenerate - assign var_o = workspace[MAX_FOLD_ROUND-1][OUTPUT_LENGTH-1: - 0]; + assign var_o = workspace[MAX_FOLD_ROUND-1][OUTPUT_LENGTH-1:0]; endmodule diff --git a/src/vsrc/branch_predictor/gshared_predictor.v b/src/vsrc/branch_predictor/gshared_predictor.v index cbfed42..131e79a 100644 --- a/src/vsrc/branch_predictor/gshared_predictor.v +++ b/src/vsrc/branch_predictor/gshared_predictor.v @@ -2,20 +2,29 @@ `include "../defines.v" `include "branch_predictor/defines.v" `include "branch_predictor/folder_func.v" +`include "branch_predictor/utils/fpa.v" module gshared_predictor #( - parameter GLOBAL_HISTORY_LENGTH = 4 + parameter INPUT_GHR_LENGTH = 4, + parameter PC_WIDTH = 32, + parameter PHT_DEPTH_EXP2 = 10, + parameter PHT_TAG_WIDTH = 10, + parameter HASH_BUFFER_SIZE = 10 ) ( input wire clk, input wire rst, - input wire [`GHR_BUS] global_history_i, - input wire [`RegBus] pc_i, + input wire [INPUT_GHR_LENGTH-1:0] global_history_i, + input wire [PC_WIDTH-1:0] pc_i, // Update signals - input wire branch_valid, - input wire branch_taken, + input wire update_valid, + input wire[PC_WIDTH:0] update_instr_info, + // update_instr_info + // [pc, taken] + + // Query output signal output wire taken, output wire tag_hit ); @@ -23,32 +32,36 @@ module gshared_predictor #( // Reset wire rst_n = ~rst; + // Unpack update instr info + wire [PC_WIDTH-1:0] update_pc = update_instr_info[PC_WIDTH:1]; + wire update_taken = update_instr_info[0]; + // PHT // - entry: {3bits bimodal, xbits tag} - reg[`PHT_TAG_WIDTH+2:0] PHT[`PHT_DEPTH]; + reg[PHT_TAG_WIDTH+2:0] PHT[2**PHT_DEPTH_EXP2]; // Fold GHT input to a fix length, the same as index range - wire [`PHT_DEPTH_LOG2-1:0] hashed_ght_input; + wire [PHT_DEPTH_EXP2-1:0] hashed_ght_input; folder_func #( - .INPUT_LENGTH (GLOBAL_HISTORY_LENGTH), - .OUTPUT_LENGTH (`PHT_DEPTH_LOG2), - .MAX_FOLD_ROUND (4) + .INPUT_LENGTH (INPUT_GHR_LENGTH), + .OUTPUT_LENGTH (PHT_DEPTH_EXP2), + .MAX_FOLD_ROUND (6) ) ght_hash( - .var_i (global_history_i[GLOBAL_HISTORY_LENGTH-1:0]), + .var_i (global_history_i), .var_o (hashed_ght_input) ); // Tag // wire [`PHT_TAG_WIDTH-1:0] hashed_pc_tag = pc_i[2+`PHT_TAG_WIDTH-1:2]; - wire [`PHT_TAG_WIDTH-1:0] hashed_pc_tag; + wire [PHT_TAG_WIDTH-1:0] hashed_pc_tag; folder_func #( - .INPUT_LENGTH (`RegWidth), - .OUTPUT_LENGTH (`PHT_TAG_WIDTH), - .MAX_FOLD_ROUND (3) + .INPUT_LENGTH (PC_WIDTH), + .OUTPUT_LENGTH (PHT_TAG_WIDTH), + .MAX_FOLD_ROUND (4) ) pc_hash( .var_i(pc_i), @@ -59,77 +72,114 @@ module gshared_predictor #( // hash with pc, and concatenate to `PHT_DEPTH_LOG2 // the low 2bits of pc is usually 0, so use upper bits - wire [`PHT_DEPTH_LOG2-1:0] query_hashed_index = {hashed_ght_input ^ pc_i[2+`PHT_DEPTH_LOG2-1:2]}; + wire [PHT_DEPTH_EXP2-1:0] query_hashed_index = {hashed_ght_input ^ pc_i[2+PHT_DEPTH_EXP2-1:2]}; // Query logic ////////////////////////////////// - wire [2:0] query_result_bimodal = PHT[query_hashed_index][`PHT_TAG_WIDTH+2:`PHT_TAG_WIDTH]; - wire [`PHT_TAG_WIDTH-1:0] query_result_tag = PHT[query_hashed_index][`PHT_TAG_WIDTH-1:0]; + wire [2:0] query_result_bimodal = PHT[query_hashed_index][PHT_TAG_WIDTH+2:PHT_TAG_WIDTH]; + wire [PHT_TAG_WIDTH-1:0] query_result_tag = PHT[query_hashed_index][PHT_TAG_WIDTH-1:0]; assign taken = (query_result_bimodal[2] == 1'b1); assign tag_hit = (hashed_pc_tag == query_result_tag); // assign tag_hit = 1; + // Use a buffer to hold the query_index and pc + // entry: {valid 1, pc PC_WIDTH, query_index} + localparam HASH_BUFFER_WIDTH = 1 + PC_WIDTH + PHT_DEPTH_EXP2; + reg [HASH_BUFFER_WIDTH-1:0] hash_buffer[HASH_BUFFER_SIZE]; + wire [HASH_BUFFER_SIZE-1:0] pc_match_table; // indicates which entry in the buffer is a match - // Update logic ////////////////////////////////// - - // This buffer is used to store the hashed index for update - reg[`PHT_DEPTH_LOG2-1:0] hashed_index_buffer [`FEEDBACK_LATENCY]; - reg[`PHT_TAG_WIDTH-1:0] tag_buffer [`FEEDBACK_LATENCY]; - always @(posedge clk) - begin - hashed_index_buffer[0] <= query_hashed_index; - tag_buffer[0] <= hashed_pc_tag; - end - genvar index_id; + // Move from lower to higher + // always @(posedge clk) + // begin + assign hash_buffer[0] = {(pc_i != 0), pc_i, query_hashed_index}; + // end generate - for (index_id = 1; index_id < `FEEDBACK_LATENCY; index_id = index_id + 1) + for (genvar i = 1; i #include -#define BRANCH_LATENCY (5) +#define BRANCH_LATENCY (3) // Work around double sc_time_stamp() { return 0; } -static std::string test_filename = "data/gcc-8M.txt"; +static std::string test_filename = "data/traces/trace_02"; struct instruction_entry { diff --git a/src/vsrc/branch_predictor/utils/fpa.v b/src/vsrc/branch_predictor/utils/fpa.v new file mode 100644 index 0000000..ff7e853 --- /dev/null +++ b/src/vsrc/branch_predictor/utils/fpa.v @@ -0,0 +1,41 @@ +// FPA detect the first 1 in input, from high to low + +`ifndef FPA_V +`define FPA_V + +module fpa #( + parameter LINES = 16, + parameter WIDTH = $clog2(LINES) + )( + input wire [LINES-1:0] unitary_in, + output reg [WIDTH-1:0] binary_out + ); + + reg [LINES-1:0] fliped_in; + + always @(*) + begin + for (integer i = 0; i Date: Wed, 13 Apr 2022 11:25:01 +0800 Subject: [PATCH 022/114] refactor: change code indent --- src/vsrc/branch_predictor/base_predictor.v | 89 +++--- src/vsrc/branch_predictor/gshared_predictor.v | 284 +++++++++--------- src/vsrc/branch_predictor/tage_predictor.v | 210 ++++++------- 3 files changed, 277 insertions(+), 306 deletions(-) diff --git a/src/vsrc/branch_predictor/base_predictor.v b/src/vsrc/branch_predictor/base_predictor.v index 6fce3c8..fddc517 100644 --- a/src/vsrc/branch_predictor/base_predictor.v +++ b/src/vsrc/branch_predictor/base_predictor.v @@ -1,67 +1,58 @@ // Base Predictor is a pure PC-indexed bimodal table -module base_predictor #( - parameter TABLE_DEPTH_EXP2 = 10, - parameter CTR_WIDTH = 2, - parameter PC_WIDTH = 32 - ) ( - input wire clk, - input wire rst, - input wire [PC_WIDTH-1:0] pc_i, - - // Update signals - input wire update_valid, - input wire[PC_WIDTH:0] update_instr_info, - // update_instr_info - // [pc, taken] - - // Query output signals - output wire taken - ); - - // Table - reg[CTR_WIDTH-1:0] PHT[2**TABLE_DEPTH_EXP2]; - - // Reset signal - wire rst_n = ~rst; - - // Reset - always @(negedge rst_n) +module base_predictor #(parameter TABLE_DEPTH_EXP2 = 10, + parameter CTR_WIDTH = 2, + parameter PC_WIDTH = 32) + (input wire clk, + input wire rst, + input wire [PC_WIDTH-1:0] pc_i, + input wire update_valid, + input wire[PC_WIDTH:0] update_instr_info, + output wire taken); + + // Table + reg[CTR_WIDTH-1:0] PHT[2**TABLE_DEPTH_EXP2]; + + // Reset signal + wire rst_n = ~rst; + + // Reset + always @(negedge rst_n) begin - if (!rst_n) + if (!rst_n) begin - for (integer i= 0; i< 2**TABLE_DEPTH_EXP2; i = i + 1) + for (integer i = 0; i< 2**TABLE_DEPTH_EXP2; i = i + 1) begin - PHT[i] = {1'b1, {CTR_WIDTH-1{1'b0}}}; + PHT[i] = {1'b1, {CTR_WIDTH-1{1'b0}}}; end end end - - // Query logic - wire[TABLE_DEPTH_EXP2-1:0] query_index = pc_i[2+TABLE_DEPTH_EXP2-1:2]; - wire[CTR_WIDTH-1:0] query_entry = PHT[query_index]; - - assign taken = (query_entry[CTR_WIDTH-1] == 1'b1); - - // Update logic - wire[PC_WIDTH-1:0] update_pc = update_instr_info[PC_WIDTH:1]; - wire[TABLE_DEPTH_EXP2-1:0] update_index = update_pc[TABLE_DEPTH_EXP2+1:2]; - wire update_taken = update_instr_info[0]; - always @(posedge clk) + + // Query logic + wire[TABLE_DEPTH_EXP2-1:0] query_index = pc_i[2+TABLE_DEPTH_EXP2-1:2]; + wire[CTR_WIDTH-1:0] query_entry = PHT[query_index]; + + assign taken = (query_entry[CTR_WIDTH-1] == 1'b1); + + // Update logic + wire[PC_WIDTH-1:0] update_pc = update_instr_info[PC_WIDTH:1]; + wire[TABLE_DEPTH_EXP2-1:0] update_index = update_pc[TABLE_DEPTH_EXP2+1:2]; + wire update_taken = update_instr_info[0]; + always @(posedge clk) begin - if (update_valid) + if (update_valid) begin - if (PHT[update_index] == {CTR_WIDTH{1'b1}}) + if (PHT[update_index] == {CTR_WIDTH{1'b1}}) begin - PHT[update_index] <= update_taken? PHT[update_index] : PHT[update_index]-1; + PHT[update_index] <= update_taken? PHT[update_index] : PHT[update_index]-1; end - else if(PHT[update_index] == {CTR_WIDTH{1'b0}}) + else if (PHT[update_index] == {CTR_WIDTH{1'b0}}) begin - PHT[update_index] <= update_taken? PHT[update_index] +1: PHT[update_index]; + PHT[update_index] <= update_taken? PHT[update_index] +1: PHT[update_index]; end - else + else begin - PHT[update_index] <= update_taken? PHT[update_index] +1: PHT[update_index]-1; + PHT[update_index] <= update_taken? PHT[update_index] +1: PHT[update_index]-1; end end end diff --git a/src/vsrc/branch_predictor/gshared_predictor.v b/src/vsrc/branch_predictor/gshared_predictor.v index 131e79a..0a12ed0 100644 --- a/src/vsrc/branch_predictor/gshared_predictor.v +++ b/src/vsrc/branch_predictor/gshared_predictor.v @@ -5,184 +5,174 @@ `include "branch_predictor/utils/fpa.v" -module gshared_predictor #( - parameter INPUT_GHR_LENGTH = 4, - parameter PC_WIDTH = 32, - parameter PHT_DEPTH_EXP2 = 10, - parameter PHT_TAG_WIDTH = 10, - parameter HASH_BUFFER_SIZE = 10 - ) ( - input wire clk, - input wire rst, - input wire [INPUT_GHR_LENGTH-1:0] global_history_i, - input wire [PC_WIDTH-1:0] pc_i, - - // Update signals - input wire update_valid, - input wire[PC_WIDTH:0] update_instr_info, - // update_instr_info - // [pc, taken] - - - // Query output signal - output wire taken, - output wire tag_hit - ); - - // Reset - wire rst_n = ~rst; - - // Unpack update instr info - wire [PC_WIDTH-1:0] update_pc = update_instr_info[PC_WIDTH:1]; - wire update_taken = update_instr_info[0]; - - // PHT - // - entry: {3bits bimodal, xbits tag} - reg[PHT_TAG_WIDTH+2:0] PHT[2**PHT_DEPTH_EXP2]; - - - // Fold GHT input to a fix length, the same as index range - wire [PHT_DEPTH_EXP2-1:0] hashed_ght_input; - folder_func +module gshared_predictor #(parameter INPUT_GHR_LENGTH = 4, + parameter PC_WIDTH = 32, + parameter PHT_DEPTH_EXP2 = 10, + parameter PHT_TAG_WIDTH = 10, + parameter HASH_BUFFER_SIZE = 10) + (input wire clk, + input wire rst, + input wire [INPUT_GHR_LENGTH-1:0] global_history_i, + input wire [PC_WIDTH-1:0] pc_i, + input wire update_valid, + input wire[PC_WIDTH:0] update_instr_info, + output wire taken, + output wire tag_hit); + + // Reset + wire rst_n = ~rst; + + // Unpack update instr info + wire [PC_WIDTH-1:0] update_pc = update_instr_info[PC_WIDTH:1]; + wire update_taken = update_instr_info[0]; + + // PHT + // - entry: {3bits bimodal, xbits tag} + reg[PHT_TAG_WIDTH+2:0] PHT[2**PHT_DEPTH_EXP2]; + + + // Fold GHT input to a fix length, the same as index range + wire [PHT_DEPTH_EXP2-1:0] hashed_ght_input; + folder_func #( - .INPUT_LENGTH (INPUT_GHR_LENGTH), - .OUTPUT_LENGTH (PHT_DEPTH_EXP2), - .MAX_FOLD_ROUND (6) + .INPUT_LENGTH (INPUT_GHR_LENGTH), + .OUTPUT_LENGTH (PHT_DEPTH_EXP2), + .MAX_FOLD_ROUND (6) ) ght_hash( - .var_i (global_history_i), - .var_o (hashed_ght_input) + .var_i (global_history_i), + .var_o (hashed_ght_input) ); - - // Tag - // wire [`PHT_TAG_WIDTH-1:0] hashed_pc_tag = pc_i[2+`PHT_TAG_WIDTH-1:2]; - wire [PHT_TAG_WIDTH-1:0] hashed_pc_tag; - folder_func + + // Tag + // wire [`PHT_TAG_WIDTH-1:0] hashed_pc_tag = pc_i[2+`PHT_TAG_WIDTH-1:2]; + wire [PHT_TAG_WIDTH-1:0] hashed_pc_tag; + folder_func #( - .INPUT_LENGTH (PC_WIDTH), - .OUTPUT_LENGTH (PHT_TAG_WIDTH), - .MAX_FOLD_ROUND (4) + .INPUT_LENGTH (PC_WIDTH), + .OUTPUT_LENGTH (PHT_TAG_WIDTH), + .MAX_FOLD_ROUND (4) ) pc_hash( - .var_i(pc_i), - .var_o (hashed_pc_tag) + .var_i(pc_i), + .var_o (hashed_pc_tag) ); - - - - // hash with pc, and concatenate to `PHT_DEPTH_LOG2 - // the low 2bits of pc is usually 0, so use upper bits - wire [PHT_DEPTH_EXP2-1:0] query_hashed_index = {hashed_ght_input ^ pc_i[2+PHT_DEPTH_EXP2-1:2]}; - - // Query logic ////////////////////////////////// - wire [2:0] query_result_bimodal = PHT[query_hashed_index][PHT_TAG_WIDTH+2:PHT_TAG_WIDTH]; - wire [PHT_TAG_WIDTH-1:0] query_result_tag = PHT[query_hashed_index][PHT_TAG_WIDTH-1:0]; - - assign taken = (query_result_bimodal[2] == 1'b1); - assign tag_hit = (hashed_pc_tag == query_result_tag); - // assign tag_hit = 1; - - - // Use a buffer to hold the query_index and pc - // entry: {valid 1, pc PC_WIDTH, query_index} - localparam HASH_BUFFER_WIDTH = 1 + PC_WIDTH + PHT_DEPTH_EXP2; - reg [HASH_BUFFER_WIDTH-1:0] hash_buffer[HASH_BUFFER_SIZE]; - wire [HASH_BUFFER_SIZE-1:0] pc_match_table; // indicates which entry in the buffer is a match - - // Move from lower to higher - // always @(posedge clk) - // begin - assign hash_buffer[0] = {(pc_i != 0), pc_i, query_hashed_index}; - // end - generate + + + + // hash with pc, and concatenate to `PHT_DEPTH_LOG2 + // the low 2bits of pc is usually 0, so use upper bits + wire [PHT_DEPTH_EXP2-1:0] query_hashed_index = {hashed_ght_input ^ pc_i[2+PHT_DEPTH_EXP2-1:2]}; + + // Query logic ========================================== + wire [2:0] query_result_bimodal = PHT[query_hashed_index][PHT_TAG_WIDTH+2:PHT_TAG_WIDTH]; + wire [PHT_TAG_WIDTH-1:0] query_result_tag = PHT[query_hashed_index][PHT_TAG_WIDTH-1:0]; + + assign taken = (query_result_bimodal[2] == 1'b1); + assign tag_hit = (hashed_pc_tag == query_result_tag); + // assign tag_hit = 1; + + + // Use a buffer to hold the query_index and pc + // entry: {valid 1, pc PC_WIDTH, query_index} + localparam HASH_BUFFER_WIDTH = 1 + PC_WIDTH + PHT_DEPTH_EXP2; + reg [HASH_BUFFER_WIDTH-1:0] hash_buffer[HASH_BUFFER_SIZE]; + wire [HASH_BUFFER_SIZE-1:0] pc_match_table; // indicates which entry in the buffer is a match + + // Move from lower to higher + // always @(posedge clk) + // begin + assign hash_buffer[0] = {(pc_i != 0), pc_i, query_hashed_index}; + // end + generate for (genvar i = 1; i Date: Wed, 13 Apr 2022 14:21:45 +0800 Subject: [PATCH 023/114] fix data related bug --- src/vsrc/cpu_top.v | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/vsrc/cpu_top.v b/src/vsrc/cpu_top.v index 0af2e22..ab606ef 100644 --- a/src/vsrc/cpu_top.v +++ b/src/vsrc/cpu_top.v @@ -60,9 +60,12 @@ module cpu_top ( wire[`InstAddrBus] pc_2; wire chip_enable; + wire [`InstAddrBus]pc_buffer_1; + wire [`InstAddrBus]pc_buffer_2; + assign ram_en_o = chip_enable; - assign ram_raddr_o_1 = pc_1; - assign ram_raddr_o_2 = pc_2; + assign ram_raddr_o_1 = pc_buffer_1; + assign ram_raddr_o_2 = pc_buffer_2; wire branch_flag; assign Instram_branch_flag=branch_flag; @@ -87,8 +90,6 @@ module cpu_top ( .stall2(stall2[0]) ); - wire [`InstAddrBus]pc_buffer_1; - wire [`InstAddrBus]pc_buffer_2; wire if_inst_valid_1; wire if_inst_valid_2; From 1a0f5b448508fb617f0e3309cb76740673ce05c5 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Thu, 14 Apr 2022 21:45:20 +0800 Subject: [PATCH 024/114] refactor: use system verilog syntax --- .gitignore | 4 + src/vsrc/branch_predictor/Makefile | 2 +- src/vsrc/branch_predictor/gshared_predictor.v | 178 ------------------ src/vsrc/branch_predictor/tage_predictor.sv | 119 ++++++++++++ src/vsrc/branch_predictor/tage_predictor.v | 129 ------------- src/vsrc/branch_predictor/tagged_predictor.sv | 162 ++++++++++++++++ 6 files changed, 286 insertions(+), 308 deletions(-) delete mode 100644 src/vsrc/branch_predictor/gshared_predictor.v create mode 100644 src/vsrc/branch_predictor/tage_predictor.sv delete mode 100644 src/vsrc/branch_predictor/tage_predictor.v create mode 100644 src/vsrc/branch_predictor/tagged_predictor.sv diff --git a/.gitignore b/.gitignore index efc1d91..79379bf 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,7 @@ build/ # Branch Predictor Test data src/vsrc/branch_predictor/data + +# System Verilog language server +.svlint.toml +.svls.toml diff --git a/src/vsrc/branch_predictor/Makefile b/src/vsrc/branch_predictor/Makefile index adea18d..51682a7 100644 --- a/src/vsrc/branch_predictor/Makefile +++ b/src/vsrc/branch_predictor/Makefile @@ -10,7 +10,7 @@ VERILATOR_FLAGS = -O3 +define+DUMP_WAVEFORM=1 #--trace verilate: *.v - verilator $(VERILATOR_FLAGS) tage_predictor.v --exe testbench.cpp --cc -I../ | true # Ignore errors + verilator $(VERILATOR_FLAGS) tage_predictor.sv --exe testbench.cpp --cc -I../ | true # Ignore errors @make -C obj_dir -f Vtage_predictor.mk 2>&1 >/dev/null clean: diff --git a/src/vsrc/branch_predictor/gshared_predictor.v b/src/vsrc/branch_predictor/gshared_predictor.v deleted file mode 100644 index 0a12ed0..0000000 --- a/src/vsrc/branch_predictor/gshared_predictor.v +++ /dev/null @@ -1,178 +0,0 @@ -// Gshared predictor as base predictor -`include "../defines.v" -`include "branch_predictor/defines.v" -`include "branch_predictor/folder_func.v" -`include "branch_predictor/utils/fpa.v" - - -module gshared_predictor #(parameter INPUT_GHR_LENGTH = 4, - parameter PC_WIDTH = 32, - parameter PHT_DEPTH_EXP2 = 10, - parameter PHT_TAG_WIDTH = 10, - parameter HASH_BUFFER_SIZE = 10) - (input wire clk, - input wire rst, - input wire [INPUT_GHR_LENGTH-1:0] global_history_i, - input wire [PC_WIDTH-1:0] pc_i, - input wire update_valid, - input wire[PC_WIDTH:0] update_instr_info, - output wire taken, - output wire tag_hit); - - // Reset - wire rst_n = ~rst; - - // Unpack update instr info - wire [PC_WIDTH-1:0] update_pc = update_instr_info[PC_WIDTH:1]; - wire update_taken = update_instr_info[0]; - - // PHT - // - entry: {3bits bimodal, xbits tag} - reg[PHT_TAG_WIDTH+2:0] PHT[2**PHT_DEPTH_EXP2]; - - - // Fold GHT input to a fix length, the same as index range - wire [PHT_DEPTH_EXP2-1:0] hashed_ght_input; - folder_func - #( - .INPUT_LENGTH (INPUT_GHR_LENGTH), - .OUTPUT_LENGTH (PHT_DEPTH_EXP2), - .MAX_FOLD_ROUND (6) - ) - ght_hash( - .var_i (global_history_i), - .var_o (hashed_ght_input) - ); - - // Tag - // wire [`PHT_TAG_WIDTH-1:0] hashed_pc_tag = pc_i[2+`PHT_TAG_WIDTH-1:2]; - wire [PHT_TAG_WIDTH-1:0] hashed_pc_tag; - folder_func - #( - .INPUT_LENGTH (PC_WIDTH), - .OUTPUT_LENGTH (PHT_TAG_WIDTH), - .MAX_FOLD_ROUND (4) - ) - pc_hash( - .var_i(pc_i), - .var_o (hashed_pc_tag) - ); - - - - // hash with pc, and concatenate to `PHT_DEPTH_LOG2 - // the low 2bits of pc is usually 0, so use upper bits - wire [PHT_DEPTH_EXP2-1:0] query_hashed_index = {hashed_ght_input ^ pc_i[2+PHT_DEPTH_EXP2-1:2]}; - - // Query logic ========================================== - wire [2:0] query_result_bimodal = PHT[query_hashed_index][PHT_TAG_WIDTH+2:PHT_TAG_WIDTH]; - wire [PHT_TAG_WIDTH-1:0] query_result_tag = PHT[query_hashed_index][PHT_TAG_WIDTH-1:0]; - - assign taken = (query_result_bimodal[2] == 1'b1); - assign tag_hit = (hashed_pc_tag == query_result_tag); - // assign tag_hit = 1; - - - // Use a buffer to hold the query_index and pc - // entry: {valid 1, pc PC_WIDTH, query_index} - localparam HASH_BUFFER_WIDTH = 1 + PC_WIDTH + PHT_DEPTH_EXP2; - reg [HASH_BUFFER_WIDTH-1:0] hash_buffer[HASH_BUFFER_SIZE]; - wire [HASH_BUFFER_SIZE-1:0] pc_match_table; // indicates which entry in the buffer is a match - - // Move from lower to higher - // always @(posedge clk) - // begin - assign hash_buffer[0] = {(pc_i != 0), pc_i, query_hashed_index}; - // end - generate - for (genvar i = 1; i Date: Sun, 17 Apr 2022 21:50:36 +0800 Subject: [PATCH 025/114] feat: add update policy - still with problem, better than before --- src/vsrc/branch_predictor/Makefile | 5 +- src/vsrc/branch_predictor/base_predictor.sv | 48 ++++++++++++ src/vsrc/branch_predictor/base_predictor.v | 59 --------------- src/vsrc/branch_predictor/{btb.v => btb.sv} | 2 +- src/vsrc/branch_predictor/folder_func.sv | 35 +++++++++ src/vsrc/branch_predictor/folder_func.v | 38 ---------- src/vsrc/branch_predictor/tage_predictor.sv | 68 +++++++++++++++-- src/vsrc/branch_predictor/tagged_predictor.sv | 73 +++++++++++-------- src/vsrc/branch_predictor/testbench.cpp | 2 +- src/vsrc/branch_predictor/utils/fpa.sv | 34 +++++++++ src/vsrc/branch_predictor/utils/fpa.v | 41 ----------- src/vsrc/branch_predictor/utils/xor_func.sv | 15 ++++ src/vsrc/branch_predictor/utils/xor_func.v | 13 ---- 13 files changed, 237 insertions(+), 196 deletions(-) create mode 100644 src/vsrc/branch_predictor/base_predictor.sv delete mode 100644 src/vsrc/branch_predictor/base_predictor.v rename src/vsrc/branch_predictor/{btb.v => btb.sv} (97%) create mode 100644 src/vsrc/branch_predictor/folder_func.sv delete mode 100644 src/vsrc/branch_predictor/folder_func.v create mode 100644 src/vsrc/branch_predictor/utils/fpa.sv delete mode 100644 src/vsrc/branch_predictor/utils/fpa.v create mode 100644 src/vsrc/branch_predictor/utils/xor_func.sv delete mode 100644 src/vsrc/branch_predictor/utils/xor_func.v diff --git a/src/vsrc/branch_predictor/Makefile b/src/vsrc/branch_predictor/Makefile index 51682a7..5223ff7 100644 --- a/src/vsrc/branch_predictor/Makefile +++ b/src/vsrc/branch_predictor/Makefile @@ -6,10 +6,9 @@ test: verilate ./obj_dir/Vtage_predictor -VERILATOR_FLAGS = -O3 +define+DUMP_WAVEFORM=1 -#--trace +VERILATOR_FLAGS = -O3 #+define+DUMP_WAVEFORM=1 --trace -verilate: *.v +verilate: *.v *.sv verilator $(VERILATOR_FLAGS) tage_predictor.sv --exe testbench.cpp --cc -I../ | true # Ignore errors @make -C obj_dir -f Vtage_predictor.mk 2>&1 >/dev/null diff --git a/src/vsrc/branch_predictor/base_predictor.sv b/src/vsrc/branch_predictor/base_predictor.sv new file mode 100644 index 0000000..18843d5 --- /dev/null +++ b/src/vsrc/branch_predictor/base_predictor.sv @@ -0,0 +1,48 @@ +// Base Predictor is a pure PC-indexed bimodal table + +module base_predictor #( + parameter TABLE_DEPTH_EXP2 = 10, + parameter CTR_WIDTH = 2, + parameter PC_WIDTH = 32 +) ( + input logic clk, + input logic rst, + input logic [PC_WIDTH-1:0] pc_i, + input logic update_valid, + input logic [PC_WIDTH:0] update_instr_info, + output logic taken +); + + // Table + bit [CTR_WIDTH-1:0] PHT [2**TABLE_DEPTH_EXP2]; + + // Reset signal + logic rst_n; + assign rst_n = ~rst; + + // Query logic + logic [TABLE_DEPTH_EXP2-1:0] query_index = pc_i[2+TABLE_DEPTH_EXP2-1:2]; + logic [ CTR_WIDTH-1:0] query_entry = PHT[query_index]; + + assign taken = (query_entry[CTR_WIDTH-1] == 1'b1); + + // Update logic + logic [ PC_WIDTH-1:0] update_pc = update_instr_info[PC_WIDTH:1]; + logic [TABLE_DEPTH_EXP2-1:0] update_index = update_pc[TABLE_DEPTH_EXP2+1:2]; + logic update_taken = update_instr_info[0]; + always @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + for (integer i = 0; i < 2 ** TABLE_DEPTH_EXP2; i = i + 1) begin + PHT[i] = {1'b1, {CTR_WIDTH - 1{1'b0}}}; + end + end else if (update_valid) begin + if (PHT[update_index] == {CTR_WIDTH{1'b1}}) begin + PHT[update_index] <= update_taken ? PHT[update_index] : PHT[update_index] - 1; + end else if (PHT[update_index] == {CTR_WIDTH{1'b0}}) begin + PHT[update_index] <= update_taken ? PHT[update_index] + 1 : PHT[update_index]; + end else begin + PHT[update_index] <= update_taken ? PHT[update_index] + 1 : PHT[update_index] - 1; + end + end + end +endmodule diff --git a/src/vsrc/branch_predictor/base_predictor.v b/src/vsrc/branch_predictor/base_predictor.v deleted file mode 100644 index fddc517..0000000 --- a/src/vsrc/branch_predictor/base_predictor.v +++ /dev/null @@ -1,59 +0,0 @@ -// Base Predictor is a pure PC-indexed bimodal table - -module base_predictor #(parameter TABLE_DEPTH_EXP2 = 10, - parameter CTR_WIDTH = 2, - parameter PC_WIDTH = 32) - (input wire clk, - input wire rst, - input wire [PC_WIDTH-1:0] pc_i, - input wire update_valid, - input wire[PC_WIDTH:0] update_instr_info, - output wire taken); - - // Table - reg[CTR_WIDTH-1:0] PHT[2**TABLE_DEPTH_EXP2]; - - // Reset signal - wire rst_n = ~rst; - - // Reset - always @(negedge rst_n) - begin - if (!rst_n) - begin - for (integer i = 0; i< 2**TABLE_DEPTH_EXP2; i = i + 1) - begin - PHT[i] = {1'b1, {CTR_WIDTH-1{1'b0}}}; - end - end - end - - // Query logic - wire[TABLE_DEPTH_EXP2-1:0] query_index = pc_i[2+TABLE_DEPTH_EXP2-1:2]; - wire[CTR_WIDTH-1:0] query_entry = PHT[query_index]; - - assign taken = (query_entry[CTR_WIDTH-1] == 1'b1); - - // Update logic - wire[PC_WIDTH-1:0] update_pc = update_instr_info[PC_WIDTH:1]; - wire[TABLE_DEPTH_EXP2-1:0] update_index = update_pc[TABLE_DEPTH_EXP2+1:2]; - wire update_taken = update_instr_info[0]; - always @(posedge clk) - begin - if (update_valid) - begin - if (PHT[update_index] == {CTR_WIDTH{1'b1}}) - begin - PHT[update_index] <= update_taken? PHT[update_index] : PHT[update_index]-1; - end - else if (PHT[update_index] == {CTR_WIDTH{1'b0}}) - begin - PHT[update_index] <= update_taken? PHT[update_index] +1: PHT[update_index]; - end - else - begin - PHT[update_index] <= update_taken? PHT[update_index] +1: PHT[update_index]-1; - end - end - end -endmodule diff --git a/src/vsrc/branch_predictor/btb.v b/src/vsrc/branch_predictor/btb.sv similarity index 97% rename from src/vsrc/branch_predictor/btb.v rename to src/vsrc/branch_predictor/btb.sv index bb65c97..5e14456 100644 --- a/src/vsrc/branch_predictor/btb.v +++ b/src/vsrc/branch_predictor/btb.sv @@ -22,7 +22,7 @@ module btb ( [tag[`BTB_TAG_LENGTH], target[30]] - target: target[31:2], lower 2bit is usually 0 */ - reg [`BTB_ENTRY_BUS] btb_entries[`BTB_DEPTH]; + reg [`BTB_ENTRY_BUS] btb_entries[`BTB_DEPTH-1:0]; // Query logic //////////////////////////////////// diff --git a/src/vsrc/branch_predictor/folder_func.sv b/src/vsrc/branch_predictor/folder_func.sv new file mode 100644 index 0000000..098087a --- /dev/null +++ b/src/vsrc/branch_predictor/folder_func.sv @@ -0,0 +1,35 @@ +`include "branch_predictor/utils/xor_func.sv" + +module folder_func #( + parameter INPUT_LENGTH = 10, + parameter OUTPUT_LENGTH = 8, + parameter MAX_FOLD_ROUND = 3 +) ( + input wire [ INPUT_LENGTH-1:0] var_i, + output wire [OUTPUT_LENGTH-1:0] var_o +); + + + wire [2**MAX_FOLD_ROUND*OUTPUT_LENGTH-1:0] workspace[MAX_FOLD_ROUND]; + + // Extend the input to working length + assign workspace[0] = {{2 ** MAX_FOLD_ROUND * OUTPUT_LENGTH - INPUT_LENGTH{1'b0}}, var_i}; + // assign workspace[0] = {var_i}; + + // Fold the input from workspace[0] to workspace[MAX_FOLD_ROUND-1] + // using XOR + generate + genvar i; + for (i = 1; i < MAX_FOLD_ROUND; i = i + 1) begin + xor_func #( + .HALF_DATA_WIDTH(2 ** (MAX_FOLD_ROUND - i) * OUTPUT_LENGTH) + ) u_xor_func ( + .i(workspace[i-1][2**(MAX_FOLD_ROUND-i+1)*OUTPUT_LENGTH-1:0]), + .o(workspace[i][2**(MAX_FOLD_ROUND-i+1)*OUTPUT_LENGTH-1:0]) + ); + end + endgenerate + + assign var_o = workspace[MAX_FOLD_ROUND-1][OUTPUT_LENGTH-1:0]; + +endmodule diff --git a/src/vsrc/branch_predictor/folder_func.v b/src/vsrc/branch_predictor/folder_func.v deleted file mode 100644 index 504f4e0..0000000 --- a/src/vsrc/branch_predictor/folder_func.v +++ /dev/null @@ -1,38 +0,0 @@ -`include "branch_predictor/utils/xor_func.v" - -module folder_func #( - parameter INPUT_LENGTH = 10, - parameter OUTPUT_LENGTH = 8, - parameter MAX_FOLD_ROUND = 3 - ) ( - input wire [INPUT_LENGTH-1:0] var_i, - output wire [OUTPUT_LENGTH-1:0] var_o - ); - - - wire[2**MAX_FOLD_ROUND*OUTPUT_LENGTH-1:0] workspace[MAX_FOLD_ROUND]; - - // Extend the input to working length - assign workspace[0] = {{2**MAX_FOLD_ROUND*OUTPUT_LENGTH-INPUT_LENGTH{1'b0}},var_i}; - // assign workspace[0] = {var_i}; - - // Fold the input from workspace[0] to workspace[MAX_FOLD_ROUND-1] - // using XOR - generate - genvar i; - for (i = 1; i < MAX_FOLD_ROUND; i = i + 1) - begin - xor_func - #( - .HALF_DATA_WIDTH (2**(MAX_FOLD_ROUND-i)*OUTPUT_LENGTH) - ) - u_xor_func( - .i (workspace[i-1][2**(MAX_FOLD_ROUND-i+1)*OUTPUT_LENGTH-1:0]), - .o (workspace[i][2**(MAX_FOLD_ROUND-i+1)*OUTPUT_LENGTH-1:0]) - ); - end - endgenerate - - assign var_o = workspace[MAX_FOLD_ROUND-1][OUTPUT_LENGTH-1:0]; - -endmodule diff --git a/src/vsrc/branch_predictor/tage_predictor.sv b/src/vsrc/branch_predictor/tage_predictor.sv index cd1f945..a61933d 100644 --- a/src/vsrc/branch_predictor/tage_predictor.sv +++ b/src/vsrc/branch_predictor/tage_predictor.sv @@ -3,17 +3,20 @@ `include "../defines.v" `include "branch_predictor/defines.v" -`include "branch_predictor/utils/fpa.v" +`include "branch_predictor/utils/fpa.sv" module tage_predictor ( input logic clk, input logic rst, input logic [`RegBus] pc_i, + + // Update signals input logic branch_valid_i, input logic branch_taken_i, input logic [`RegBus] branch_pc_i, input logic [`RegBus] branch_target_address_i, + output logic [`RegBus] predicted_branch_target_o, output logic predict_branch_taken_o, output logic predict_valid, @@ -21,7 +24,6 @@ module tage_predictor ( ); `ifdef DUMP_WAVEFORM - initial begin $dumpfile("logs/wave.vcd"); $dumpvars(0, tage_predictor); @@ -61,7 +63,7 @@ module tage_predictor ( .clk (clk), .rst (rst), .pc_i (pc_i), - .update_valid (branch_valid_i), + .update_valid (tag_update_valid[0]), .update_instr_info({branch_pc_i, branch_taken_i}), .taken (base_taken) ); @@ -70,10 +72,12 @@ module tage_predictor ( // Tagged Predictors + localparam TAG_COMPONENT_AMOUNT = 4; logic [3:0] tag_taken; logic [3:0] tag_hit; - logic [2:0] accept_prediction_id; - localparam integer provider_ghr_length[4] = '{5, 10, 20, 40}; + logic [$clog2(TAG_COMPONENT_AMOUNT):0] accept_prediction_id; + logic [4:0] tag_update_valid; + localparam integer provider_ghr_length[TAG_COMPONENT_AMOUNT] = '{5, 10, 20, 40}; generate genvar provider_id; @@ -81,13 +85,13 @@ module tage_predictor ( logic valid = (accept_prediction_id == provider_id) ? branch_valid_i : 0; tagged_predictor #( .INPUT_GHR_LENGTH(provider_ghr_length[provider_id]), - .PHT_DEPTH_EXP2 (12) + .PHT_DEPTH_EXP2 (10) ) tag_predictor ( .clk (clk), .rst (rst), .global_history_i (GHR[provider_ghr_length[provider_id]-1:0]), .pc_i (pc_i), - .update_valid (branch_valid_i), + .update_valid (tag_update_valid[provider_id+1]), .update_instr_info({branch_pc_i, branch_taken_i}), .taken (tag_taken[provider_id]), .tag_hit (tag_hit[provider_id]) @@ -95,11 +99,59 @@ module tage_predictor ( end endgenerate + // Update policy + // Update on a correct prediction: update the ctr bits of the provider + // Update on a wrong prediction: update the ctr bits of the provider, then allocate an entry in a longer history component + // + // Buffer content: pc, accepted_provider_id, predicted_taken + typedef struct packed { + bit [`RegBus] pc; + bit [$clog2(TAG_COMPONENT_AMOUNT+1)-1:0] accepted_provider_id; + bit taken; + } provider_history_entry; + provider_history_entry provider_history_buffer[10]; // TODO: parameterize 10 + assign provider_history_buffer[0] = {pc_i, accept_prediction_id, predict_branch_taken_o}; + always_ff @(posedge clk) begin : shift + for (integer i = 1; i < 10; i++) begin + if (i == provider_history_matched_id) begin + provider_history_buffer[i] <= 0; + end else provider_history_buffer[i] <= provider_history_buffer[i-1]; + end + end + bit [10-1:0] provider_history_match; + always_comb begin : provider_history_search // match pc with update signals + for (integer i = 0; i < 10; i++) begin + provider_history_match[i] = (branch_pc_i == provider_history_buffer[i].pc); + end + end + + logic [$clog2(10)-1:0] provider_history_matched_id; // The entry id of the matched pc + fpa #( + .LINES(10) + ) u_fpa_provider_history_matched_id ( + .unitary_in(provider_history_match), + .binary_out(provider_history_matched_id) + ); + + logic [2:0] update_valid_id; + assign update_valid_id = provider_history_buffer[provider_history_matched_id].accepted_provider_id; + always_comb begin : update_policy + for (integer i = 0; i < TAG_COMPONENT_AMOUNT + 1; i++) begin + tag_update_valid[i] = 1'b0; + end + if (branch_taken_i == provider_history_buffer[provider_history_matched_id].taken) begin + tag_update_valid[update_valid_id] = 1'b1; + end else begin // Wrong prediction + tag_update_valid[provider_history_buffer[provider_history_matched_id].accepted_provider_id] = 1'b1; + // tag_update_valid[provider_history_buffer[provider_history_matched_id].accepted_provider_id+1] = 1'b1; + end + end + fpa #( .LINES(5) ) u_fpa ( - .unitary_in({tag_hit, 1'b0}), + .unitary_in({tag_hit, 1'b1}), .binary_out(accept_prediction_id) ); diff --git a/src/vsrc/branch_predictor/tagged_predictor.sv b/src/vsrc/branch_predictor/tagged_predictor.sv index 482de3e..ec54fdc 100644 --- a/src/vsrc/branch_predictor/tagged_predictor.sv +++ b/src/vsrc/branch_predictor/tagged_predictor.sv @@ -1,8 +1,8 @@ // Gshared predictor as base predictor `include "../defines.v" `include "branch_predictor/defines.v" -`include "branch_predictor/folder_func.v" -`include "branch_predictor/utils/fpa.v" +`include "branch_predictor/folder_func.sv" +`include "branch_predictor/utils/fpa.sv" module tagged_predictor #( @@ -12,30 +12,36 @@ module tagged_predictor #( parameter PHT_TAG_WIDTH = 10, parameter HASH_BUFFER_SIZE = 10 ) ( - input wire clk, - input wire rst, - input wire [INPUT_GHR_LENGTH-1:0] global_history_i, - input wire [PC_WIDTH-1:0] pc_i, - input wire update_valid, - input wire [PC_WIDTH:0] update_instr_info, - output wire taken, - output wire tag_hit + input logic clk, + input logic rst, + input logic [INPUT_GHR_LENGTH-1:0] global_history_i, + input logic [PC_WIDTH-1:0] pc_i, + + // Update signals + input logic update_valid, + input logic [PC_WIDTH:0] update_instr_info, + + output logic taken, + output logic tag_hit ); // Reset - wire rst_n = ~rst; + logic rst_n; + assign rst_n = ~rst; // Unpack update instr info - wire [PC_WIDTH-1:0] update_pc = update_instr_info[PC_WIDTH:1]; - wire update_taken = update_instr_info[0]; + logic [PC_WIDTH-1:0] update_pc; + assign update_pc = update_instr_info[PC_WIDTH:1]; + logic update_taken; + assign update_taken = update_instr_info[0]; // PHT // - entry: {3bits bimodal, xbits tag} - reg [PHT_TAG_WIDTH+2:0] PHT[2**PHT_DEPTH_EXP2]; + logic [PHT_TAG_WIDTH+2:0] PHT[2**PHT_DEPTH_EXP2]; // Fold GHT input to a fix length, the same as index range - wire [PHT_DEPTH_EXP2-1:0] hashed_ght_input; + logic [PHT_DEPTH_EXP2-1:0] hashed_ght_input; folder_func #( .INPUT_LENGTH (INPUT_GHR_LENGTH), .OUTPUT_LENGTH (PHT_DEPTH_EXP2), @@ -46,8 +52,8 @@ module tagged_predictor #( ); // Tag - // wire [`PHT_TAG_WIDTH-1:0] hashed_pc_tag = pc_i[2+`PHT_TAG_WIDTH-1:2]; - wire [PHT_TAG_WIDTH-1:0] hashed_pc_tag; + // logic [`PHT_TAG_WIDTH-1:0] hashed_pc_tag = pc_i[2+`PHT_TAG_WIDTH-1:2]; + logic [PHT_TAG_WIDTH-1:0] hashed_pc_tag; folder_func #( .INPUT_LENGTH (PC_WIDTH), .OUTPUT_LENGTH (PHT_TAG_WIDTH), @@ -61,15 +67,16 @@ module tagged_predictor #( // hash with pc, and concatenate to `PHT_DEPTH_LOG2 // the low 2bits of pc is usually 0, so use upper bits - wire [PHT_DEPTH_EXP2-1:0] query_hashed_index = { - hashed_ght_input ^ pc_i[2+PHT_DEPTH_EXP2-1:2] - }; + logic [PHT_DEPTH_EXP2-1:0] query_hashed_index; + assign query_hashed_index = (hashed_ght_input ^ pc_i[2+PHT_DEPTH_EXP2-1:2]); // Query logic ========================================== - wire [2:0] query_result_bimodal = PHT[query_hashed_index][PHT_TAG_WIDTH+2:PHT_TAG_WIDTH]; - wire [PHT_TAG_WIDTH-1:0] query_result_tag = PHT[query_hashed_index][PHT_TAG_WIDTH-1:0]; + logic [2:0] query_result_bimodal; + assign query_result_bimodal = PHT[query_hashed_index][PHT_TAG_WIDTH+2:PHT_TAG_WIDTH]; + logic [PHT_TAG_WIDTH-1:0] query_result_tag; + assign query_result_tag = PHT[query_hashed_index][PHT_TAG_WIDTH-1:0]; - assign taken = (query_result_bimodal[2] == 1'b1); + assign taken = (query_result_bimodal[2] == 1'b1); assign tag_hit = (hashed_pc_tag == query_result_tag); // assign tag_hit = 1; @@ -77,8 +84,8 @@ module tagged_predictor #( // Use a buffer to hold the query_index and pc // entry: {valid 1, pc PC_WIDTH, query_index} localparam HASH_BUFFER_WIDTH = 1 + PC_WIDTH + PHT_DEPTH_EXP2; - reg [HASH_BUFFER_WIDTH-1:0] hash_buffer[HASH_BUFFER_SIZE]; - wire [HASH_BUFFER_SIZE-1:0] pc_match_table; // indicates which entry in the buffer is a match + bit [HASH_BUFFER_WIDTH-1:0] hash_buffer[HASH_BUFFER_SIZE]; + logic [HASH_BUFFER_SIZE-1:0] pc_match_table; // indicates which entry in the buffer is a match // Move from lower to higher // always @(posedge clk) @@ -103,23 +110,25 @@ module tagged_predictor #( endgenerate // Get match index - wire [$clog2(HASH_BUFFER_SIZE+1)-1:0] update_match_index; + logic [$clog2(HASH_BUFFER_SIZE+1)-1:0] update_match_index; fpa #( - .LINES(HASH_BUFFER_SIZE + 1) + .LINES(HASH_BUFFER_SIZE) ) u_fpa ( - .unitary_in({pc_match_table, 1'b1}), // Set lowest bit to 1 to catch missing condition + .unitary_in({pc_match_table}), .binary_out(update_match_index) ); - wire [PHT_DEPTH_EXP2-1:0] update_index = hash_buffer[update_match_index-1][PHT_DEPTH_EXP2-1:0]; - wire update_match_valid = ~(update_match_index == 0) & (hash_buffer[update_match_index][HASH_BUFFER_WIDTH-1] == 1); + logic [PHT_DEPTH_EXP2-1:0] update_index; + assign update_index = hash_buffer[update_match_index][PHT_DEPTH_EXP2-1:0]; + logic update_match_valid; + assign update_match_valid = (update_match_index != 0) & (hash_buffer[update_match_index][HASH_BUFFER_WIDTH-1] == 1); // Calculate update tag - wire [PHT_TAG_WIDTH-1:0] update_tag; + logic [PHT_TAG_WIDTH-1:0] update_tag; folder_func #( .INPUT_LENGTH (PC_WIDTH), .OUTPUT_LENGTH (PHT_TAG_WIDTH), .MAX_FOLD_ROUND(4) - ) u_folder_func ( + ) update_pc_hash ( .var_i(update_pc), .var_o(update_tag) ); diff --git a/src/vsrc/branch_predictor/testbench.cpp b/src/vsrc/branch_predictor/testbench.cpp index e7e3c7a..3658bf5 100644 --- a/src/vsrc/branch_predictor/testbench.cpp +++ b/src/vsrc/branch_predictor/testbench.cpp @@ -12,7 +12,7 @@ // Work around double sc_time_stamp() { return 0; } -static std::string test_filename = "data/traces/trace_02"; +static std::string test_filename = "data/gcc-8M.txt"; struct instruction_entry { diff --git a/src/vsrc/branch_predictor/utils/fpa.sv b/src/vsrc/branch_predictor/utils/fpa.sv new file mode 100644 index 0000000..0e57e79 --- /dev/null +++ b/src/vsrc/branch_predictor/utils/fpa.sv @@ -0,0 +1,34 @@ +// FPA detect the first 1 in input, from high to low + +`ifndef FPA_V +`define FPA_V + +module fpa #( + parameter LINES = 16, + parameter WIDTH = $clog2(LINES) +) ( + input logic [LINES-1:0] unitary_in, + output logic [WIDTH-1:0] binary_out +); + + logic [LINES-1:0] fliped_in; + + always @(*) begin + for (integer i = 0; i < LINES; i = i + 1) begin + fliped_in[i] = unitary_in[LINES-i-1]; + end + end + + logic [LINES-1:0] one_hot; + assign one_hot = fliped_in & ((~fliped_in) + 1); + + always @(*) begin + binary_out = 0; + for (integer i = 0; i < LINES; i = i + 1) begin + if (one_hot[i]) binary_out = LINES[WIDTH-1:0] - i[WIDTH-1:0] - 1; + end + + end + +endmodule +`endif diff --git a/src/vsrc/branch_predictor/utils/fpa.v b/src/vsrc/branch_predictor/utils/fpa.v deleted file mode 100644 index ff7e853..0000000 --- a/src/vsrc/branch_predictor/utils/fpa.v +++ /dev/null @@ -1,41 +0,0 @@ -// FPA detect the first 1 in input, from high to low - -`ifndef FPA_V -`define FPA_V - -module fpa #( - parameter LINES = 16, - parameter WIDTH = $clog2(LINES) - )( - input wire [LINES-1:0] unitary_in, - output reg [WIDTH-1:0] binary_out - ); - - reg [LINES-1:0] fliped_in; - - always @(*) - begin - for (integer i = 0; i Date: Tue, 19 Apr 2022 17:22:44 +0800 Subject: [PATCH 026/114] feat: add cbp-3 traces and mpki log --- src/vsrc/branch_predictor/Makefile | 8 + src/vsrc/branch_predictor/README.md | 52 ++++++ src/vsrc/branch_predictor/cbp3.cpp | 185 ++++++++++++++++++++ src/vsrc/branch_predictor/tage_predictor.sv | 4 +- 4 files changed, 247 insertions(+), 2 deletions(-) create mode 100644 src/vsrc/branch_predictor/README.md create mode 100644 src/vsrc/branch_predictor/cbp3.cpp diff --git a/src/vsrc/branch_predictor/Makefile b/src/vsrc/branch_predictor/Makefile index 5223ff7..4751b3e 100644 --- a/src/vsrc/branch_predictor/Makefile +++ b/src/vsrc/branch_predictor/Makefile @@ -1,4 +1,12 @@ +cbp3: *.v *.sv + verilator $(VERILATOR_FLAGS) tage_predictor.sv --exe cbp3.cpp --cc -I../ | true # Ignore errors + @make -C obj_dir -f Vtage_predictor.mk 2>&1 >/dev/null + trace_id=0; while [[ $$trace_id -lt 20 ]]; do \ + echo $$(./obj_dir/Vtage_predictor $$trace_id | grep MPKI); \ + (( trace_id = trace_id + 1 )); \ + done + benchmark: verilate ./benchmark.sh diff --git a/src/vsrc/branch_predictor/README.md b/src/vsrc/branch_predictor/README.md new file mode 100644 index 0000000..1df4bd6 --- /dev/null +++ b/src/vsrc/branch_predictor/README.md @@ -0,0 +1,52 @@ +# Branch Predictor Unit + +## Reference + +### MPKI + +``` + MPKI: 3.787425 + MPKI: 1.614177 + MPKI: 13.759027 + MPKI: 0.297560 + MPKI: 0.701255 + MPKI: 14.145463 + MPKI: 13.420007 + MPKI: 26.892054 + MPKI: 5.227905 + MPKI: 39.794147 + MPKI: 11.073499 + MPKI: 12.654080 + MPKI: 6.380413 + MPKI: 2.989018 + MPKI: 9.888374 + MPKI: 18.752298 + MPKI: 19.088045 + MPKI: 10.448743 + MPKI: 16.002567 + MPKI: 17.744772 +``` + +### Misprediction Rate +``` + Misprediction Rate: 0.050472 + Misprediction Rate: 0.026560 + Misprediction Rate: 0.262407 + Misprediction Rate: 0.009799 + Misprediction Rate: 0.008541 + Misprediction Rate: 0.099716 + Misprediction Rate: 0.138109 + Misprediction Rate: 0.210334 + Misprediction Rate: 0.074508 + Misprediction Rate: 0.312604 + Misprediction Rate: 0.146535 + Misprediction Rate: 0.097983 + Misprediction Rate: 0.062432 + Misprediction Rate: 0.018088 + Misprediction Rate: 0.113774 + Misprediction Rate: 0.151117 + Misprediction Rate: 0.159172 + Misprediction Rate: 0.080861 + Misprediction Rate: 0.110632 + Misprediction Rate: 0.121956 +``` \ No newline at end of file diff --git a/src/vsrc/branch_predictor/cbp3.cpp b/src/vsrc/branch_predictor/cbp3.cpp new file mode 100644 index 0000000..927b174 --- /dev/null +++ b/src/vsrc/branch_predictor/cbp3.cpp @@ -0,0 +1,185 @@ +#include "Vtage_predictor.h" +#include +#include +#include +#include +#include +#include +#include + +#define BRANCH_LATENCY (3) + +// Work around +double sc_time_stamp() { return 0; } + +static int TRACE_NUM = 20; + +static std::string traces_dir = "data/cbp3/"; + +struct instruction_entry +{ + uint64_t pc; + bool taken; + bool conditional; +}; + +struct trace +{ + std::vector entries; + uint64_t total_instr_num; +}; + +// Parse test file +trace parse_test_file(int trace_id) +{ + std::ifstream addresses_file(traces_dir + "addresses" + std::to_string(trace_id)); + std::ifstream conditional_file(traces_dir + "conditionals" + std::to_string(trace_id)); + std::ifstream result_file(traces_dir + "branchresults" + std::to_string(trace_id)); + + if (!addresses_file.is_open() || !conditional_file.is_open() || !result_file.is_open()) + { + std::cerr << "Open Input File Failed." << std::endl; + std::exit(EXIT_FAILURE); + } + + std::string total_instr_num_s; + getline(addresses_file, total_instr_num_s); + uint64_t total_instr_num = std::stoi(total_instr_num_s); + + std::vector entries; + + // Read loop + while (!addresses_file.eof()) + { + uint64_t pc; + char taken_char; + char conditional; + addresses_file >> std::hex >> pc; + result_file >> taken_char; + conditional_file >> conditional; + + entries.push_back({pc, taken_char == 'T' || taken_char == '1', conditional == '1'}); + } + + addresses_file.close(); + result_file.close(); + conditional_file.close(); + return {entries, total_instr_num}; +} + +int main(int argc, char const *argv[]) +{ + // Enable tracing aka waveform + const std::unique_ptr context{new VerilatedContext}; + context->debug(0); + context->traceEverOn(true); + context->commandArgs(argc, argv); + Verilated::mkdir("logs"); + + // initialize + std::unique_ptr sopc(new Vtage_predictor{context.get()}); + sopc->clk = 1; + sopc->rst = 1; + + std::string trace_id = "0"; + if (argc > 1) + { + trace_id = std::string(argv[1]); + } + + auto trace = parse_test_file(std::stoi(trace_id)); + auto entries = trace.entries; + std::cout << "Procceeding with test instructions: " << entries.size() << std::endl; + std::cout << "First instruction: 0x" << std::hex << entries[0].pc << " " << entries[0].taken << std::dec << std::endl; + + // Delay queue + std::queue delay_queue_taken; + std::queue delay_queue_valid; + for (size_t i = 0; i < BRANCH_LATENCY; i++) + { + delay_queue_taken.push({}); + delay_queue_valid.push(false); + } + + // Reset + sopc->clk = 0; + sopc->eval(); + context->timeInc(1); + sopc->clk = 1; + sopc->rst = 0; + sopc->eval(); + context->timeInc(1); + + std::deque prediction_taken; + + // Simulation loop + for (size_t i = 0; i < entries.size(); i++) + { + + sopc->clk = 0; + sopc->eval(); + context->timeInc(1); + + sopc->pc_i = entries[i].pc; + sopc->branch_valid_i = delay_queue_valid.front(); + delay_queue_valid.pop(); + sopc->branch_taken_i = delay_queue_taken.front().taken; + sopc->branch_pc_i = delay_queue_taken.front().pc; + delay_queue_taken.pop(); + delay_queue_valid.push(true); + delay_queue_taken.push(entries[i]); + + // Evaluate cycle + sopc->clk = 1; + sopc->eval(); + context->timeInc(1); + + // Retrieve prediction + // std::cout << "predicted, truth: " << (uint32_t)sopc->predict_branch_taken_o << " " << entries[i].taken << std::endl; + prediction_taken.push_back(sopc->predict_branch_taken_o); + } + uint32_t perf_tag_hit_counter[5]; + std::memcpy(perf_tag_hit_counter, sopc->perf_tag_hit_counter, sizeof(uint32_t) * 5); + std::cout << perf_tag_hit_counter[4] << std::endl; + std::cout << perf_tag_hit_counter[3] << std::endl; + std::cout << perf_tag_hit_counter[2] << std::endl; + std::cout << perf_tag_hit_counter[1] << std::endl; + std::cout << perf_tag_hit_counter[0] << std::endl; + sopc->final(); + + // First predicto is invalid + // prediction_taken.pop_front(); + + // Statistics + uint64_t misprediction = 0; + uint64_t correct = 0; + uint64_t target_taken = 0; + uint64_t predicted_taken = 0; + for (size_t i = 0; i < prediction_taken.size(); i++) + { + if (entries[i].taken == prediction_taken[i]) + { + correct++; + } + if ((entries[i].taken != prediction_taken[i]) && entries[i].conditional) + { + misprediction++; + } + if (entries[i].taken) + { + target_taken++; + } + if (prediction_taken[i]) + { + predicted_taken++; + } + } + std::cout << "Correct Taken: " << target_taken << '\n'; + std::cout << "Predicted Taken: " << predicted_taken << '\n'; + std::cout << "Correct: " << correct << '\n'; + std::cout << "Wrong: " << misprediction << '\n'; + std::cout << "Correct Rate: " << (double)correct / prediction_taken.size() << std::endl; + std::cout << "MPKI: " << (double)misprediction * 1000 / trace.total_instr_num << std::endl; + + return 0; +} \ No newline at end of file diff --git a/src/vsrc/branch_predictor/tage_predictor.sv b/src/vsrc/branch_predictor/tage_predictor.sv index a61933d..fdcbe1f 100644 --- a/src/vsrc/branch_predictor/tage_predictor.sv +++ b/src/vsrc/branch_predictor/tage_predictor.sv @@ -56,7 +56,7 @@ module tage_predictor ( // Base Predictor logic base_taken; base_predictor #( - .TABLE_DEPTH_EXP2(12), + .TABLE_DEPTH_EXP2(10), .CTR_WIDTH (2), .PC_WIDTH (`RegWidth) ) u_base_predictor ( @@ -143,7 +143,7 @@ module tage_predictor ( tag_update_valid[update_valid_id] = 1'b1; end else begin // Wrong prediction tag_update_valid[provider_history_buffer[provider_history_matched_id].accepted_provider_id] = 1'b1; - // tag_update_valid[provider_history_buffer[provider_history_matched_id].accepted_provider_id+1] = 1'b1; + tag_update_valid[provider_history_buffer[provider_history_matched_id].accepted_provider_id+1] = 1'b1; end end From 03886ede99c2acadde3059f5fb5437cf2db47ac0 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Tue, 19 Apr 2022 20:58:28 +0800 Subject: [PATCH 027/114] feat: implement hash function using CSR - CSR is short for Circular Shifted Register --- src/vsrc/branch_predictor/tage_predictor.sv | 8 +- src/vsrc/branch_predictor/tagged_predictor.sv | 102 ++++++++++-------- 2 files changed, 63 insertions(+), 47 deletions(-) diff --git a/src/vsrc/branch_predictor/tage_predictor.sv b/src/vsrc/branch_predictor/tage_predictor.sv index fdcbe1f..a9dd5e8 100644 --- a/src/vsrc/branch_predictor/tage_predictor.sv +++ b/src/vsrc/branch_predictor/tage_predictor.sv @@ -56,7 +56,7 @@ module tage_predictor ( // Base Predictor logic base_taken; base_predictor #( - .TABLE_DEPTH_EXP2(10), + .TABLE_DEPTH_EXP2(12), .CTR_WIDTH (2), .PC_WIDTH (`RegWidth) ) u_base_predictor ( @@ -77,7 +77,7 @@ module tage_predictor ( logic [3:0] tag_hit; logic [$clog2(TAG_COMPONENT_AMOUNT):0] accept_prediction_id; logic [4:0] tag_update_valid; - localparam integer provider_ghr_length[TAG_COMPONENT_AMOUNT] = '{5, 10, 20, 40}; + localparam integer provider_ghr_length[TAG_COMPONENT_AMOUNT] = '{10, 20, 40, 80}; generate genvar provider_id; @@ -89,7 +89,7 @@ module tage_predictor ( ) tag_predictor ( .clk (clk), .rst (rst), - .global_history_i (GHR[provider_ghr_length[provider_id]-1:0]), + .global_history_i (GHR[provider_ghr_length[provider_id]:0]), .pc_i (pc_i), .update_valid (tag_update_valid[provider_id+1]), .update_instr_info({branch_pc_i, branch_taken_i}), @@ -143,7 +143,7 @@ module tage_predictor ( tag_update_valid[update_valid_id] = 1'b1; end else begin // Wrong prediction tag_update_valid[provider_history_buffer[provider_history_matched_id].accepted_provider_id] = 1'b1; - tag_update_valid[provider_history_buffer[provider_history_matched_id].accepted_provider_id+1] = 1'b1; + // tag_update_valid[provider_history_buffer[provider_history_matched_id].accepted_provider_id+1] = 1'b1; end end diff --git a/src/vsrc/branch_predictor/tagged_predictor.sv b/src/vsrc/branch_predictor/tagged_predictor.sv index ec54fdc..7515086 100644 --- a/src/vsrc/branch_predictor/tagged_predictor.sv +++ b/src/vsrc/branch_predictor/tagged_predictor.sv @@ -1,7 +1,6 @@ // Gshared predictor as base predictor `include "../defines.v" `include "branch_predictor/defines.v" -`include "branch_predictor/folder_func.sv" `include "branch_predictor/utils/fpa.sv" @@ -9,12 +8,14 @@ module tagged_predictor #( parameter INPUT_GHR_LENGTH = 4, parameter PC_WIDTH = 32, parameter PHT_DEPTH_EXP2 = 10, - parameter PHT_TAG_WIDTH = 10, + parameter PHT_TAG_WIDTH = 8, parameter HASH_BUFFER_SIZE = 10 ) ( input logic clk, input logic rst, - input logic [INPUT_GHR_LENGTH-1:0] global_history_i, + + // Require one more bit input + input logic [INPUT_GHR_LENGTH:0] global_history_i, input logic [PC_WIDTH-1:0] pc_i, // Update signals @@ -41,34 +42,57 @@ module tagged_predictor #( // Fold GHT input to a fix length, the same as index range + // Using a CSR, described in PPM-Liked essay + logic [PHT_DEPTH_EXP2-1:0] ght_hash_csr; logic [PHT_DEPTH_EXP2-1:0] hashed_ght_input; - folder_func #( - .INPUT_LENGTH (INPUT_GHR_LENGTH), - .OUTPUT_LENGTH (PHT_DEPTH_EXP2), - .MAX_FOLD_ROUND(6) - ) ght_hash ( - .var_i(global_history_i), - .var_o(hashed_ght_input) - ); + assign hashed_ght_input = { + ght_hash_csr[PHT_DEPTH_EXP2-2:0], + ght_hash_csr[PHT_DEPTH_EXP2-1] ^ global_history_i[0] ^ global_history_i[INPUT_GHR_LENGTH] + }; + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + ght_hash_csr <= 0; + end else begin + ght_hash_csr <= PHT_DEPTH_EXP2 > INPUT_GHR_LENGTH ?hashed_ght_input : global_history_i; + end + end + // Tag - // logic [`PHT_TAG_WIDTH-1:0] hashed_pc_tag = pc_i[2+`PHT_TAG_WIDTH-1:2]; + // Generate a hashed tage from only pc, as described in PPM-Liked essay + // csr1 < ght[high] < csr2 < ght[0] + logic [PHT_TAG_WIDTH-1:0] pc_hash_csr1; + logic [PHT_TAG_WIDTH-2:0] pc_hash_csr2; + logic [PHT_TAG_WIDTH-1:0] pc_hash_csr1_next; + logic [PHT_TAG_WIDTH-2:0] pc_hash_csr2_next; + + assign pc_hash_csr1_next = { + pc_hash_csr1[PHT_TAG_WIDTH-2:0], + pc_hash_csr2[PHT_TAG_WIDTH-2] ^ global_history_i[INPUT_GHR_LENGTH] + }; + assign pc_hash_csr2_next = { + pc_hash_csr2[PHT_TAG_WIDTH-3:0], pc_hash_csr1[PHT_TAG_WIDTH-1] ^ global_history_i[0] + }; + + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + pc_hash_csr1 <= 0; + pc_hash_csr2 <= 0; + end else begin + pc_hash_csr1 <= pc_hash_csr1_next; + pc_hash_csr2 <= pc_hash_csr2_next; + end + end + logic [PHT_TAG_WIDTH-1:0] hashed_pc_tag; - folder_func #( - .INPUT_LENGTH (PC_WIDTH), - .OUTPUT_LENGTH (PHT_TAG_WIDTH), - .MAX_FOLD_ROUND(4) - ) pc_hash ( - .var_i(pc_i), - .var_o(hashed_pc_tag) - ); + assign hashed_pc_tag = pc_i[PHT_TAG_WIDTH+1:2] ^ pc_hash_csr1 ^ {pc_hash_csr2 , 1'b0}; - // hash with pc, and concatenate to `PHT_DEPTH_LOG2 + // hash with pc, and concatenate to PHT_DEPTH_EXP2 // the low 2bits of pc is usually 0, so use upper bits logic [PHT_DEPTH_EXP2-1:0] query_hashed_index; - assign query_hashed_index = (hashed_ght_input ^ pc_i[2+PHT_DEPTH_EXP2-1:2]); + assign query_hashed_index = (ght_hash_csr ^ pc_i[PHT_DEPTH_EXP2-1:0] ^ pc_i[PHT_DEPTH_EXP2*2-1:PHT_DEPTH_EXP2]); // Query logic ========================================== logic [2:0] query_result_bimodal; @@ -83,15 +107,17 @@ module tagged_predictor #( // Use a buffer to hold the query_index and pc // entry: {valid 1, pc PC_WIDTH, query_index} - localparam HASH_BUFFER_WIDTH = 1 + PC_WIDTH + PHT_DEPTH_EXP2; - bit [HASH_BUFFER_WIDTH-1:0] hash_buffer[HASH_BUFFER_SIZE]; + typedef struct packed { + bit valid; + bit [PC_WIDTH-1:0] pc; + bit [PHT_DEPTH_EXP2-1:0] index; + bit [PHT_TAG_WIDTH-1:0] tag; + } info_buffer_entry; + info_buffer_entry hash_buffer[HASH_BUFFER_SIZE]; logic [HASH_BUFFER_SIZE-1:0] pc_match_table; // indicates which entry in the buffer is a match // Move from lower to higher - // always @(posedge clk) - // begin - assign hash_buffer[0] = {(pc_i != 0), pc_i, query_hashed_index}; - // end + assign hash_buffer[0] = {(pc_i != 0), pc_i, query_hashed_index, hashed_pc_tag}; generate for (genvar i = 1; i < HASH_BUFFER_SIZE; i = i + 1) begin always @(posedge clk) begin @@ -104,7 +130,7 @@ module tagged_predictor #( generate for (genvar i = 0; i < HASH_BUFFER_SIZE; i = i + 1) begin always @(*) begin - pc_match_table[i] = (hash_buffer[i][PC_WIDTH+PHT_DEPTH_EXP2-1:PHT_DEPTH_EXP2] == update_pc); + pc_match_table[i] = (hash_buffer[i].pc == update_pc); end end endgenerate @@ -118,21 +144,11 @@ module tagged_predictor #( .binary_out(update_match_index) ); logic [PHT_DEPTH_EXP2-1:0] update_index; - assign update_index = hash_buffer[update_match_index][PHT_DEPTH_EXP2-1:0]; - logic update_match_valid; - assign update_match_valid = (update_match_index != 0) & (hash_buffer[update_match_index][HASH_BUFFER_WIDTH-1] == 1); - - // Calculate update tag + assign update_index = hash_buffer[update_match_index].index; logic [PHT_TAG_WIDTH-1:0] update_tag; - folder_func #( - .INPUT_LENGTH (PC_WIDTH), - .OUTPUT_LENGTH (PHT_TAG_WIDTH), - .MAX_FOLD_ROUND(4) - ) update_pc_hash ( - .var_i(update_pc), - .var_o(update_tag) - ); - + assign update_tag = hash_buffer[update_match_index].tag; + logic update_match_valid; + assign update_match_valid = (update_match_index != 0) & hash_buffer[update_match_index].valid; From eab272a5f8016d5edeb22ef63ab3edd3e388138d Mon Sep 17 00:00:00 2001 From: Easton Man Date: Wed, 20 Apr 2022 09:39:45 +0800 Subject: [PATCH 028/114] fix: fix csr hash --- src/vsrc/branch_predictor/tagged_predictor.sv | 65 +++++++++---------- src/vsrc/branch_predictor/utils/csr_hash.sv | 39 +++++++++++ 2 files changed, 70 insertions(+), 34 deletions(-) create mode 100644 src/vsrc/branch_predictor/utils/csr_hash.sv diff --git a/src/vsrc/branch_predictor/tagged_predictor.sv b/src/vsrc/branch_predictor/tagged_predictor.sv index 7515086..9dc7792 100644 --- a/src/vsrc/branch_predictor/tagged_predictor.sv +++ b/src/vsrc/branch_predictor/tagged_predictor.sv @@ -1,6 +1,7 @@ // Gshared predictor as base predictor `include "../defines.v" `include "branch_predictor/defines.v" +`include "branch_predictor/utils/csr_hash.sv" `include "branch_predictor/utils/fpa.sv" @@ -43,19 +44,17 @@ module tagged_predictor #( // Fold GHT input to a fix length, the same as index range // Using a CSR, described in PPM-Liked essay - logic [PHT_DEPTH_EXP2-1:0] ght_hash_csr; logic [PHT_DEPTH_EXP2-1:0] hashed_ght_input; - assign hashed_ght_input = { - ght_hash_csr[PHT_DEPTH_EXP2-2:0], - ght_hash_csr[PHT_DEPTH_EXP2-1] ^ global_history_i[0] ^ global_history_i[INPUT_GHR_LENGTH] - }; - always_ff @(posedge clk or negedge rst_n) begin - if (!rst_n) begin - ght_hash_csr <= 0; - end else begin - ght_hash_csr <= PHT_DEPTH_EXP2 > INPUT_GHR_LENGTH ?hashed_ght_input : global_history_i; - end - end + csr_hash #( + .INPUT_LENGTH (INPUT_GHR_LENGTH + 1), + .OUTPUT_LENGTH(PHT_DEPTH_EXP2) + ) ght_hash_csr_hash ( + .clk (clk), + .rst (rst), + .data_i(global_history_i), + .hash_o(hashed_ght_input) + ); + // Tag @@ -63,36 +62,34 @@ module tagged_predictor #( // csr1 < ght[high] < csr2 < ght[0] logic [PHT_TAG_WIDTH-1:0] pc_hash_csr1; logic [PHT_TAG_WIDTH-2:0] pc_hash_csr2; - logic [PHT_TAG_WIDTH-1:0] pc_hash_csr1_next; - logic [PHT_TAG_WIDTH-2:0] pc_hash_csr2_next; - - assign pc_hash_csr1_next = { - pc_hash_csr1[PHT_TAG_WIDTH-2:0], - pc_hash_csr2[PHT_TAG_WIDTH-2] ^ global_history_i[INPUT_GHR_LENGTH] - }; - assign pc_hash_csr2_next = { - pc_hash_csr2[PHT_TAG_WIDTH-3:0], pc_hash_csr1[PHT_TAG_WIDTH-1] ^ global_history_i[0] - }; - - always_ff @(posedge clk or negedge rst_n) begin - if (!rst_n) begin - pc_hash_csr1 <= 0; - pc_hash_csr2 <= 0; - end else begin - pc_hash_csr1 <= pc_hash_csr1_next; - pc_hash_csr2 <= pc_hash_csr2_next; - end - end + csr_hash #( + .INPUT_LENGTH (INPUT_GHR_LENGTH + 1), + .OUTPUT_LENGTH(PHT_TAG_WIDTH - 1) + ) pc_hash_csr_hash2 ( + .clk (clk), + .rst (rst), + .data_i(global_history_i), + .hash_o(pc_hash_csr2) + ); + csr_hash #( + .INPUT_LENGTH (INPUT_GHR_LENGTH + 1), + .OUTPUT_LENGTH(PHT_TAG_WIDTH) + ) pc_hash_csr_hash1 ( + .clk (clk), + .rst (rst), + .data_i(global_history_i), + .hash_o(pc_hash_csr1) + ); logic [PHT_TAG_WIDTH-1:0] hashed_pc_tag; - assign hashed_pc_tag = pc_i[PHT_TAG_WIDTH+1:2] ^ pc_hash_csr1 ^ {pc_hash_csr2 , 1'b0}; + assign hashed_pc_tag = pc_i[PHT_TAG_WIDTH-1:0] ^ pc_hash_csr1 ^ {pc_hash_csr2, 1'b0}; // hash with pc, and concatenate to PHT_DEPTH_EXP2 // the low 2bits of pc is usually 0, so use upper bits logic [PHT_DEPTH_EXP2-1:0] query_hashed_index; - assign query_hashed_index = (ght_hash_csr ^ pc_i[PHT_DEPTH_EXP2-1:0] ^ pc_i[PHT_DEPTH_EXP2*2-1:PHT_DEPTH_EXP2]); + assign query_hashed_index = (hashed_ght_input ^ pc_i[PHT_DEPTH_EXP2-1:0] ^ pc_i[PHT_DEPTH_EXP2*2-1:PHT_DEPTH_EXP2]); // Query logic ========================================== logic [2:0] query_result_bimodal; diff --git a/src/vsrc/branch_predictor/utils/csr_hash.sv b/src/vsrc/branch_predictor/utils/csr_hash.sv new file mode 100644 index 0000000..d3758b5 --- /dev/null +++ b/src/vsrc/branch_predictor/utils/csr_hash.sv @@ -0,0 +1,39 @@ +// Implement GHR hash using a CSR (Circular Shifted Register) +module csr_hash #( + parameter INPUT_LENGTH = 25, + parameter OUTPUT_LENGTH = 10 +) ( + input logic clk, + input logic rst, + input logic [INPUT_LENGTH-1:0] data_i, + output logic [OUTPUT_LENGTH-1:0] hash_o +); + + // Reset signal + logic rst_n; + assign rst_n = ~rst; + + bit [OUTPUT_LENGTH-1:0] CSR; + + // State migration function + bit [OUTPUT_LENGTH-1:0] next_CSR; + always_comb begin : csr_hash_comb + localparam residual = (INPUT_LENGTH - 1) % OUTPUT_LENGTH; + // $display(residual, INPUT_LENGTH, OUTPUT_LENGTH); + next_CSR = {CSR[OUTPUT_LENGTH-2:0], CSR[OUTPUT_LENGTH-1] ^ data_i[0]}; + next_CSR[residual] = next_CSR[residual] ^ data_i[INPUT_LENGTH-1]; + end + + // Update CSR + always_ff @(posedge clk or negedge rst_n) begin : csr_hash_ff + if (!rst_n) begin + CSR <= 0; + end else begin + CSR <= next_CSR; + end + end + + // Assign output + assign hash_o = next_CSR; + +endmodule From 223f61432aef17663e737b4e3d356a1501980f95 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Wed, 20 Apr 2022 10:16:22 +0800 Subject: [PATCH 029/114] fix: fix update history buffer --- src/vsrc/branch_predictor/tage_predictor.sv | 12 ++++++++---- src/vsrc/branch_predictor/tagged_predictor.sv | 13 +++++++------ 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/vsrc/branch_predictor/tage_predictor.sv b/src/vsrc/branch_predictor/tage_predictor.sv index a9dd5e8..ef8f09b 100644 --- a/src/vsrc/branch_predictor/tage_predictor.sv +++ b/src/vsrc/branch_predictor/tage_predictor.sv @@ -81,7 +81,9 @@ module tage_predictor ( generate genvar provider_id; - for (provider_id = 0; provider_id < 4; provider_id = provider_id + 1) begin + for ( + provider_id = 0; provider_id < TAG_COMPONENT_AMOUNT; provider_id = provider_id + 1 + ) begin logic valid = (accept_prediction_id == provider_id) ? branch_valid_i : 0; tagged_predictor #( .INPUT_GHR_LENGTH(provider_ghr_length[provider_id]), @@ -113,7 +115,7 @@ module tage_predictor ( assign provider_history_buffer[0] = {pc_i, accept_prediction_id, predict_branch_taken_o}; always_ff @(posedge clk) begin : shift for (integer i = 1; i < 10; i++) begin - if (i == provider_history_matched_id) begin + if (i == provider_history_matched_id + 1) begin provider_history_buffer[i] <= 0; end else provider_history_buffer[i] <= provider_history_buffer[i-1]; end @@ -142,8 +144,10 @@ module tage_predictor ( if (branch_taken_i == provider_history_buffer[provider_history_matched_id].taken) begin tag_update_valid[update_valid_id] = 1'b1; end else begin // Wrong prediction - tag_update_valid[provider_history_buffer[provider_history_matched_id].accepted_provider_id] = 1'b1; - // tag_update_valid[provider_history_buffer[provider_history_matched_id].accepted_provider_id+1] = 1'b1; + tag_update_valid[update_valid_id] = 1'b1; + if (update_valid_id < TAG_COMPONENT_AMOUNT) begin + tag_update_valid[update_valid_id+1] = 1'b1; + end end end diff --git a/src/vsrc/branch_predictor/tagged_predictor.sv b/src/vsrc/branch_predictor/tagged_predictor.sv index 9dc7792..245ed18 100644 --- a/src/vsrc/branch_predictor/tagged_predictor.sv +++ b/src/vsrc/branch_predictor/tagged_predictor.sv @@ -64,21 +64,21 @@ module tagged_predictor #( logic [PHT_TAG_WIDTH-2:0] pc_hash_csr2; csr_hash #( .INPUT_LENGTH (INPUT_GHR_LENGTH + 1), - .OUTPUT_LENGTH(PHT_TAG_WIDTH - 1) - ) pc_hash_csr_hash2 ( + .OUTPUT_LENGTH(PHT_TAG_WIDTH) + ) pc_hash_csr_hash1 ( .clk (clk), .rst (rst), .data_i(global_history_i), - .hash_o(pc_hash_csr2) + .hash_o(pc_hash_csr1) ); csr_hash #( .INPUT_LENGTH (INPUT_GHR_LENGTH + 1), - .OUTPUT_LENGTH(PHT_TAG_WIDTH) - ) pc_hash_csr_hash1 ( + .OUTPUT_LENGTH(PHT_TAG_WIDTH - 1) + ) pc_hash_csr_hash2 ( .clk (clk), .rst (rst), .data_i(global_history_i), - .hash_o(pc_hash_csr1) + .hash_o(pc_hash_csr2) ); logic [PHT_TAG_WIDTH-1:0] hashed_pc_tag; @@ -176,6 +176,7 @@ module tagged_predictor #( if (PHT[update_index][PHT_TAG_WIDTH-1:0] != update_tag) // Miss tag begin // Do swap PHT[update_index][PHT_TAG_WIDTH-1:0] <= {update_tag}; + // PHT[update_index] <= {3'b100, update_tag}; end end end From 63a3183810aeb5190c68e151b75583f92cd270a3 Mon Sep 17 00:00:00 2001 From: Rookie <74707760+Rookie-Cai-niao@users.noreply.github.com> Date: Thu, 21 Apr 2022 11:36:11 +0800 Subject: [PATCH 030/114] fix for implemention --- src/SimTop.v | 51 ++-- src/vsrc/cs_reg.v | 75 ++++++ src/vsrc/defines.v | 13 +- src/vsrc/pipeline/1_fetch/if_id.v | 2 +- src/vsrc/pipeline/2_decode/id.v | 113 ++++++++- src/vsrc/pipeline/2_decode/id_ex.v | 19 +- src/vsrc/pipeline/3_execution/ex.v | 2 +- src/vsrc/pipeline/3_execution/ex_mem.v | 2 +- src/vsrc/pipeline/4_mem/mem.v | 2 +- src/vsrc/pipeline/4_mem/mem_wb.v | 2 +- src/vsrc/pipeline/pipeline_top.v | 325 ------------------------- src/vsrc/tlb.v | 19 ++ src/vsrc/tlb_entry.v | 96 ++++++++ 13 files changed, 349 insertions(+), 372 deletions(-) delete mode 100644 src/vsrc/pipeline/pipeline_top.v create mode 100644 src/vsrc/tlb.v create mode 100644 src/vsrc/tlb_entry.v diff --git a/src/SimTop.v b/src/SimTop.v index 3bda228..6d5ca80 100644 --- a/src/SimTop.v +++ b/src/SimTop.v @@ -129,24 +129,41 @@ module SimTop( `endif - data_ram u_data_ram( - .clk(clock), - .ce_1(dram_ce_1), - .we_1(dram_we_1), - .pc_1(dram_pc_1), - .addr_1(dram_addr_1), - .sel_1(dram_sel_1), - .data_i_1(dram_data_i_1), - .data_o_1(dram_data_o_1), - .ce_2(dram_ce_2), - .we_2(dram_we_2), - .pc_2(dram_pc_2), - .addr_2(dram_addr_2), - .sel_2(dram_sel_2), - .data_i_2(dram_data_i_2), - .data_o_2(dram_data_o_2) - ); + //data_ram u_data_ram( + // .clk(clock), + // .ce_1(dram_ce_1), + // .we_1(dram_we_1), + // .pc_1(dram_pc_1), + // .addr_1(dram_addr_1), + // .sel_1(dram_sel_1), + // .data_i_1(dram_data_i_1), + // .data_o_1(dram_data_o_1), + // .ce_2(dram_ce_2), + // .we_2(dram_we_2), + // .pc_2(dram_pc_2), + // .addr_2(dram_addr_2), + // .sel_2(dram_sel_2), + // .data_i_2(dram_data_i_2), + // .data_o_2(dram_data_o_2) + // ); + + + dual_data_rom u_dual_data_rom( + .clka(clock), + .rsta(reset), + .wea(dram_sel_1), + .addra(dram_addr_1), + .dina(dram_data_i_1), + .douta(dram_data_o_1), + .clkb(clock), + .rstb(reset), + .enb(1'b1), + .web(dram_sel_2), + .addrb(dram_addr_2), + .dinb(dram_data_i_2), + .doutb(dram_data_o_2) + ); `ifdef DIFFTEST diff --git a/src/vsrc/cs_reg.v b/src/vsrc/cs_reg.v index f3e00ae..9779baa 100644 --- a/src/vsrc/cs_reg.v +++ b/src/vsrc/cs_reg.v @@ -29,6 +29,10 @@ reg [31:0] csr_asid; reg [31:0] csr_cpuid; reg [31:0] csr_pgdl; reg [31:0] csr_pgdh; +reg [31:0] csr_save0; +reg [31:0] csr_save1; +reg [31:0] csr_save2; +reg [31:0] csr_save3; //crmd @@ -90,5 +94,76 @@ always @(posedge clk) begin else if(we == 1'b1 && csr_num == `ECTL) csr_ectl[`LIE] <= wdata[`LIE]; end + +always @(posedge clk) begin + +end + +//era +always @(posedge clk) begin + if (excp_flush) begin + + end + else if (we == 1'b1 && csr_num == `ERA) begin + csr_era <= wdata; + end +end + +//badv +always @(posedge clk) begin + if (we == 1'b1 && csr_num == `BADV) begin + csr_badv <= wdata; + end + else if (va_error_in) begin + csr_badv <= bad_va_in; + end +end + +//eentry +always @(posedge clk) begin + if (rst) begin + csr_eentry[5:0] <= 6'b0; + end + else if (we == 1'b1 && csr_num == `EENTRY) begin + csr_eentry[31:6] <= wdata[31:6]; + end +end + +//cpuid +always @(posedge clk) begin + if (rst) begin + csr_cpuid <= 32'b0; + end +end + +//save0 +always @(posedge clk) begin + if (we == 1'b1 && csr_num == `SAVE0) csr_save0 <= wdata; +end + +//save1 +always @(posedge clk) begin + if (we == 1'b1 && csr_num == `SAVE1) csr_save1 <= wdata; +end + +//save2 +always @(posedge clk) begin + if (we == 1'b1 && csr_num == `SAVE2) csr_save2 <= wdata; +end + +//save3 +always @(posedge clk) begin + if (we == 1'b1 && csr_num == `SAVE3) csr_save3 <= wdata; +end + +//pgdl +always @(posedge clk) begin + if (we == 1'b1 && csr_num == `PGDL) csr_pgdl[`BASE] <= wr_data[`BASE]; +end + +//pgdh +always @(posedge clk) begin + if (we == 1'b1 && csr_num == `PGDH) csr_pgdh[`BASE] <= wr_data[`BASE]; +end endmodule \ No newline at end of file diff --git a/src/vsrc/defines.v b/src/vsrc/defines.v index 5c8c8ea..fc97157 100644 --- a/src/vsrc/defines.v +++ b/src/vsrc/defines.v @@ -56,9 +56,11 @@ `define EXE_SPECIAL 6'b000001 `define EXE_CSR_RELATED 6'b00???? +`define EXE_OTHER 6'b100100 `define EXE_CSRRD 8'b00000100 `define EXE_CSRWR 8'b00000100 `define EXE_CSRXCHG 8'b00000100 +`define EXE_TLB_RELATED 5'b10000 `define EXE_IDLE 17'b00000110010010001 `define EXE_INVTLB 17'b00000110010010011 `define EXE_TLBSRCH 22'b0000011001001000001010 @@ -152,7 +154,16 @@ `define EXE_PCADD_OP 8'b00100100 `define EXE_SYSCALL_OP 8'b00100101 `define EXE_BREAK_OP 8'b00100110 - +`define EXE_CSRRD_OP 8'b00100111 +`define EXE_CSRWR_OP 8'b00101000 +`define EXE_CSRXCHG_OP 8'b00101001 +`define EXE_TLBFILL_OP 8'b00101010 +`define EXE_TLBRD_OP 8'b00101011 +`define EXE_TLBWR_OP 8'b00101100 +`define EXE_TLBSRCH_OP 8'b00101101 +`define EXE_ERTN_OP 8'b00101110 +`define EXE_IDLE_OP 8'b00101111 +`define EXE_INVTLB_OP 8'b00110000 //AluSel diff --git a/src/vsrc/pipeline/1_fetch/if_id.v b/src/vsrc/pipeline/1_fetch/if_id.v index b538fc4..5aab6df 100644 --- a/src/vsrc/pipeline/1_fetch/if_id.v +++ b/src/vsrc/pipeline/1_fetch/if_id.v @@ -1,4 +1,4 @@ -`include "../../defines.v" +`include "defines.v" module if_id ( input wire clk, input wire rst, diff --git a/src/vsrc/pipeline/2_decode/id.v b/src/vsrc/pipeline/2_decode/id.v index e15a253..ebe9b2f 100644 --- a/src/vsrc/pipeline/2_decode/id.v +++ b/src/vsrc/pipeline/2_decode/id.v @@ -1,4 +1,4 @@ -`include "../../defines.v" +`include "defines.v" module id( input wire rst, @@ -72,6 +72,7 @@ module id( wire[21:0] opcode_22 = inst_i[31:10]; wire[4:0] imm_5 = inst_i[14:10]; wire[9:0] imm_10 = inst_i[9:0]; + wire[13:0] imm_14 = inst_i[23:10]; wire[15:0] imm_16 = inst_i[25:10]; wire[11:0] imm_12 = inst_i[21:10]; wire[19:0] imm_20 = inst_i[24:5]; @@ -124,18 +125,17 @@ module id( always @(*) begin - stallreq_for_reg1_loadrelate = `NoStop; if(rst == `RstEnable) - reg1_o = `ZeroWord; + stallreq_for_reg1_loadrelate = `NoStop; else if(pre_inst_is_load == 1'b1 && ex_waddr_i_1 == reg1_addr_o && reg1_read_o == 1'b1) stallreq_for_reg1_loadrelate = `Stop; end always @(*) begin - stallreq_for_reg2_loadrelate = `NoStop; + if(rst == `RstEnable) - reg2_o = `ZeroWord; + stallreq_for_reg2_loadrelate = `NoStop; else if(pre_inst_is_load == 1'b1 && ex_waddr_i_1 == reg2_addr_o && reg2_read_o == 1'b1) stallreq_for_reg2_loadrelate = `Stop; end @@ -459,8 +459,107 @@ module id( `EXE_SPECIAL: begin - // All CSR related instr is 8'b00000100 - + case (opcode_2) + `EXE_CSR_RELATED:begin + case (op2) + `EXE_CSRRD:begin + wreg_o = `WriteEnable; + aluop_o = `EXE_CSRRD_OP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + imm = {18'b0,imm_14}; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_CSRWR:begin + wreg_o = `WriteEnable; + aluop_o = `EXE_CSRWR_OP; + reg1_read_o = 1'b1; + reg2_read_o = 1'b0; + imm = {18'b0,imm_14}; + reg1_addr_o = op1; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + default:begin + wreg_o = `WriteEnable; + aluop_o = `EXE_CSRXCHG_OP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + imm = {18'b0,imm_14}; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + endcase + end + `EXE_OTHER:begin + case (opcode_3) + `EXE_TLB_RELATED:begin + case (opcode_22) + `EXE_TLBFILL:begin + wreg_o = `WriteDisable; + aluop_o = `EXE_TLBFILL_OP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + inst_valid = `InstValid; + end + `EXE_TLBRD:begin + wreg_o = `WriteDisable; + aluop_o = `EXE_TLBRD_OP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + inst_valid = `InstValid; + end + `EXE_TLBSRCH:begin + wreg_o = `WriteDisable; + aluop_o = `EXE_TLBSRCH_OP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + inst_valid = `InstValid; + end + `EXE_TLBWR:begin + wreg_o = `WriteDisable; + aluop_o = `EXE_TLBWR_OP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + inst_valid = `InstValid; + end + `EXE_ERTN:begin + wreg_o = `WriteDisable; + aluop_o = `EXE_ERTN_OP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + inst_valid = `InstValid; + end + default:begin + end + endcase + end + default:begin + case (opcode_17) + `EXE_IDLE:begin + wreg_o = `WriteDisable; + aluop_o = `EXE_IDLE_OP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + inst_valid = `InstValid; + end + `EXE_INVTLB:begin + wreg_o = `WriteDisable; + aluop_o = `EXE_INVTLB_OP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + inst_valid = `InstValid; + end + default: begin + end + endcase + end + endcase + end + default:begin + end + endcase end `EXE_ARITHMETIC: diff --git a/src/vsrc/pipeline/2_decode/id_ex.v b/src/vsrc/pipeline/2_decode/id_ex.v index 62493cf..a56151d 100644 --- a/src/vsrc/pipeline/2_decode/id_ex.v +++ b/src/vsrc/pipeline/2_decode/id_ex.v @@ -1,4 +1,4 @@ -`include "../../defines.v" +`include "defines.v" module id_ex ( input wire clk, input wire rst, @@ -42,28 +42,13 @@ module id_ex ( output reg stallreq ); - wire stallreq1; - wire stallreq2; - wire stallreq3; - wire stallreq4; - wire stallreq5; - wire stallreq6; - wire stallreq7; - - assign sallreq1 = id_inst_pc == pc_i_other + 4; - assign sallreq3 = (reg1_addr_i == reg1_addr_i_other) && reg1_addr_i != 0; - assign sallreq4 = (reg2_addr_i == reg2_addr_i_other) && reg2_addr_i != 0; - assign sallreq5 = reg1_addr_i == waddr_i_other; - assign sallreq6 = reg2_addr_i == waddr_i_other; - assign sallreq7 = stallreq3 | stallreq4 | stallreq5 | stallreq6; //always @(*) begin //stallreq = stallreq_from_id | stallreq1 | stallreq7; //end always @(*) begin - stallreq = stallreq_from_id | ((id_inst_pc == pc_i_other + 4) && (((reg1_addr_i == reg1_addr_i_other) && reg1_addr_i != 0 ) | ((reg2_addr_i == reg2_addr_i_other) && reg2_addr_i != 0) - | (reg1_addr_i == waddr_i_other) | (reg2_addr_i == waddr_i_other))); + stallreq = stallreq_from_id | ((id_inst_pc == pc_i_other + 4) && ( (reg1_addr_i == waddr_i_other) | (reg2_addr_i == waddr_i_other))); end diff --git a/src/vsrc/pipeline/3_execution/ex.v b/src/vsrc/pipeline/3_execution/ex.v index 3e54728..57045e2 100644 --- a/src/vsrc/pipeline/3_execution/ex.v +++ b/src/vsrc/pipeline/3_execution/ex.v @@ -1,4 +1,4 @@ -`include "../../defines.v" +`include "defines.v" module ex ( input wire rst, diff --git a/src/vsrc/pipeline/3_execution/ex_mem.v b/src/vsrc/pipeline/3_execution/ex_mem.v index dc6f2ae..a23ce64 100644 --- a/src/vsrc/pipeline/3_execution/ex_mem.v +++ b/src/vsrc/pipeline/3_execution/ex_mem.v @@ -1,4 +1,4 @@ -`include "../../defines.v" +`include "defines.v" module ex_mem ( input wire clk, diff --git a/src/vsrc/pipeline/4_mem/mem.v b/src/vsrc/pipeline/4_mem/mem.v index 3ed0041..d59cb47 100644 --- a/src/vsrc/pipeline/4_mem/mem.v +++ b/src/vsrc/pipeline/4_mem/mem.v @@ -1,4 +1,4 @@ -`include "../../defines.v" +`include "defines.v" module mem ( input wire rst, diff --git a/src/vsrc/pipeline/4_mem/mem_wb.v b/src/vsrc/pipeline/4_mem/mem_wb.v index 14a29dd..17196d4 100644 --- a/src/vsrc/pipeline/4_mem/mem_wb.v +++ b/src/vsrc/pipeline/4_mem/mem_wb.v @@ -1,4 +1,4 @@ -`include "../../defines.v" +`include "defines.v" module mem_wb ( input wire clk, diff --git a/src/vsrc/pipeline/pipeline_top.v b/src/vsrc/pipeline/pipeline_top.v deleted file mode 100644 index 99c431b..0000000 --- a/src/vsrc/pipeline/pipeline_top.v +++ /dev/null @@ -1,325 +0,0 @@ -`include "../defines.v" -`include "1_fetch/if_id.v" -`include "2_decode/id.v" -`include "2_decode/id_ex.v" -`include "3_execution/ex.v" -`include "3_execution/ex_mem.v" -`include "4_mem/mem.v" -`include "4_mem/mem_wb.v" - -module cpu_top ( - input wire clk, - input wire rst, - input wire[`RegBus] dram_data_i, - input wire[`RegBus] ram_rdata_i, - - output wire[`RegBus] ram_raddr_o, - output wire[`RegBus] ram_wdata_o, - output wire[`RegBus] ram_waddr_o, - output wire ram_wen_o, - output wire ram_en_o, - - output wire[`RegBus] dram_addr_o, - output wire[`RegBus] dram_data_o, - output wire dram_we_o, - output wire[3:0] dram_sel_o, - output wire dram_ce_o, - - output wire[`RegBus] debug_commit_pc, - output wire debug_commit_valid, - output wire[`InstBus] debug_commit_instr, - output wire debug_commit_wreg, - output wire[`RegAddrBus] debug_commit_reg_waddr, - output wire[`RegBus] debug_commit_reg_wdata, - output wire[1023:0] debug_reg, - output wire Instram_branch_flag - ); - - wire[`InstAddrBus] pc; - wire chip_enable; - - assign ram_en_o = chip_enable; - assign ram_raddr_o = pc; - - wire branch_flag; - assign Instram_branch_flag=branch_flag; - wire[`RegBus] branch_target_address; - wire[`RegBus] link_addr; - - wire [`InstAddrBus]pc2; - if_buffer if_buffer_1( - .clk(clk), - .rst(rst), - .pc_i(pc), - .branch_flag_i(branch_flag), - .pc_valid(if_inst_valid), - .pc_o(pc2) - ); - - - wire[`InstAddrBus] id_pc; - wire[`InstBus] id_inst; - wire if_inst_valid; - - // wire if_id_instr_invalid; - if_id u_if_id( - .clk(clk), - .rst(rst), - .if_pc_i(pc2), - .if_inst_i(ram_rdata_i), - .id_pc_o(id_pc), - .id_inst_o(id_inst), - .if_inst_valid(if_inst_valid), - .branch_flag_i(branch_flag) - ); - - wire[`AluOpBus] id_aluop; - wire[`AluSelBus] id_alusel; - wire[`RegBus] id_reg1; - wire[`RegBus] id_reg2; - wire[`RegAddrBus] id_reg_waddr; - wire id_wreg; - wire id_inst_valid; - wire[`InstAddrBus] id_inst_pc; - wire[`RegBus] id_inst_o; - - wire reg1_read; - wire reg2_read; - wire[`RegAddrBus] reg1_addr; - wire[`RegAddrBus] reg2_addr; - wire[`RegBus] reg1_data; - wire[`RegBus] reg2_data; - - wire ex_wreg_o; - wire[`RegAddrBus] ex_reg_waddr_o; - wire[`RegBus] ex_reg_wdata; - wire[`AluOpBus] ex_aluop_o; - - wire mem_wreg_o; - wire[`RegAddrBus] mem_reg_waddr_o; - wire[`RegBus] mem_reg_wdata_o; - - wire stallreq_from_id; - - - id u_id( - .rst(rst), - .pc_i(id_pc), - .inst_i(id_inst), - - .reg1_data_i (reg1_data ), - .reg2_data_i (reg2_data ), - - .ex_wreg_i (ex_wreg_o ), - .ex_waddr_i (ex_reg_waddr_o), - .ex_wdata_i (ex_reg_wdata), - .ex_aluop_i (ex_aluop_o), - - .mem_wreg_i (mem_wreg_o), - .mem_waddr_i (mem_reg_waddr_o), - .mem_wdata_i (mem_reg_wdata_o), - - .reg1_read_o (reg1_read ), - .reg2_read_o (reg2_read ), - - .reg1_addr_o (reg1_addr ), - .reg2_addr_o (reg2_addr ), - - .aluop_o (id_aluop ), - .alusel_o (id_alusel ), - .reg1_o (id_reg1 ), - .reg2_o (id_reg2 ), - .reg_waddr_o (id_reg_waddr ), - .wreg_o (id_wreg ), - .inst_valid(id_inst_valid), - .inst_pc(id_inst_pc), - .inst_o(id_inst_o), - - .branch_flag_o(branch_flag), - .branch_target_address_o(branch_target_address), - .link_addr_o(link_addr), - - .stallreq(stallreq_from_id) - ); - - wire[`AluOpBus] ex_aluop; - wire[`AluSelBus] ex_alusel; - wire[`RegBus] ex_reg1; - wire[`RegBus] ex_reg2; - wire[`RegAddrBus] ex_reg_waddr_i; - wire ex_wreg_i; - wire ex_inst_valid_i; - wire[`InstAddrBus] ex_inst_pc_i; - wire[`RegBus] ex_link_address; - wire[`RegBus] ex_inst_i; - - id_ex id_ex0( - .clk(clk), - .rst(rst), - - .id_aluop(id_aluop), - .id_alusel(id_alusel), - .id_reg1(id_reg1), - .id_reg2(id_reg2), - .id_wd(id_reg_waddr), - .id_wreg(id_wreg), - .id_inst_pc(id_inst_pc), - .id_inst_valid(id_inst_valid), - .id_link_address(link_addr), - .id_inst(id_inst_o), - - .ex_aluop(ex_aluop), - .ex_alusel(ex_alusel), - .ex_reg1(ex_reg1), - .ex_reg2(ex_reg2), - .ex_wd(ex_reg_waddr_i), - .ex_wreg(ex_wreg_i), - .ex_inst_pc(ex_inst_pc_i), - .ex_inst_valid(ex_inst_valid_i), - .ex_link_address(ex_link_address), - .ex_inst(ex_inst_i) - ); - - - wire ex_inst_valid_o; - wire[`InstAddrBus] ex_inst_pc_o; - wire[`RegBus] ex_addr_o; - wire[`RegBus] ex_reg2_o; - - ex u_ex( - .rst(rst), - - .aluop_i(ex_aluop), - .alusel_i(ex_alusel), - .reg1_i(ex_reg1), - .reg2_i(ex_reg2), - .wd_i(ex_reg_waddr_i), - .wreg_i(ex_wreg_i), - .inst_valid_i(ex_inst_valid_i), - .inst_pc_i(ex_inst_pc_i), - .inst_i(ex_inst_i), - .link_addr_i(ex_link_address), - - .wd_o(ex_reg_waddr_o), - .wreg_o(ex_wreg_o), - .wdata_o(ex_reg_wdata), - .inst_valid_o(ex_inst_valid_o), - .inst_pc_o(ex_inst_pc_o), - .aluop_o(ex_aluop_o), - .mem_addr_o(ex_addr_o), - .reg2_o(ex_reg2_o) - ); - - - wire mem_wreg_i; - wire[`RegAddrBus] mem_reg_waddr_i; - wire[`RegBus] mem_reg_wdata_i; - - wire mem_inst_valid; - wire[`InstAddrBus] mem_inst_pc; - - wire[`AluOpBus] mem_aluop_i; - wire[`RegBus] mem_addr_i; - wire[`RegBus] mem_reg2_i; - - ex_mem u_ex_mem( - .clk(clk ), - .rst(rst ), - - .ex_wd (ex_reg_waddr_o ), - .ex_wreg (ex_wreg_o ), - .ex_wdata (ex_reg_wdata ), - .ex_inst_pc(ex_inst_pc_o), - .ex_inst_valid(ex_inst_valid_o), - .ex_aluop(ex_aluop_o), - .ex_mem_addr(ex_addr_o), - .ex_reg2(ex_reg2_o), - - .mem_wd(mem_reg_waddr_i ), - .mem_wreg(mem_wreg_i ), - .mem_wdata(mem_reg_wdata_i ), - .mem_inst_valid(mem_inst_valid), - .mem_inst_pc(mem_inst_pc), - .mem_aluop(mem_aluop_i), - .mem_mem_addr(mem_addr_i), - .mem_reg2(mem_reg2_i) - ); - - wire LLbit_o; - wire wb_LLbit_we_i; - wire wb_LLbit_value_i; - wire mem_LLbit_we_o; - wire mem_LLbit_value_o; - - mem u_mem( - .rst (rst ), - - .wd_i (mem_reg_waddr_i ), - .wreg_i (mem_wreg_i ), - .wdata_i (mem_reg_wdata_i), - .aluop_i(mem_aluop_i), - .mem_addr_i(mem_addr_i), - .reg2_i(mem_reg2_i), - - .mem_data_i(dram_data_i), - - .LLbit_i(LLbit_o), - .wb_LLbit_we_i(wb_LLbit_we_i), - .wb_LLbit_value_i(wb_LLbit_value_i), - - - .wd_o (mem_reg_waddr_o), - .wreg_o (mem_wreg_o ), - .wdata_o (mem_reg_wdata_o ), - - .mem_addr_o(dram_addr_o), - .mem_we_o(dram_we_o), - .mem_sel_o(dram_sel_o), - .mem_data_o(dram_data_o), - .mem_ce_o(dram_ce_o), - - .LLbit_we_o(mem_LLbit_we_o), - .LLbit_value_o(mem_LLbit_value_o) - - ); - - - wire wb_wreg; - wire[`RegAddrBus] wb_reg_waddr; - wire[`RegBus] wb_reg_wdata; - - assign debug_commit_wreg = wb_wreg; - assign debug_commit_reg_waddr = wb_reg_waddr; - assign debug_commit_reg_wdata = wb_reg_wdata; - - - - mem_wb mem_wb0( - .clk(clk), - .rst(rst), - - .mem_wd(mem_reg_waddr_o), - .mem_wreg(mem_wreg_o), - .mem_wdata(mem_reg_wdata_o), - .mem_inst_pc (mem_inst_pc ), - .mem_instr ( ), - .mem_inst_valid (mem_inst_valid ), - - .mem_LLbit_we(mem_LLbit_we_o), - .mem_LLbit_value(mem_LLbit_value_o), - - .wb_wd(wb_reg_waddr), - .wb_wreg(wb_wreg), - .wb_wdata(wb_reg_wdata), - - .wb_LLbit_we(wb_LLbit_we_i), - .wb_LLbit_value(wb_LLbit_value_i), - - .debug_commit_pc (debug_commit_pc ), - .debug_commit_valid (debug_commit_valid ), - .debug_commit_instr (debug_commit_instr ) - ); - - - -endmodule \ No newline at end of file diff --git a/src/vsrc/tlb.v b/src/vsrc/tlb.v new file mode 100644 index 0000000..4c1a0ea --- /dev/null +++ b/src/vsrc/tlb.v @@ -0,0 +1,19 @@ +`include "defines.v" +module tlb #( + parameter TLBNum = 32; +)( + input wire clk, + input wire rst, + + input wire[] asid, + + input wire inst_en, + input wire data_en, + + input wire inst_match, + input wire inst_vaddr, + input +); + + +endmodule \ No newline at end of file diff --git a/src/vsrc/tlb_entry.v b/src/vsrc/tlb_entry.v new file mode 100644 index 0000000..3c5b201 --- /dev/null +++ b/src/vsrc/tlb_entry.v @@ -0,0 +1,96 @@ +module tlb_entry +#( + parameter TLBNum = 32; + parameter EntryLen = 88:0; + parameter TLB_e = 0; + parameter TLB_asid = 10:1; + parameter TLB_g = 11; + parameter TLB_ps = 17:12; + parameter TLB_vppn = 36:18; + parameter TLB_v0 = 37; + parameter TLB_d0 = 38; + parameter TLB_mat0 = 40:39; + parameter TLB_plv0 = 42:41; + parameter TLB_ppn0 = 62:43; + parameter TLB_v1 = 63; + parameter TLB_d1 = 64; + parameter TLB_mat1 = 66:65; + parameter TLB_plv1 = 68:67; + parameter TLB_ppn1 = 88:69; +) +( + input wire clk, + input wire rst, + + input wire s0_match, + input wire [18:0] s0_vppn, + input wire s0_odd_page, + input wire [9:0]s0_asid, + + output reg s0_found, + output reg[$clog2(TLBNUM)-1:0] s0_index , + output reg[5:0] s0_ps, + output reg[19:0] s0_ppn, + output reg s0_v, + output reg s0_d, + output reg[1:0] s0_mat, + output reg[1:0] s0_plv, + + input wire s1_match, + input wire [18:0] s1_vppn, + input wire s1_odd_page, + input wire [9:0]s1_asid, + + output reg s1_found, + output reg[$clog2(TLBNUM)-1:0] s1_index , + output reg[5:0] s1_ps, + output reg[19:0] s1_ppn, + output reg s1_v, + output reg s1_d, + output reg[1:0] s1_mat, + output reg[1:0] s1_plv, + + input wire we, + input wire[$clog2(TLBNUM)-1:0] w_index, + input wire[18:0] w_vppn, + input wire[ 9:0] w_asid, + input wire w_g , + input wire [5:0]w_ps, + input wire w_e, + input wire w_v0, + input wire w_d0, + input wire [1:0] w_mat0, + input wire [1:0] w_plv0, + input wire [19:0] w_ppn0, + input wire w_v1, + input wire w_d1, + input wire [1:0] w_mat1, + input wire [1:0] w_plv1, + input wire [19:0] w_ppn1, + + input wire[$clog2(TLBNUM)-1:0] r_index, + output wire[18:0] r_vppn, + output wire[ 9:0] r_asid, + output wire r_g , + output wire[5:0] r_ps, + output wire r_e, + output wire r_v0, + output wire r_d0, + output wire[1:0]r_mat0, + output wire[1:0]r_plv0, + output wire[19:0]r_ppn0, + output wire r_v1, + output wire r_d1, + output wire[1:0] r_mat1, + output wire[1:0] r_plv1 , + output wire[19:0] r_ppn1, + + input wire inv_en, + input wire[ 4:0] inv_op, + input wire[ 9:0] inv_asid, + input wire[18:0] inv_vpn +); + +reg [EntryLen] entry [TLBNum-1:0]; + +endmodule \ No newline at end of file From b040b52f5153ae52804d472d625ad0a90505a7db Mon Sep 17 00:00:00 2001 From: Rookie <74707760+Rookie-Cai-niao@users.noreply.github.com> Date: Thu, 21 Apr 2022 22:21:27 +0800 Subject: [PATCH 031/114] implementation success --- src/vsrc/cpu_top.v | 30 ++++++++++++++++++------------ src/vsrc/ctrl.v | 20 +++++++++++++++++--- src/vsrc/defines.v | 2 +- src/vsrc/pc_reg.v | 19 +++++++++++++------ 4 files changed, 49 insertions(+), 22 deletions(-) diff --git a/src/vsrc/cpu_top.v b/src/vsrc/cpu_top.v index ab606ef..08a344d 100644 --- a/src/vsrc/cpu_top.v +++ b/src/vsrc/cpu_top.v @@ -67,9 +67,11 @@ module cpu_top ( assign ram_raddr_o_1 = pc_buffer_1; assign ram_raddr_o_2 = pc_buffer_2; - wire branch_flag; + wire branch_flag_1; + wire branch_flag_2; assign Instram_branch_flag=branch_flag; - wire[`RegBus] branch_target_address; + wire[`RegBus] branch_target_address_1; + wire[`RegBus] branch_target_address_2; wire[`RegBus] link_addr; wire flush; wire[`RegBus] new_pc; @@ -82,8 +84,10 @@ module cpu_top ( .pc_1(pc_1), .pc_2(pc_2), .ce(chip_enable), - .branch_flag_i(branch_flag), - .branch_target_address(branch_target_address), + .branch_flag_i_1(branch_flag_1), + .branch_target_address_1(branch_target_address_1), + .branch_flag_i_2(branch_flag_2), + .branch_target_address_2(branch_target_address_2), .flush(flush), .new_pc(new_pc), .stall1(stall1[0]), @@ -245,8 +249,8 @@ module cpu_top ( .inst_pc(id_inst_pc_1), .inst_o(id_inst_o_1), - .branch_flag_o(branch_flag), - .branch_target_address_o(branch_target_address), + .branch_flag_o(branch_flag_1), + .branch_target_address_o(branch_target_address_1), .link_addr_o(link_addr_1), .stallreq(stallreq_to_next_1), @@ -324,8 +328,8 @@ module cpu_top ( .inst_pc(id_inst_pc_2), .inst_o(id_inst_o_2), - .branch_flag_o(branch_flag), - .branch_target_address_o(branch_target_address), + .branch_flag_o(branch_flag_2), + .branch_target_address_o(branch_target_address_2), .link_addr_o(link_addr_2), .stallreq(stallreq_to_next_2), @@ -614,7 +618,8 @@ module cpu_top ( wire wb_LLbit_value_i_1; wire mem_LLbit_we_o_1; wire mem_LLbit_value_o_1; - wire[1:0] mem_excepttype_o; + wire[1:0] mem_excepttype_o_1; + wire[1:0] mem_excepttype_o_2; wire[`RegBus] mem_current_inst_address_o_1; wire[`InstAddrBus] wb_inst_pc_1; @@ -652,7 +657,7 @@ module cpu_top ( .LLbit_we_o(mem_LLbit_we_o_1), .LLbit_value_o(mem_LLbit_value_o_1), - .excepttype_o(mem_excepttype_o), + .excepttype_o(mem_excepttype_o_1), .current_inst_address_o(mem_current_inst_address_o_1) ); @@ -699,7 +704,7 @@ module cpu_top ( .LLbit_we_o(mem_LLbit_we_o_2), .LLbit_value_o(mem_LLbit_value_o_2), - .excepttype_o(mem_excepttype_o), + .excepttype_o(mem_excepttype_o_2), .current_inst_address_o(mem_current_inst_address_o_2) ); @@ -820,7 +825,8 @@ module cpu_top ( .stall2(stall2), .stallreq_from_id_2(stallreq_from_id_2), .stallreq_from_ex_2(stallreq_from_ex_2), - .excepttype_i(mem_excepttype_o), + .excepttype_i_1(mem_excepttype_o_1), + .excepttype_i_2(mem_excepttype_o_2), .new_pc(new_pc), .flush(flush) ); diff --git a/src/vsrc/ctrl.v b/src/vsrc/ctrl.v index da829b8..64af4a5 100644 --- a/src/vsrc/ctrl.v +++ b/src/vsrc/ctrl.v @@ -7,7 +7,8 @@ module ctrl ( input wire stallreq_from_id_2, input wire stallreq_from_ex_2, - input wire[1:0] excepttype_i, + input wire[1:0] excepttype_i_1, + input wire[1:0] excepttype_i_2, output reg[6:0]stall1, output reg[6:0]stall2, @@ -25,10 +26,23 @@ module ctrl ( new_pc = `ZeroWord; end else - if(excepttype_i != 0) + if(excepttype_i_1 != 0) begin flush = 1'b1; - case (excepttype_i) + case (excepttype_i_1) + 2'b01: + new_pc = 32'h0000000c; + 2'b10: + new_pc = 32'h0000000c; + default: + begin + end + endcase + end + else if(excepttype_i_2 != 0) + begin + flush = 1'b1; + case (excepttype_i_2) 2'b01: new_pc = 32'h0000000c; 2'b10: diff --git a/src/vsrc/defines.v b/src/vsrc/defines.v index fc97157..ddc4ef2 100644 --- a/src/vsrc/defines.v +++ b/src/vsrc/defines.v @@ -194,7 +194,7 @@ //data_ram `define DataAddrBus 31:0 `define DataBus 31:0 -`define DataMemNum 131071 +`define DataMemNum 128 `define DataMemNumLog2 17 `define ByteWidth 7:0 diff --git a/src/vsrc/pc_reg.v b/src/vsrc/pc_reg.v index 557b933..f2849d0 100644 --- a/src/vsrc/pc_reg.v +++ b/src/vsrc/pc_reg.v @@ -5,8 +5,11 @@ module pc_reg ( input wire stall1, input wire stall2, - input wire branch_flag_i, - input wire[`RegBus] branch_target_address, + input wire branch_flag_i_1, + input wire[`RegBus] branch_target_address_1, + + input wire branch_flag_i_2, + input wire[`RegBus] branch_target_address_2, input wire flush, input wire[`RegBus] new_pc, @@ -28,8 +31,10 @@ module pc_reg ( end else begin - if(branch_flag_i == `Branch) - pc_1 <= branch_target_address; + if(branch_flag_i_1 == `Branch) + pc_1 <= branch_target_address_1; + else if(branch_flag_i_2 == `Branch) + pc_1 <= branch_target_address_2; else pc_1 <= pc_1 + 32'h8; end @@ -47,8 +52,10 @@ module pc_reg ( end else begin - if(branch_flag_i == `Branch) - pc_2 <= branch_target_address + 4'h4; + if(branch_flag_i_1 == `Branch) + pc_2 <= branch_target_address_1 + 4'h4; + if(branch_flag_i_2 == `Branch) + pc_2 <= branch_target_address_2 + 4'h4; else pc_2 <= pc_2 + 32'h8; end From 39a581297aab565ed403ac7dd3fe7ee25cc93b1a Mon Sep 17 00:00:00 2001 From: Easton Man Date: Fri, 22 Apr 2022 09:36:33 +0800 Subject: [PATCH 032/114] refactor: use sv truct as PHT entry - add useful counter --- src/vsrc/branch_predictor/tage_predictor.sv | 17 ++-- src/vsrc/branch_predictor/tagged_predictor.sv | 77 ++++++++++--------- 2 files changed, 54 insertions(+), 40 deletions(-) diff --git a/src/vsrc/branch_predictor/tage_predictor.sv b/src/vsrc/branch_predictor/tage_predictor.sv index ef8f09b..06c7b43 100644 --- a/src/vsrc/branch_predictor/tage_predictor.sv +++ b/src/vsrc/branch_predictor/tage_predictor.sv @@ -30,10 +30,17 @@ module tage_predictor ( end `endif + + // Reset + logic rst_n; + assign rst_n = ~rst; + // Global History Register bit [`GHR_BUS] GHR; - always @(posedge clk) begin - if (branch_valid_i) begin + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + GHR <= 0; + end else if (branch_valid_i) begin // Shift left for every valid branch GHR <= {GHR[`GHR_DEPTH-2:0], branch_taken_i}; end @@ -77,14 +84,13 @@ module tage_predictor ( logic [3:0] tag_hit; logic [$clog2(TAG_COMPONENT_AMOUNT):0] accept_prediction_id; logic [4:0] tag_update_valid; - localparam integer provider_ghr_length[TAG_COMPONENT_AMOUNT] = '{10, 20, 40, 80}; + localparam integer provider_ghr_length[TAG_COMPONENT_AMOUNT] = '{5, 10, 40, 130}; generate genvar provider_id; for ( provider_id = 0; provider_id < TAG_COMPONENT_AMOUNT; provider_id = provider_id + 1 ) begin - logic valid = (accept_prediction_id == provider_id) ? branch_valid_i : 0; tagged_predictor #( .INPUT_GHR_LENGTH(provider_ghr_length[provider_id]), .PHT_DEPTH_EXP2 (10) @@ -152,9 +158,10 @@ module tage_predictor ( end + // Output logic, select the longest matched provider fpa #( .LINES(5) - ) u_fpa ( + ) prediction_select ( .unitary_in({tag_hit, 1'b1}), .binary_out(accept_prediction_id) ); diff --git a/src/vsrc/branch_predictor/tagged_predictor.sv b/src/vsrc/branch_predictor/tagged_predictor.sv index 245ed18..4667e8d 100644 --- a/src/vsrc/branch_predictor/tagged_predictor.sv +++ b/src/vsrc/branch_predictor/tagged_predictor.sv @@ -10,6 +10,8 @@ module tagged_predictor #( parameter PC_WIDTH = 32, parameter PHT_DEPTH_EXP2 = 10, parameter PHT_TAG_WIDTH = 8, + parameter PHT_CTR_WIDTH = 3, + parameter PHT_USEFUL_WIDTH = 2, parameter HASH_BUFFER_SIZE = 10 ) ( input logic clk, @@ -38,10 +40,16 @@ module tagged_predictor #( assign update_taken = update_instr_info[0]; // PHT - // - entry: {3bits bimodal, xbits tag} - logic [PHT_TAG_WIDTH+2:0] PHT[2**PHT_DEPTH_EXP2]; + typedef struct packed { + bit [PHT_CTR_WIDTH-1:0] ctr; + bit [PHT_TAG_WIDTH-1:0] tag; + bit [PHT_USEFUL_WIDTH-1:0] useful; + } pht_entry; + pht_entry PHT[2**PHT_DEPTH_EXP2]; + + // Query Index // Fold GHT input to a fix length, the same as index range // Using a CSR, described in PPM-Liked essay logic [PHT_DEPTH_EXP2-1:0] hashed_ght_input; @@ -54,12 +62,12 @@ module tagged_predictor #( .data_i(global_history_i), .hash_o(hashed_ght_input) ); - - + // query_index in Fold(GHR) ^ PC[low] ^ PC[high] + logic [PHT_DEPTH_EXP2-1:0] query_index; + assign query_index = (hashed_ght_input ^ pc_i[PHT_DEPTH_EXP2-1:0] ^ pc_i[PHT_DEPTH_EXP2*2-1:PHT_DEPTH_EXP2]); // Tag - // Generate a hashed tage from only pc, as described in PPM-Liked essay - // csr1 < ght[high] < csr2 < ght[0] + // Generate another hash different from above, as described in PPM-Liked essay logic [PHT_TAG_WIDTH-1:0] pc_hash_csr1; logic [PHT_TAG_WIDTH-2:0] pc_hash_csr2; csr_hash #( @@ -81,29 +89,23 @@ module tagged_predictor #( .hash_o(pc_hash_csr2) ); - logic [PHT_TAG_WIDTH-1:0] hashed_pc_tag; - assign hashed_pc_tag = pc_i[PHT_TAG_WIDTH-1:0] ^ pc_hash_csr1 ^ {pc_hash_csr2, 1'b0}; + logic [PHT_TAG_WIDTH-1:0] query_tag; + assign query_tag = pc_i[PHT_TAG_WIDTH-1:0] ^ pc_hash_csr1 ^ {pc_hash_csr2, 1'b0}; - // hash with pc, and concatenate to PHT_DEPTH_EXP2 - // the low 2bits of pc is usually 0, so use upper bits - logic [PHT_DEPTH_EXP2-1:0] query_hashed_index; - assign query_hashed_index = (hashed_ght_input ^ pc_i[PHT_DEPTH_EXP2-1:0] ^ pc_i[PHT_DEPTH_EXP2*2-1:PHT_DEPTH_EXP2]); // Query logic ========================================== - logic [2:0] query_result_bimodal; - assign query_result_bimodal = PHT[query_hashed_index][PHT_TAG_WIDTH+2:PHT_TAG_WIDTH]; - logic [PHT_TAG_WIDTH-1:0] query_result_tag; - assign query_result_tag = PHT[query_hashed_index][PHT_TAG_WIDTH-1:0]; + pht_entry query_result; + assign query_result = PHT[query_index]; - assign taken = (query_result_bimodal[2] == 1'b1); - assign tag_hit = (hashed_pc_tag == query_result_tag); - // assign tag_hit = 1; + // Assign Output + assign taken = (query_result.ctr[PHT_CTR_WIDTH-1] == 1'b1); + assign tag_hit = (query_tag == query_result.tag); // Use a buffer to hold the query_index and pc - // entry: {valid 1, pc PC_WIDTH, query_index} + // This is used when branch update came in with uncertain delay typedef struct packed { bit valid; bit [PC_WIDTH-1:0] pc; @@ -114,7 +116,7 @@ module tagged_predictor #( logic [HASH_BUFFER_SIZE-1:0] pc_match_table; // indicates which entry in the buffer is a match // Move from lower to higher - assign hash_buffer[0] = {(pc_i != 0), pc_i, query_hashed_index, hashed_pc_tag}; + assign hash_buffer[0] = {(pc_i != 0), pc_i, query_index, query_tag}; generate for (genvar i = 1; i < HASH_BUFFER_SIZE; i = i + 1) begin always @(posedge clk) begin @@ -151,31 +153,36 @@ module tagged_predictor #( // Update logic =========================================================== - always @(posedge clk or negedge rst_n) begin + always_ff @(posedge clk or negedge rst_n) begin if (!rst_n) begin - // Reset all PHT to 01 + // Reset all PHT, useful to 0, ctr to weak taken for (integer i = 0; i < 2 ** PHT_DEPTH_EXP2; i = i + 1) begin - PHT[i] = {3'b100, {PHT_TAG_WIDTH{1'b0}}}; + PHT[i].ctr = {1'b1, {PHT_CTR_WIDTH - 1{1'b0}}}; + PHT[i].tag = 0; + PHT[i].useful = 0; end end else begin if (update_valid & update_match_valid) begin - // 000,001,010,011 | 100,101,110,111 - - case (PHT[update_index][PHT_TAG_WIDTH+2:PHT_TAG_WIDTH]) - 3'b000: begin - PHT[update_index][PHT_TAG_WIDTH+2:PHT_TAG_WIDTH] <= update_taken ? 3'b001 : 3'b000; + // Update PHT entry + case (PHT[update_index].ctr) + {PHT_CTR_WIDTH{1'b0}} : begin + PHT[update_index].ctr <= update_taken ? {{PHT_CTR_WIDTH-1{1'b0}},1'b1} : {PHT_CTR_WIDTH{1'b0}}; end - 3'b111: begin - PHT[update_index][PHT_TAG_WIDTH+2:PHT_TAG_WIDTH] <= update_taken ? 3'b111 : 3'b110; + {PHT_CTR_WIDTH{1'b1}} : begin + PHT[update_index].ctr <= update_taken ? {PHT_CTR_WIDTH{1'b1}}:{{PHT_CTR_WIDTH-1{1'b1}},1'b0}; end default: begin - PHT[update_index][PHT_TAG_WIDTH+2:PHT_TAG_WIDTH] <= update_taken ? PHT[update_index][PHT_TAG_WIDTH+2:PHT_TAG_WIDTH] +1 : PHT[update_index][PHT_TAG_WIDTH+2:PHT_TAG_WIDTH] -1; + PHT[update_index].ctr <= update_taken ? PHT[update_index].ctr +1 : PHT[update_index].ctr -1; end endcase - if (PHT[update_index][PHT_TAG_WIDTH-1:0] != update_tag) // Miss tag - begin // Do swap - PHT[update_index][PHT_TAG_WIDTH-1:0] <= {update_tag}; + if (PHT[update_index].tag != update_tag) // Miss tag + begin + PHT[update_index].tag <= update_tag; + PHT[update_index].ctr <= {1'b1, {PHT_CTR_WIDTH - 1{1'b0}}}; // Reset CTR + PHT[update_index].useful <= 0; // Reset useful counter + + // PHT[update_index] <= {3'b100, update_tag}; end end From c96b1b0935d29b39389c3c443379ab0af8902fb4 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Fri, 22 Apr 2022 11:11:16 +0800 Subject: [PATCH 033/114] feat: implement useful cnt based update policy --- src/vsrc/branch_predictor/Makefile | 6 +- src/vsrc/branch_predictor/btb.sv | 47 +++--- .../{defines.v => defines.sv} | 2 - src/vsrc/branch_predictor/tage_predictor.sv | 154 ++++++++++++++---- src/vsrc/branch_predictor/tagged_predictor.sv | 52 ++++-- 5 files changed, 184 insertions(+), 77 deletions(-) rename src/vsrc/branch_predictor/{defines.v => defines.sv} (90%) diff --git a/src/vsrc/branch_predictor/Makefile b/src/vsrc/branch_predictor/Makefile index 4751b3e..fa338cb 100644 --- a/src/vsrc/branch_predictor/Makefile +++ b/src/vsrc/branch_predictor/Makefile @@ -1,6 +1,6 @@ -cbp3: *.v *.sv - verilator $(VERILATOR_FLAGS) tage_predictor.sv --exe cbp3.cpp --cc -I../ | true # Ignore errors +cbp3: *.sv + verilator -O3 tage_predictor.sv --exe cbp3.cpp --cc -I../ | true # Ignore errors @make -C obj_dir -f Vtage_predictor.mk 2>&1 >/dev/null trace_id=0; while [[ $$trace_id -lt 20 ]]; do \ echo $$(./obj_dir/Vtage_predictor $$trace_id | grep MPKI); \ @@ -16,7 +16,7 @@ test: verilate VERILATOR_FLAGS = -O3 #+define+DUMP_WAVEFORM=1 --trace -verilate: *.v *.sv +verilate: *.sv verilator $(VERILATOR_FLAGS) tage_predictor.sv --exe testbench.cpp --cc -I../ | true # Ignore errors @make -C obj_dir -f Vtage_predictor.mk 2>&1 >/dev/null diff --git a/src/vsrc/branch_predictor/btb.sv b/src/vsrc/branch_predictor/btb.sv index 5e14456..32f94fa 100644 --- a/src/vsrc/branch_predictor/btb.sv +++ b/src/vsrc/branch_predictor/btb.sv @@ -1,5 +1,5 @@ // Branch Target Buffer -`include "branch_predictor/defines.v" +`include "branch_predictor/defines.sv" `include "../defines.v" @@ -15,43 +15,44 @@ module btb ( output wire [`RegBus] branch_target_address_o, output wire btb_hit - ); +); - /** A entry in BTB looks like this: + /** A entry in BTB looks like this: [tag[`BTB_TAG_LENGTH], target[30]] - target: target[31:2], lower 2bit is usually 0 */ - reg [`BTB_ENTRY_BUS] btb_entries[`BTB_DEPTH-1:0]; + reg [`BTB_ENTRY_BUS] btb_entries[`BTB_DEPTH-1:0]; - // Query logic //////////////////////////////////// + // Query logic //////////////////////////////////// - // pc_i[2+2x`BTB_DEPTH_LOG2:2] is first hashed into `BTB_DEPTH_LOG2 as an index - // use a 2-stage XOR for now - wire[`BTB_DEPTH_LOG2-1:0] query_hashed_index = (query_pc_i[`BTB_DEPTH_LOG2+1:2] ^ query_pc_i[`BTB_DEPTH_LOG2+`BTB_DEPTH_LOG2+1:`BTB_DEPTH_LOG2+2]) ^ query_pc_i[`BTB_DEPTH_LOG2+1:2]; + // pc_i[2+2x`BTB_DEPTH_LOG2:2] is first hashed into `BTB_DEPTH_LOG2 as an index + // use a 2-stage XOR for now + wire[`BTB_DEPTH_LOG2-1:0] query_hashed_index = (query_pc_i[`BTB_DEPTH_LOG2+1:2] ^ query_pc_i[`BTB_DEPTH_LOG2+`BTB_DEPTH_LOG2+1:`BTB_DEPTH_LOG2+2]) ^ query_pc_i[`BTB_DEPTH_LOG2+1:2]; - // Extract the entry - wire[`BTB_ENTRY_BUS] btb_entry = btb_entries[query_hashed_index]; + // Extract the entry + wire [`BTB_ENTRY_BUS] btb_entry = btb_entries[query_hashed_index]; - // Mark hit flag, use the lower bits of query_pc_i as tag - assign btb_hit = (btb_entry[`BTB_ENTRY_LENGTH-1:`BTB_ENTRY_LENGTH-`BTB_TAG_LENGTH] == query_pc_i[`BTB_TAG_LENGTH+1:2]); + // Mark hit flag, use the lower bits of query_pc_i as tag + assign btb_hit = (btb_entry[`BTB_ENTRY_LENGTH-1:`BTB_ENTRY_LENGTH-`BTB_TAG_LENGTH] == query_pc_i[`BTB_TAG_LENGTH+1:2]); - // Output branch_target_address_o if btb_hit - assign branch_target_address_o = btb_hit ? {btb_entry[`BTB_ENTRY_LENGTH-`BTB_TAG_LENGTH-1:0],2'b0} : 32'b0; + // Output branch_target_address_o if btb_hit + assign branch_target_address_o = btb_hit ? {btb_entry[`BTB_ENTRY_LENGTH-`BTB_TAG_LENGTH-1:0],2'b0} : 32'b0; - // Update logic ///////////////////////////////// + // Update logic ///////////////////////////////// - // Also hashed in the same way as query_hashed_index - wire[`BTB_DEPTH_LOG2-1:0] update_hashed_index = (update_pc_i[`BTB_DEPTH_LOG2+1:2] ^ update_pc_i[`BTB_DEPTH_LOG2+`BTB_DEPTH_LOG2+1:`BTB_DEPTH_LOG2+2]) ^ update_pc_i[`BTB_DEPTH_LOG2+1:2]; + // Also hashed in the same way as query_hashed_index + wire[`BTB_DEPTH_LOG2-1:0] update_hashed_index = (update_pc_i[`BTB_DEPTH_LOG2+1:2] ^ update_pc_i[`BTB_DEPTH_LOG2+`BTB_DEPTH_LOG2+1:`BTB_DEPTH_LOG2+2]) ^ update_pc_i[`BTB_DEPTH_LOG2+1:2]; - // update each cycle - always @(posedge clk) - begin - if (update_valid) - begin - btb_entries[update_hashed_index] <= {btb_entry[`BTB_ENTRY_LENGTH-1:`BTB_ENTRY_LENGTH-`BTB_TAG_LENGTH],update_branch_target_i[`RegWidth-1:2]}; + // update each cycle + always @(posedge clk) begin + if (update_valid) begin + btb_entries[update_hashed_index] <= { + btb_entry[`BTB_ENTRY_LENGTH-1:`BTB_ENTRY_LENGTH-`BTB_TAG_LENGTH], + update_branch_target_i[`RegWidth-1:2] + }; end end diff --git a/src/vsrc/branch_predictor/defines.v b/src/vsrc/branch_predictor/defines.sv similarity index 90% rename from src/vsrc/branch_predictor/defines.v rename to src/vsrc/branch_predictor/defines.sv index 76961f9..4c2b689 100644 --- a/src/vsrc/branch_predictor/defines.v +++ b/src/vsrc/branch_predictor/defines.sv @@ -15,7 +15,5 @@ `define MAX_GHT_LENGTH 512 `define MAX_GHT_LENGTH_LOG2 9 -// Parameters -`define FEEDBACK_LATENCY 4 `endif diff --git a/src/vsrc/branch_predictor/tage_predictor.sv b/src/vsrc/branch_predictor/tage_predictor.sv index 06c7b43..71b44c7 100644 --- a/src/vsrc/branch_predictor/tage_predictor.sv +++ b/src/vsrc/branch_predictor/tage_predictor.sv @@ -2,11 +2,14 @@ // This is the main predictor `include "../defines.v" -`include "branch_predictor/defines.v" +`include "branch_predictor/defines.sv" `include "branch_predictor/utils/fpa.sv" -module tage_predictor ( +module tage_predictor #( + parameter PROVIDER_HISTORY_BUFFER_SIZE = 10, + parameter TAGGED_PREDICTOR_USEFUL_WIDTH = 2 +) ( input logic clk, input logic rst, input logic [`RegBus] pc_i, @@ -76,49 +79,84 @@ module tage_predictor ( ); - + // The provider id of the accepted prediction + logic [$clog2(TAG_COMPONENT_AMOUNT):0] pred_prediction_id; + // The provider id of the last hit provider + logic [$clog2(TAG_COMPONENT_AMOUNT):0] altpred_prediction_id; + // For example, provider 2,4 hit, and provider 1,3 missed + // then pred is 4, and altpred is 2 // Tagged Predictors localparam TAG_COMPONENT_AMOUNT = 4; - logic [3:0] tag_taken; - logic [3:0] tag_hit; - logic [$clog2(TAG_COMPONENT_AMOUNT):0] accept_prediction_id; - logic [4:0] tag_update_valid; + // History length of each tagged predictor localparam integer provider_ghr_length[TAG_COMPONENT_AMOUNT] = '{5, 10, 40, 130}; + // Query structs + logic [TAG_COMPONENT_AMOUNT-1:0] tag_taken; + logic [TAG_COMPONENT_AMOUNT-1:0] tag_hit; + logic query_tag_useful; + assign query_tag_useful = (taken[pred_prediction_id] != taken[altpred_prediction_id]); + // Update structs + logic [TAG_COMPONENT_AMOUNT:0] tag_update_valid; // Including base predictor + logic [TAG_COMPONENT_AMOUNT-1:0] tag_update_useful; + logic [TAG_COMPONENT_AMOUNT-1:0] tag_update_useful_inc; + logic [TAGGED_PREDICTOR_USEFUL_WIDTH-1:0] tag_update_query_useful[TAG_COMPONENT_AMOUNT]; + generate genvar provider_id; for ( provider_id = 0; provider_id < TAG_COMPONENT_AMOUNT; provider_id = provider_id + 1 ) begin + typedef struct packed { + logic [`RegWidth-1:0] pc; + logic taken; + logic inc; + logic useful; + } update_info_struct; + update_info_struct update_info; + assign update_info.pc = branch_pc_i; + assign update_info.taken = branch_taken_i; + assign update_info.inc = tag_update_useful_inc[provider_id]; + assign update_info.useful = tag_update_useful[provider_id]; + tagged_predictor #( .INPUT_GHR_LENGTH(provider_ghr_length[provider_id]), - .PHT_DEPTH_EXP2 (10) + .PHT_DEPTH_EXP2 (10), + .PHT_USEFUL_WIDTH(TAGGED_PREDICTOR_USEFUL_WIDTH), + .PC_WIDTH (`RegWidth) ) tag_predictor ( - .clk (clk), - .rst (rst), - .global_history_i (GHR[provider_ghr_length[provider_id]:0]), - .pc_i (pc_i), - .update_valid (tag_update_valid[provider_id+1]), - .update_instr_info({branch_pc_i, branch_taken_i}), - .taken (tag_taken[provider_id]), - .tag_hit (tag_hit[provider_id]) + .clk(clk), + .rst(rst), + .global_history_i(GHR[provider_ghr_length[provider_id]:0]), + .pc_i(pc_i), + .update_valid(tag_update_valid[provider_id+1]), + .update_instr_info(update_info), + .update_query_useful_o(tag_update_query_useful[provider_id]), + .taken(tag_taken[provider_id]), + .tag_hit(tag_hit[provider_id]) ); end endgenerate // Update policy + // CTR policy // Update on a correct prediction: update the ctr bits of the provider // Update on a wrong prediction: update the ctr bits of the provider, then allocate an entry in a longer history component - // - // Buffer content: pc, accepted_provider_id, predicted_taken + // Useful policy + // if pred != altpred, then the pred is useful, and the provider is updated when result come + // if pred is correct, then increase useful counter, else decrese typedef struct packed { bit [`RegBus] pc; - bit [$clog2(TAG_COMPONENT_AMOUNT+1)-1:0] accepted_provider_id; + bit [$clog2(TAG_COMPONENT_AMOUNT+1)-1:0] pred_provider_id; + bit useful; bit taken; } provider_history_entry; - provider_history_entry provider_history_buffer[10]; // TODO: parameterize 10 - assign provider_history_buffer[0] = {pc_i, accept_prediction_id, predict_branch_taken_o}; + provider_history_entry provider_history_buffer[PROVIDER_HISTORY_BUFFER_SIZE]; + + // Shift left + assign provider_history_buffer[0] = { + pc_i, pred_prediction_id, query_tag_useful, predict_branch_taken_o + }; always_ff @(posedge clk) begin : shift for (integer i = 1; i < 10; i++) begin if (i == provider_history_matched_id + 1) begin @@ -126,55 +164,103 @@ module tage_predictor ( end else provider_history_buffer[i] <= provider_history_buffer[i-1]; end end - bit [10-1:0] provider_history_match; + + // Generate provider histry entry that matched update pc siganl + bit [PROVIDER_HISTORY_BUFFER_SIZE-1:0] provider_history_match; always_comb begin : provider_history_search // match pc with update signals - for (integer i = 0; i < 10; i++) begin + for (integer i = 0; i < PROVIDER_HISTORY_BUFFER_SIZE; i++) begin provider_history_match[i] = (branch_pc_i == provider_history_buffer[i].pc); end end - logic [$clog2(10)-1:0] provider_history_matched_id; // The entry id of the matched pc + logic [$clog2( +PROVIDER_HISTORY_BUFFER_SIZE +)-1:0] provider_history_matched_id; // The entry id of the matched pc fpa #( - .LINES(10) + .LINES(PROVIDER_HISTORY_BUFFER_SIZE) ) u_fpa_provider_history_matched_id ( .unitary_in(provider_history_match), .binary_out(provider_history_matched_id) ); + logic [TAG_COMPONENT_AMOUNT-1:0] tag_update_query_useful_match; + always_comb begin + for (integer i = 0; i < TAG_COMPONENT_AMOUNT; i++) begin + tag_update_query_useful_match[i] = tag_update_query_useful[i] == 0; + end + end + logic [$clog2(TAG_COMPONENT_AMOUNT+1)-1:0] tag_update_useful_zero_id; + fpa #( + .LINES(TAG_COMPONENT_AMOUNT + 1) + ) u_fpa_tag_update_useful_match ( + .unitary_in({tag_update_query_useful_match, 1'b1}), + .binary_out(tag_update_useful_zero_id) + ); + + logic [2:0] update_valid_id; - assign update_valid_id = provider_history_buffer[provider_history_matched_id].accepted_provider_id; + assign update_valid_id = provider_history_buffer[provider_history_matched_id].pred_provider_id; + + // Fill update structs always_comb begin : update_policy + // Default for (integer i = 0; i < TAG_COMPONENT_AMOUNT + 1; i++) begin tag_update_valid[i] = 1'b0; + tag_update_useful[i] = 1'b0; + tag_update_useful_inc[i] = 1'b0; end + + // Useful + tag_update_useful[update_valid_id-1] = provider_history_buffer[provider_history_matched_id].useful; + + // Valid if (branch_taken_i == provider_history_buffer[provider_history_matched_id].taken) begin tag_update_valid[update_valid_id] = 1'b1; + tag_update_useful_inc[update_valid_id-1] = 1'b1; end else begin // Wrong prediction tag_update_valid[update_valid_id] = 1'b1; - if (update_valid_id < TAG_COMPONENT_AMOUNT) begin + tag_update_useful_inc[update_valid_id-1] = 1'b0; + + // Allocate entry in longer history component + if (tag_update_useful_zero_id > update_valid_id) begin + tag_update_valid[tag_update_useful_zero_id] = 1'b1; + end else if (update_valid_id < TAG_COMPONENT_AMOUNT) begin tag_update_valid[update_valid_id+1] = 1'b1; end end end - - // Output logic, select the longest matched provider + // Select the longest match provider fpa #( .LINES(5) - ) prediction_select ( + ) pred_select ( .unitary_in({tag_hit, 1'b1}), - .binary_out(accept_prediction_id) + .binary_out(pred_prediction_id) + ); + // Select altpred + logic [TAG_COMPONENT_AMOUNT:0] altpred_pool; + always_comb begin + altpred_pool = {tag_hit, 1'b1}; + altpred_pool[pred_prediction_id] = 1'b0; + end + fpa #( + .LINES(5) + ) altpred_select ( + .unitary_in(altpred_pool), + .binary_out(altpred_prediction_id) ); - logic [4:0] taken = {tag_taken, base_taken}; - assign predict_branch_taken_o = taken[accept_prediction_id]; + // Output logic + logic [4:0] taken; + assign taken = {tag_taken, base_taken}; + assign predict_branch_taken_o = taken[pred_prediction_id]; // Counter generate genvar i; for (i = 0; i < 5; i = i + 1) begin always @(posedge clk) begin - perf_tag_hit_counter[i*32+31:i*32] <= perf_tag_hit_counter[i*32+31:i*32] + {31'b0,(i == accept_prediction_id)}; + perf_tag_hit_counter[i*32+31:i*32] <= perf_tag_hit_counter[i*32+31:i*32] + {31'b0,(i == pred_prediction_id)}; end end endgenerate diff --git a/src/vsrc/branch_predictor/tagged_predictor.sv b/src/vsrc/branch_predictor/tagged_predictor.sv index 4667e8d..1ca75cc 100644 --- a/src/vsrc/branch_predictor/tagged_predictor.sv +++ b/src/vsrc/branch_predictor/tagged_predictor.sv @@ -1,6 +1,6 @@ // Gshared predictor as base predictor `include "../defines.v" -`include "branch_predictor/defines.v" +`include "branch_predictor/defines.sv" `include "branch_predictor/utils/csr_hash.sv" `include "branch_predictor/utils/fpa.sv" @@ -23,7 +23,9 @@ module tagged_predictor #( // Update signals input logic update_valid, - input logic [PC_WIDTH:0] update_instr_info, + input logic [PC_WIDTH+2:0] update_instr_info, + // Useful counter for update policy + output logic [PHT_USEFUL_WIDTH-1:0] update_query_useful_o, output logic taken, output logic tag_hit @@ -33,11 +35,15 @@ module tagged_predictor #( logic rst_n; assign rst_n = ~rst; - // Unpack update instr info - logic [PC_WIDTH-1:0] update_pc; - assign update_pc = update_instr_info[PC_WIDTH:1]; - logic update_taken; - assign update_taken = update_instr_info[0]; + // Update Info + typedef struct packed { + logic [PC_WIDTH-1:0] pc; + logic taken; + logic inc; + logic useful; + } update_info_struct; + update_info_struct update_info; + assign update_info = update_instr_info; // PHT typedef struct packed { @@ -129,7 +135,7 @@ module tagged_predictor #( generate for (genvar i = 0; i < HASH_BUFFER_SIZE; i = i + 1) begin always @(*) begin - pc_match_table[i] = (hash_buffer[i].pc == update_pc); + pc_match_table[i] = (hash_buffer[i].pc == update_info.pc); end end endgenerate @@ -153,7 +159,11 @@ module tagged_predictor #( // Update logic =========================================================== - always_ff @(posedge clk or negedge rst_n) begin + // Give out the matched useful counter + assign update_query_useful_o = PHT[update_index].useful; + + // Main update ff + always_ff @(posedge clk or negedge rst_n) begin : update_ff if (!rst_n) begin // Reset all PHT, useful to 0, ctr to weak taken for (integer i = 0; i < 2 ** PHT_DEPTH_EXP2; i = i + 1) begin @@ -166,24 +176,36 @@ module tagged_predictor #( // Update PHT entry case (PHT[update_index].ctr) {PHT_CTR_WIDTH{1'b0}} : begin - PHT[update_index].ctr <= update_taken ? {{PHT_CTR_WIDTH-1{1'b0}},1'b1} : {PHT_CTR_WIDTH{1'b0}}; + PHT[update_index].ctr <= update_info.taken ? {{PHT_CTR_WIDTH-1{1'b0}},1'b1} : {PHT_CTR_WIDTH{1'b0}}; end {PHT_CTR_WIDTH{1'b1}} : begin - PHT[update_index].ctr <= update_taken ? {PHT_CTR_WIDTH{1'b1}}:{{PHT_CTR_WIDTH-1{1'b1}},1'b0}; + PHT[update_index].ctr <= update_info.taken ? {PHT_CTR_WIDTH{1'b1}}:{{PHT_CTR_WIDTH-1{1'b1}},1'b0}; end default: begin - PHT[update_index].ctr <= update_taken ? PHT[update_index].ctr +1 : PHT[update_index].ctr -1; + PHT[update_index].ctr <= update_info.taken ? PHT[update_index].ctr +1 : PHT[update_index].ctr -1; end endcase + // Update useful + if (update_info.useful) begin + case (PHT[update_index].useful) + {PHT_USEFUL_WIDTH{1'b1}} : begin + PHT[update_index].useful <= update_info.inc ? {PHT_USEFUL_WIDTH{1'b1}} : PHT[update_index].useful -1; + end + {PHT_USEFUL_WIDTH{1'b0}} : begin + PHT[update_index].useful <= update_info.inc ? PHT[update_index].useful +1 : {PHT_USEFUL_WIDTH{1'b0}}; + end + default: begin + PHT[update_index].useful <= update_info.inc ? PHT[update_index].useful +1 : PHT[update_index].useful -1; + end + endcase + end + if (PHT[update_index].tag != update_tag) // Miss tag begin PHT[update_index].tag <= update_tag; PHT[update_index].ctr <= {1'b1, {PHT_CTR_WIDTH - 1{1'b0}}}; // Reset CTR PHT[update_index].useful <= 0; // Reset useful counter - - - // PHT[update_index] <= {3'b100, update_tag}; end end end From c5f6a6762efce52bb86e965dbb609f7d0d4e8b4b Mon Sep 17 00:00:00 2001 From: Easton Man Date: Sat, 23 Apr 2022 16:54:58 +0800 Subject: [PATCH 034/114] feat: implement ping-pong avoid method --- src/vsrc/branch_predictor/tage_predictor.sv | 41 +++++++++++++++++---- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/src/vsrc/branch_predictor/tage_predictor.sv b/src/vsrc/branch_predictor/tage_predictor.sv index 71b44c7..0343d3f 100644 --- a/src/vsrc/branch_predictor/tage_predictor.sv +++ b/src/vsrc/branch_predictor/tage_predictor.sv @@ -161,7 +161,9 @@ module tage_predictor #( for (integer i = 1; i < 10; i++) begin if (i == provider_history_matched_id + 1) begin provider_history_buffer[i] <= 0; - end else provider_history_buffer[i] <= provider_history_buffer[i-1]; + end else begin + provider_history_buffer[i] <= provider_history_buffer[i-1]; + end end end @@ -190,12 +192,35 @@ PROVIDER_HISTORY_BUFFER_SIZE end end logic [$clog2(TAG_COMPONENT_AMOUNT+1)-1:0] tag_update_useful_zero_id; - fpa #( - .LINES(TAG_COMPONENT_AMOUNT + 1) - ) u_fpa_tag_update_useful_match ( - .unitary_in({tag_update_query_useful_match, 1'b1}), - .binary_out(tag_update_useful_zero_id) - ); + // Allocation policy, according to TAGE essay + always_comb begin + tag_update_useful_zero_id = 0; // default 0 + for (integer i = TAG_COMPONENT_AMOUNT - 1; i >= 0; i--) begin + if (tag_update_query_useful_match[i]) begin + // 1/2 probability when longer history tag want to be selected + if (tag_update_useful_pingpong_counter[i] != 2'b00) begin + tag_update_useful_zero_id = i + 1; + end + end + end + end + + // pingpong counter, is a random number array + bit [1:0] tag_update_useful_pingpong_counter[TAG_COMPONENT_AMOUNT]; + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + for (integer i = 0; i < TAG_COMPONENT_AMOUNT; i++) begin + tag_update_useful_pingpong_counter[i] <= 2'b11; + end + end else begin + // LSFR pseudo random number generator + tag_update_useful_pingpong_counter[TAG_COMPONENT_AMOUNT-1] <= tag_update_useful_pingpong_counter[0] ^ tag_update_useful_pingpong_counter[TAG_COMPONENT_AMOUNT-1]; + for (integer i = 0; i < TAG_COMPONENT_AMOUNT - 1; i++) begin + tag_update_useful_pingpong_counter[i] <= tag_update_useful_pingpong_counter[i+1]; + end + end + end + logic [2:0] update_valid_id; @@ -225,7 +250,7 @@ PROVIDER_HISTORY_BUFFER_SIZE if (tag_update_useful_zero_id > update_valid_id) begin tag_update_valid[tag_update_useful_zero_id] = 1'b1; end else if (update_valid_id < TAG_COMPONENT_AMOUNT) begin - tag_update_valid[update_valid_id+1] = 1'b1; + // tag_update_valid[update_valid_id+1] = 1'b1; end end end From 33c5576ff7f1b4da76ea313b08cda046c6b1e771 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Sat, 23 Apr 2022 21:40:14 +0800 Subject: [PATCH 035/114] feat: approaching mpki 6 - still unknown fxxking problem with update policy --- src/vsrc/branch_predictor/cbp3.cpp | 1 + src/vsrc/branch_predictor/tage_predictor.sv | 151 +++++++++++------- src/vsrc/branch_predictor/tagged_predictor.sv | 88 +++++----- src/vsrc/branch_predictor/testbench.cpp | 3 +- 4 files changed, 145 insertions(+), 98 deletions(-) diff --git a/src/vsrc/branch_predictor/cbp3.cpp b/src/vsrc/branch_predictor/cbp3.cpp index 927b174..f289305 100644 --- a/src/vsrc/branch_predictor/cbp3.cpp +++ b/src/vsrc/branch_predictor/cbp3.cpp @@ -122,6 +122,7 @@ int main(int argc, char const *argv[]) sopc->pc_i = entries[i].pc; sopc->branch_valid_i = delay_queue_valid.front(); + sopc->branch_conditional_i = delay_queue_taken.front().conditional; delay_queue_valid.pop(); sopc->branch_taken_i = delay_queue_taken.front().taken; sopc->branch_pc_i = delay_queue_taken.front().pc; diff --git a/src/vsrc/branch_predictor/tage_predictor.sv b/src/vsrc/branch_predictor/tage_predictor.sv index 0343d3f..17dfcdf 100644 --- a/src/vsrc/branch_predictor/tage_predictor.sv +++ b/src/vsrc/branch_predictor/tage_predictor.sv @@ -16,6 +16,7 @@ module tage_predictor #( // Update signals input logic branch_valid_i, + input logic branch_conditional_i, input logic branch_taken_i, input logic [`RegBus] branch_pc_i, input logic [`RegBus] branch_target_address_i, @@ -65,6 +66,7 @@ module tage_predictor #( // Base Predictor logic base_taken; + logic base_update_ctr; base_predictor #( .TABLE_DEPTH_EXP2(12), .CTR_WIDTH (2), @@ -73,51 +75,62 @@ module tage_predictor #( .clk (clk), .rst (rst), .pc_i (pc_i), - .update_valid (tag_update_valid[0]), + .update_valid (base_update_ctr), .update_instr_info({branch_pc_i, branch_taken_i}), .taken (base_taken) ); + localparam TAG_COMPONENT_AMOUNT = 4; // The provider id of the accepted prediction - logic [$clog2(TAG_COMPONENT_AMOUNT):0] pred_prediction_id; + logic [$clog2(TAG_COMPONENT_AMOUNT+1)-1:0] pred_prediction_id; // The provider id of the last hit provider - logic [$clog2(TAG_COMPONENT_AMOUNT):0] altpred_prediction_id; + logic [$clog2(TAG_COMPONENT_AMOUNT+1)-1:0] altpred_prediction_id; // For example, provider 2,4 hit, and provider 1,3 missed // then pred is 4, and altpred is 2 // Tagged Predictors - localparam TAG_COMPONENT_AMOUNT = 4; // History length of each tagged predictor - localparam integer provider_ghr_length[TAG_COMPONENT_AMOUNT] = '{5, 10, 40, 130}; + localparam integer provider_ghr_length[TAG_COMPONENT_AMOUNT] = '{5, 15, 44, 130}; // Query structs logic [TAG_COMPONENT_AMOUNT-1:0] tag_taken; logic [TAG_COMPONENT_AMOUNT-1:0] tag_hit; logic query_tag_useful; assign query_tag_useful = (taken[pred_prediction_id] != taken[altpred_prediction_id]); // Update structs - logic [TAG_COMPONENT_AMOUNT:0] tag_update_valid; // Including base predictor + logic [ TAG_COMPONENT_AMOUNT:0] update_ctr; + logic [TAG_COMPONENT_AMOUNT-1:0] tag_update_ctr; + assign tag_update_ctr = update_ctr[TAG_COMPONENT_AMOUNT:1]; + assign base_update_ctr = update_ctr[0]; logic [TAG_COMPONENT_AMOUNT-1:0] tag_update_useful; - logic [TAG_COMPONENT_AMOUNT-1:0] tag_update_useful_inc; + logic [TAG_COMPONENT_AMOUNT-1:0] tag_update_inc_useful; + logic [TAG_COMPONENT_AMOUNT-1:0] tag_update_realloc_entry; logic [TAGGED_PREDICTOR_USEFUL_WIDTH-1:0] tag_update_query_useful[TAG_COMPONENT_AMOUNT]; - generate genvar provider_id; for ( provider_id = 0; provider_id < TAG_COMPONENT_AMOUNT; provider_id = provider_id + 1 ) begin + // Update Info typedef struct packed { - logic [`RegWidth-1:0] pc; - logic taken; - logic inc; - logic useful; + logic [`RegBus] pc; + + // 0: decrease, invalid, decrease, invalid, no reallocate + // 1: increase, valid, increase, valid, reallocate + logic update_ctr; + logic inc_ctr; + logic update_useful; + logic inc_useful; + logic realloc_entry; } update_info_struct; update_info_struct update_info; assign update_info.pc = branch_pc_i; - assign update_info.taken = branch_taken_i; - assign update_info.inc = tag_update_useful_inc[provider_id]; - assign update_info.useful = tag_update_useful[provider_id]; + assign update_info.update_ctr = tag_update_ctr[provider_id]; + assign update_info.inc_ctr = branch_taken_i; + assign update_info.update_useful = tag_update_useful[provider_id]; + assign update_info.inc_useful = tag_update_inc_useful[provider_id]; + assign update_info.realloc_entry = tag_update_realloc_entry[provider_id]; tagged_predictor #( .INPUT_GHR_LENGTH(provider_ghr_length[provider_id]), @@ -129,11 +142,10 @@ module tage_predictor #( .rst(rst), .global_history_i(GHR[provider_ghr_length[provider_id]:0]), .pc_i(pc_i), - .update_valid(tag_update_valid[provider_id+1]), - .update_instr_info(update_info), + .update_info_i(update_info), .update_query_useful_o(tag_update_query_useful[provider_id]), - .taken(tag_taken[provider_id]), - .tag_hit(tag_hit[provider_id]) + .taken_o(tag_taken[provider_id]), + .tag_hit_o(tag_hit[provider_id]) ); end endgenerate @@ -158,16 +170,18 @@ module tage_predictor #( pc_i, pred_prediction_id, query_tag_useful, predict_branch_taken_o }; always_ff @(posedge clk) begin : shift - for (integer i = 1; i < 10; i++) begin + for (integer i = 1; i < PROVIDER_HISTORY_BUFFER_SIZE; i++) begin + /* verilator lint_off WIDTH */ if (i == provider_history_matched_id + 1) begin provider_history_buffer[i] <= 0; end else begin provider_history_buffer[i] <= provider_history_buffer[i-1]; end + /* verilator lint_on WIDTH */ end end - // Generate provider histry entry that matched update pc siganl + // Generate provider histry entry that matched update pc signal bit [PROVIDER_HISTORY_BUFFER_SIZE-1:0] provider_history_match; always_comb begin : provider_history_search // match pc with update signals for (integer i = 0; i < PROVIDER_HISTORY_BUFFER_SIZE; i++) begin @@ -175,9 +189,8 @@ module tage_predictor #( end end - logic [$clog2( -PROVIDER_HISTORY_BUFFER_SIZE -)-1:0] provider_history_matched_id; // The entry id of the matched pc + // The entry id of the matched pc + logic [$clog2(PROVIDER_HISTORY_BUFFER_SIZE)-1:0] provider_history_matched_id; fpa #( .LINES(PROVIDER_HISTORY_BUFFER_SIZE) ) u_fpa_provider_history_matched_id ( @@ -185,10 +198,11 @@ PROVIDER_HISTORY_BUFFER_SIZE .binary_out(provider_history_matched_id) ); + // Get the id of the desired allocate provider logic [TAG_COMPONENT_AMOUNT-1:0] tag_update_query_useful_match; always_comb begin for (integer i = 0; i < TAG_COMPONENT_AMOUNT; i++) begin - tag_update_query_useful_match[i] = tag_update_query_useful[i] == 0; + tag_update_query_useful_match[i] = (tag_update_query_useful[i] == 0); end end logic [$clog2(TAG_COMPONENT_AMOUNT+1)-1:0] tag_update_useful_zero_id; @@ -199,58 +213,83 @@ PROVIDER_HISTORY_BUFFER_SIZE if (tag_update_query_useful_match[i]) begin // 1/2 probability when longer history tag want to be selected if (tag_update_useful_pingpong_counter[i] != 2'b00) begin + /* verilator lint_off WIDTH */ tag_update_useful_zero_id = i + 1; + /* verilator lint_on WIDTH */ end end end end // pingpong counter, is a random number array + bit [31:0] LSFR; + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + LSFR <= 32'hffffffff; + end else begin + // LSFR pseudo random number generator + LSFR <= {LSFR[30:0], LSFR[29] ^ LSFR[5] ^ LSFR[3] ^ LSFR[0]}; + end + end bit [1:0] tag_update_useful_pingpong_counter[TAG_COMPONENT_AMOUNT]; always_ff @(posedge clk or negedge rst_n) begin if (!rst_n) begin for (integer i = 0; i < TAG_COMPONENT_AMOUNT; i++) begin - tag_update_useful_pingpong_counter[i] <= 2'b11; + tag_update_useful_pingpong_counter[i] <= 2'b00; end end else begin - // LSFR pseudo random number generator - tag_update_useful_pingpong_counter[TAG_COMPONENT_AMOUNT-1] <= tag_update_useful_pingpong_counter[0] ^ tag_update_useful_pingpong_counter[TAG_COMPONENT_AMOUNT-1]; - for (integer i = 0; i < TAG_COMPONENT_AMOUNT - 1; i++) begin - tag_update_useful_pingpong_counter[i] <= tag_update_useful_pingpong_counter[i+1]; + tag_update_useful_pingpong_counter[0] <= LSFR[1:0]; + for (integer i = 1; i < TAG_COMPONENT_AMOUNT; i++) begin + tag_update_useful_pingpong_counter[i] <= tag_update_useful_pingpong_counter[i-1]; end end end - logic [2:0] update_valid_id; - assign update_valid_id = provider_history_buffer[provider_history_matched_id].pred_provider_id; + logic [$clog2(TAG_COMPONENT_AMOUNT+1)-1:0] update_provider_id; // including base predictor + assign update_provider_id = provider_history_buffer[provider_history_matched_id].pred_provider_id; // Fill update structs - always_comb begin : update_policy - // Default + // update_ctr + always_comb begin : update_ctr_policy + // update_ctr, default 0 for (integer i = 0; i < TAG_COMPONENT_AMOUNT + 1; i++) begin - tag_update_valid[i] = 1'b0; - tag_update_useful[i] = 1'b0; - tag_update_useful_inc[i] = 1'b0; + update_ctr[i] = 1'b0; + end + if (branch_conditional_i) begin // Only update on conditional branches + update_ctr[update_provider_id] = 1'b1; // One hot end + end - // Useful - tag_update_useful[update_valid_id-1] = provider_history_buffer[provider_history_matched_id].useful; - - // Valid - if (branch_taken_i == provider_history_buffer[provider_history_matched_id].taken) begin - tag_update_valid[update_valid_id] = 1'b1; - tag_update_useful_inc[update_valid_id-1] = 1'b1; - end else begin // Wrong prediction - tag_update_valid[update_valid_id] = 1'b1; - tag_update_useful_inc[update_valid_id-1] = 1'b0; - - // Allocate entry in longer history component - if (tag_update_useful_zero_id > update_valid_id) begin - tag_update_valid[tag_update_useful_zero_id] = 1'b1; - end else if (update_valid_id < TAG_COMPONENT_AMOUNT) begin - // tag_update_valid[update_valid_id+1] = 1'b1; + // tag_update_useful & tag_update_inc_useful & tag_update_realloc_entry + always_comb begin : tag_update_policy + // Default 0 + for (integer i = 0; i < TAG_COMPONENT_AMOUNT; i++) begin + tag_update_useful[i] = 1'b0; + tag_update_inc_useful[i] = 1'b0; + tag_update_realloc_entry[i] = 1'b0; + end + if (branch_conditional_i) begin // Only update on conditional branches + // If useful, update useful bits + tag_update_useful[update_provider_id-1] = provider_history_buffer[provider_history_matched_id].useful; + // Increase if correct, else decrease + tag_update_inc_useful[update_provider_id-1] = (branch_taken_i == provider_history_buffer[provider_history_matched_id].taken); + + // Allocate new entry if failed + if (branch_taken_i != provider_history_buffer[provider_history_matched_id].taken) begin + // Allocate entry in longer history component + if (tag_update_useful_zero_id > update_provider_id) begin // Have found a slot to allocate + tag_update_realloc_entry[tag_update_useful_zero_id-1] = 1'b1; + end else begin // No slot to allocate, decrease all useful bits of longer history components + /* verilator lint_off WIDTH */ + for (integer i = update_provider_id; i < TAG_COMPONENT_AMOUNT; i++) begin + // tag_update_realloc_entry[i] = 1'b1; + tag_update_useful[i] = 1'b1; + tag_update_inc_useful[i] = 1'b0; + end + /* verilator lint_on WIDTH */ + end end end end @@ -266,7 +305,9 @@ PROVIDER_HISTORY_BUFFER_SIZE logic [TAG_COMPONENT_AMOUNT:0] altpred_pool; always_comb begin altpred_pool = {tag_hit, 1'b1}; - altpred_pool[pred_prediction_id] = 1'b0; + if (pred_prediction_id != 0) begin + altpred_pool[pred_prediction_id] = 1'b0; + end end fpa #( .LINES(5) @@ -276,7 +317,7 @@ PROVIDER_HISTORY_BUFFER_SIZE ); // Output logic - logic [4:0] taken; + logic [TAG_COMPONENT_AMOUNT:0] taken; assign taken = {tag_taken, base_taken}; assign predict_branch_taken_o = taken[pred_prediction_id]; diff --git a/src/vsrc/branch_predictor/tagged_predictor.sv b/src/vsrc/branch_predictor/tagged_predictor.sv index 1ca75cc..eca69bd 100644 --- a/src/vsrc/branch_predictor/tagged_predictor.sv +++ b/src/vsrc/branch_predictor/tagged_predictor.sv @@ -22,13 +22,13 @@ module tagged_predictor #( input logic [PC_WIDTH-1:0] pc_i, // Update signals - input logic update_valid, - input logic [PC_WIDTH+2:0] update_instr_info, + input logic [PC_WIDTH+4:0] update_info_i, + // Useful counter for update policy output logic [PHT_USEFUL_WIDTH-1:0] update_query_useful_o, - output logic taken, - output logic tag_hit + output logic taken_o, + output logic tag_hit_o ); // Reset @@ -38,19 +38,23 @@ module tagged_predictor #( // Update Info typedef struct packed { logic [PC_WIDTH-1:0] pc; - logic taken; - logic inc; - logic useful; + + // 0: invalid, decrease, invalid, decrease, no reallocate + // 1: valid, increase, valid, increase, reallocate + logic update_ctr; + logic inc_ctr; + logic update_useful; + logic inc_useful; + logic realloc_entry; } update_info_struct; update_info_struct update_info; - assign update_info = update_instr_info; + assign update_info = update_info_i; // PHT typedef struct packed { bit [PHT_CTR_WIDTH-1:0] ctr; bit [PHT_TAG_WIDTH-1:0] tag; bit [PHT_USEFUL_WIDTH-1:0] useful; - } pht_entry; pht_entry PHT[2**PHT_DEPTH_EXP2]; @@ -74,8 +78,8 @@ module tagged_predictor #( // Tag // Generate another hash different from above, as described in PPM-Liked essay - logic [PHT_TAG_WIDTH-1:0] pc_hash_csr1; - logic [PHT_TAG_WIDTH-2:0] pc_hash_csr2; + logic [PHT_TAG_WIDTH-1:0] tag_hash_csr1; + logic [PHT_TAG_WIDTH-2:0] tag_hash_csr2; csr_hash #( .INPUT_LENGTH (INPUT_GHR_LENGTH + 1), .OUTPUT_LENGTH(PHT_TAG_WIDTH) @@ -83,7 +87,7 @@ module tagged_predictor #( .clk (clk), .rst (rst), .data_i(global_history_i), - .hash_o(pc_hash_csr1) + .hash_o(tag_hash_csr1) ); csr_hash #( .INPUT_LENGTH (INPUT_GHR_LENGTH + 1), @@ -92,11 +96,11 @@ module tagged_predictor #( .clk (clk), .rst (rst), .data_i(global_history_i), - .hash_o(pc_hash_csr2) + .hash_o(tag_hash_csr2) ); logic [PHT_TAG_WIDTH-1:0] query_tag; - assign query_tag = pc_i[PHT_TAG_WIDTH-1:0] ^ pc_hash_csr1 ^ {pc_hash_csr2, 1'b0}; + assign query_tag = pc_i[PHT_TAG_WIDTH-1:0] ^ tag_hash_csr1 ^ {tag_hash_csr2, 1'b0}; @@ -106,8 +110,8 @@ module tagged_predictor #( assign query_result = PHT[query_index]; // Assign Output - assign taken = (query_result.ctr[PHT_CTR_WIDTH-1] == 1'b1); - assign tag_hit = (query_tag == query_result.tag); + assign taken_o = (query_result.ctr[PHT_CTR_WIDTH-1] == 1'b1); + assign tag_hit_o = (query_tag == query_result.tag); // Use a buffer to hold the query_index and pc @@ -172,41 +176,41 @@ module tagged_predictor #( PHT[i].useful = 0; end end else begin - if (update_valid & update_match_valid) begin - // Update PHT entry + // Update CTR bits + if (update_info.update_ctr & update_match_valid) begin case (PHT[update_index].ctr) {PHT_CTR_WIDTH{1'b0}} : begin - PHT[update_index].ctr <= update_info.taken ? {{PHT_CTR_WIDTH-1{1'b0}},1'b1} : {PHT_CTR_WIDTH{1'b0}}; + PHT[update_index].ctr <= update_info.inc_ctr ? {{PHT_CTR_WIDTH-1{1'b0}},1'b1} : {PHT_CTR_WIDTH{1'b0}}; end {PHT_CTR_WIDTH{1'b1}} : begin - PHT[update_index].ctr <= update_info.taken ? {PHT_CTR_WIDTH{1'b1}}:{{PHT_CTR_WIDTH-1{1'b1}},1'b0}; + PHT[update_index].ctr <= update_info.inc_ctr ? {PHT_CTR_WIDTH{1'b1}}:{{PHT_CTR_WIDTH-1{1'b1}},1'b0}; end default: begin - PHT[update_index].ctr <= update_info.taken ? PHT[update_index].ctr +1 : PHT[update_index].ctr -1; + PHT[update_index].ctr <= update_info.inc_ctr ? PHT[update_index].ctr + 1 : PHT[update_index].ctr - 1; end endcase + end + + // Update useful bits + if (update_info.update_useful & update_match_valid) begin + case (PHT[update_index].useful) + {PHT_USEFUL_WIDTH{1'b1}} : begin + PHT[update_index].useful <= update_info.inc_useful ? {PHT_USEFUL_WIDTH{1'b1}} : PHT[update_index].useful - 1; + end + {PHT_USEFUL_WIDTH{1'b0}} : begin + PHT[update_index].useful <= update_info.inc_useful ? PHT[update_index].useful + 1 : {PHT_USEFUL_WIDTH{1'b0}}; + end + default: begin + PHT[update_index].useful <= update_info.inc_useful ? PHT[update_index].useful + 1 : PHT[update_index].useful - 1; + end + endcase + end - // Update useful - if (update_info.useful) begin - case (PHT[update_index].useful) - {PHT_USEFUL_WIDTH{1'b1}} : begin - PHT[update_index].useful <= update_info.inc ? {PHT_USEFUL_WIDTH{1'b1}} : PHT[update_index].useful -1; - end - {PHT_USEFUL_WIDTH{1'b0}} : begin - PHT[update_index].useful <= update_info.inc ? PHT[update_index].useful +1 : {PHT_USEFUL_WIDTH{1'b0}}; - end - default: begin - PHT[update_index].useful <= update_info.inc ? PHT[update_index].useful +1 : PHT[update_index].useful -1; - end - endcase - end - - if (PHT[update_index].tag != update_tag) // Miss tag - begin - PHT[update_index].tag <= update_tag; - PHT[update_index].ctr <= {1'b1, {PHT_CTR_WIDTH - 1{1'b0}}}; // Reset CTR - PHT[update_index].useful <= 0; // Reset useful counter - end + // Alocate new entry + if (update_info.realloc_entry & update_match_valid & PHT[update_index].tag != update_tag) begin + PHT[update_index].tag <= update_tag; + PHT[update_index].ctr <= {1'b1, {PHT_CTR_WIDTH - 1{1'b0}}}; // Reset CTR + PHT[update_index].useful <= 0; // Reset useful counter end end end diff --git a/src/vsrc/branch_predictor/testbench.cpp b/src/vsrc/branch_predictor/testbench.cpp index 3658bf5..891d577 100644 --- a/src/vsrc/branch_predictor/testbench.cpp +++ b/src/vsrc/branch_predictor/testbench.cpp @@ -12,7 +12,7 @@ // Work around double sc_time_stamp() { return 0; } -static std::string test_filename = "data/gcc-8M.txt"; +static std::string test_filename = "data/gcc-10K.txt"; struct instruction_entry { @@ -106,6 +106,7 @@ int main(int argc, char const *argv[]) sopc->pc_i = entries[i].pc; sopc->branch_valid_i = delay_queue_valid.front(); + sopc->branch_conditional_i = true; delay_queue_valid.pop(); sopc->branch_taken_i = delay_queue_taken.front().taken; sopc->branch_pc_i = delay_queue_taken.front().pc; From 9725f6c2b1cf37278c5e0373f0616c7b7b55d213 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Sat, 23 Apr 2022 23:10:54 +0800 Subject: [PATCH 036/114] feat: fix tagged-predictor match table bug --- src/vsrc/branch_predictor/Makefile | 7 ++++++- src/vsrc/branch_predictor/tagged_predictor.sv | 9 +++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/vsrc/branch_predictor/Makefile b/src/vsrc/branch_predictor/Makefile index fa338cb..90cb339 100644 --- a/src/vsrc/branch_predictor/Makefile +++ b/src/vsrc/branch_predictor/Makefile @@ -1,5 +1,10 @@ -cbp3: *.sv +4: *.sv + verilator -O3 --trace tage_predictor.sv --exe cbp3.cpp --cc -I../ | true # Ignore errors + @make -C obj_dir -f Vtage_predictor.mk 2>&1 >/dev/null + ./obj_dir/Vtage_predictor 4 + +cbp: *.sv verilator -O3 tage_predictor.sv --exe cbp3.cpp --cc -I../ | true # Ignore errors @make -C obj_dir -f Vtage_predictor.mk 2>&1 >/dev/null trace_id=0; while [[ $$trace_id -lt 20 ]]; do \ diff --git a/src/vsrc/branch_predictor/tagged_predictor.sv b/src/vsrc/branch_predictor/tagged_predictor.sv index eca69bd..61b76fc 100644 --- a/src/vsrc/branch_predictor/tagged_predictor.sv +++ b/src/vsrc/branch_predictor/tagged_predictor.sv @@ -9,7 +9,7 @@ module tagged_predictor #( parameter INPUT_GHR_LENGTH = 4, parameter PC_WIDTH = 32, parameter PHT_DEPTH_EXP2 = 10, - parameter PHT_TAG_WIDTH = 8, + parameter PHT_TAG_WIDTH = 9, parameter PHT_CTR_WIDTH = 3, parameter PHT_USEFUL_WIDTH = 2, parameter HASH_BUFFER_SIZE = 10 @@ -130,7 +130,12 @@ module tagged_predictor #( generate for (genvar i = 1; i < HASH_BUFFER_SIZE; i = i + 1) begin always @(posedge clk) begin - hash_buffer[i] <= hash_buffer[i-1]; + if (i == update_match_index + 1) begin + hash_buffer[i].valid <= 0; + hash_buffer[i].pc <= 0; + end else begin + hash_buffer[i] <= hash_buffer[i-1]; + end end end endgenerate From cf76019e81746ddf9e46e4b230d07825f058ce40 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Fri, 29 Apr 2022 16:04:16 +0800 Subject: [PATCH 037/114] feat: fit PHT table into 36K BRAM block --- src/vsrc/branch_predictor/Makefile | 5 -- src/vsrc/branch_predictor/README.md | 76 ++++++++----------- src/vsrc/branch_predictor/cbp3.cpp | 2 +- src/vsrc/branch_predictor/tage_predictor.sv | 19 ++--- src/vsrc/branch_predictor/tagged_predictor.sv | 2 +- 5 files changed, 43 insertions(+), 61 deletions(-) diff --git a/src/vsrc/branch_predictor/Makefile b/src/vsrc/branch_predictor/Makefile index 90cb339..3b03120 100644 --- a/src/vsrc/branch_predictor/Makefile +++ b/src/vsrc/branch_predictor/Makefile @@ -1,9 +1,4 @@ -4: *.sv - verilator -O3 --trace tage_predictor.sv --exe cbp3.cpp --cc -I../ | true # Ignore errors - @make -C obj_dir -f Vtage_predictor.mk 2>&1 >/dev/null - ./obj_dir/Vtage_predictor 4 - cbp: *.sv verilator -O3 tage_predictor.sv --exe cbp3.cpp --cc -I../ | true # Ignore errors @make -C obj_dir -f Vtage_predictor.mk 2>&1 >/dev/null diff --git a/src/vsrc/branch_predictor/README.md b/src/vsrc/branch_predictor/README.md index 1df4bd6..692b653 100644 --- a/src/vsrc/branch_predictor/README.md +++ b/src/vsrc/branch_predictor/README.md @@ -1,52 +1,38 @@ # Branch Predictor Unit -## Reference +## Final MPKI -### MPKI +Using + +- 16K-Entry Base Predictor + +- 2K-Entry Tagged Predictor + +- 3-bits CTR, 3bits Useful, 13-bits Tag + +each of the table is less then 36K, in order to fit in a BRAM of xc7a FPGA ``` - MPKI: 3.787425 - MPKI: 1.614177 - MPKI: 13.759027 - MPKI: 0.297560 - MPKI: 0.701255 - MPKI: 14.145463 - MPKI: 13.420007 - MPKI: 26.892054 - MPKI: 5.227905 - MPKI: 39.794147 - MPKI: 11.073499 - MPKI: 12.654080 - MPKI: 6.380413 - MPKI: 2.989018 - MPKI: 9.888374 - MPKI: 18.752298 - MPKI: 19.088045 - MPKI: 10.448743 - MPKI: 16.002567 - MPKI: 17.744772 +MPKI: 1.65644 +MPKI: 0.887665 +MPKI: 0.0851187 +MPKI: 0.105119 +MPKI: 0.0329153 +MPKI: 1.02339 +MPKI: 5.97177 +MPKI: 8.59235 +MPKI: 1.10197 +MPKI: 0.326644 +MPKI: 7.55845 +MPKI: 9.7676 +MPKI: 0.43156 +MPKI: 1.42641 +MPKI: 4.27732 +MPKI: 1.33129 +MPKI: 1.33265 +MPKI: 3.55453 +MPKI: 2.52962 +MPKI: 2.19501 +Avg: 2.70 ``` -### Misprediction Rate -``` - Misprediction Rate: 0.050472 - Misprediction Rate: 0.026560 - Misprediction Rate: 0.262407 - Misprediction Rate: 0.009799 - Misprediction Rate: 0.008541 - Misprediction Rate: 0.099716 - Misprediction Rate: 0.138109 - Misprediction Rate: 0.210334 - Misprediction Rate: 0.074508 - Misprediction Rate: 0.312604 - Misprediction Rate: 0.146535 - Misprediction Rate: 0.097983 - Misprediction Rate: 0.062432 - Misprediction Rate: 0.018088 - Misprediction Rate: 0.113774 - Misprediction Rate: 0.151117 - Misprediction Rate: 0.159172 - Misprediction Rate: 0.080861 - Misprediction Rate: 0.110632 - Misprediction Rate: 0.121956 -``` \ No newline at end of file diff --git a/src/vsrc/branch_predictor/cbp3.cpp b/src/vsrc/branch_predictor/cbp3.cpp index f289305..e909687 100644 --- a/src/vsrc/branch_predictor/cbp3.cpp +++ b/src/vsrc/branch_predictor/cbp3.cpp @@ -7,7 +7,7 @@ #include #include -#define BRANCH_LATENCY (3) +#define BRANCH_LATENCY (1) // Work around double sc_time_stamp() { return 0; } diff --git a/src/vsrc/branch_predictor/tage_predictor.sv b/src/vsrc/branch_predictor/tage_predictor.sv index 17dfcdf..0b382c7 100644 --- a/src/vsrc/branch_predictor/tage_predictor.sv +++ b/src/vsrc/branch_predictor/tage_predictor.sv @@ -8,7 +8,7 @@ module tage_predictor #( parameter PROVIDER_HISTORY_BUFFER_SIZE = 10, - parameter TAGGED_PREDICTOR_USEFUL_WIDTH = 2 + parameter TAGGED_PREDICTOR_USEFUL_WIDTH = 3 ) ( input logic clk, input logic rst, @@ -68,7 +68,7 @@ module tage_predictor #( logic base_taken; logic base_update_ctr; base_predictor #( - .TABLE_DEPTH_EXP2(12), + .TABLE_DEPTH_EXP2(14), .CTR_WIDTH (2), .PC_WIDTH (`RegWidth) ) u_base_predictor ( @@ -134,7 +134,7 @@ module tage_predictor #( tagged_predictor #( .INPUT_GHR_LENGTH(provider_ghr_length[provider_id]), - .PHT_DEPTH_EXP2 (10), + .PHT_DEPTH_EXP2 (11), .PHT_USEFUL_WIDTH(TAGGED_PREDICTOR_USEFUL_WIDTH), .PC_WIDTH (`RegWidth) ) tag_predictor ( @@ -225,10 +225,10 @@ module tage_predictor #( bit [31:0] LSFR; always_ff @(posedge clk or negedge rst_n) begin if (!rst_n) begin - LSFR <= 32'hffffffff; + LSFR <= 32'h00000000; end else begin // LSFR pseudo random number generator - LSFR <= {LSFR[30:0], LSFR[29] ^ LSFR[5] ^ LSFR[3] ^ LSFR[0]}; + LSFR <= {LSFR[30:0], LSFR[31] + LSFR[21] + LSFR[1] + LSFR[0] + 1'b1}; end end bit [1:0] tag_update_useful_pingpong_counter[TAG_COMPONENT_AMOUNT]; @@ -283,10 +283,11 @@ module tage_predictor #( tag_update_realloc_entry[tag_update_useful_zero_id-1] = 1'b1; end else begin // No slot to allocate, decrease all useful bits of longer history components /* verilator lint_off WIDTH */ - for (integer i = update_provider_id; i < TAG_COMPONENT_AMOUNT; i++) begin - // tag_update_realloc_entry[i] = 1'b1; - tag_update_useful[i] = 1'b1; - tag_update_inc_useful[i] = 1'b0; + for (integer i = 0; i < TAG_COMPONENT_AMOUNT; i++) begin + if (i >= update_provider_id - 1) begin + tag_update_useful[i] = 1'b1; + tag_update_inc_useful[i] = 1'b0; + end end /* verilator lint_on WIDTH */ end diff --git a/src/vsrc/branch_predictor/tagged_predictor.sv b/src/vsrc/branch_predictor/tagged_predictor.sv index 61b76fc..9a40ca1 100644 --- a/src/vsrc/branch_predictor/tagged_predictor.sv +++ b/src/vsrc/branch_predictor/tagged_predictor.sv @@ -9,7 +9,7 @@ module tagged_predictor #( parameter INPUT_GHR_LENGTH = 4, parameter PC_WIDTH = 32, parameter PHT_DEPTH_EXP2 = 10, - parameter PHT_TAG_WIDTH = 9, + parameter PHT_TAG_WIDTH = 12, parameter PHT_CTR_WIDTH = 3, parameter PHT_USEFUL_WIDTH = 2, parameter HASH_BUFFER_SIZE = 10 From 54a11d3e186cb3946cee2e15a8891b14891ca54a Mon Sep 17 00:00:00 2001 From: Rookie <74707760+Rookie-Cai-niao@users.noreply.github.com> Date: Mon, 2 May 2022 11:37:36 +0800 Subject: [PATCH 038/114] add CSR and tlb without test --- .gitignore | 1 + src/SimTop.v | 70 +-- src/vsrc/LLbit_reg.v | 5 +- src/vsrc/cpu_top.v | 680 ++++++++++++++++++++++++- src/vsrc/cs_reg.v | 510 ++++++++++++++++++- src/vsrc/csr_defines.v | 35 +- src/vsrc/ctrl.v | 11 +- src/vsrc/if_buffer.v | 44 -- src/vsrc/pc_reg.v | 108 +++- src/vsrc/pipeline/1_fetch/if_buffer.v | 21 +- src/vsrc/pipeline/1_fetch/if_id.v | 19 +- src/vsrc/pipeline/2_decode/id.v | 79 ++- src/vsrc/pipeline/2_decode/id_ex.v | 36 +- src/vsrc/pipeline/3_execution/ex.v | 24 +- src/vsrc/pipeline/3_execution/ex_mem.v | 33 +- src/vsrc/pipeline/4_mem/mem.v | 85 +++- src/vsrc/pipeline/4_mem/mem_wb.v | 93 +++- src/vsrc/tlb.v | 252 ++++++++- src/vsrc/tlb_entry.v | 402 +++++++++++---- 19 files changed, 2242 insertions(+), 266 deletions(-) delete mode 100644 src/vsrc/if_buffer.v diff --git a/.gitignore b/.gitignore index 07cf18a..216d913 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,7 @@ src/emu-compile src/emu src/lock-emu src/time.log +src/.history la32-nemu-interpreter-so test/*.bin build/ \ No newline at end of file diff --git a/src/SimTop.v b/src/SimTop.v index 6d5ca80..cd00b11 100644 --- a/src/SimTop.v +++ b/src/SimTop.v @@ -1,3 +1,5 @@ +`timescale 1ns/1ns + `include "vsrc/defines.v" `include "ram.v" @@ -55,6 +57,7 @@ module SimTop( wire [`RegBus] debug_commit_reg_wdata_o_2; wire[1023:0] debug_reg; wire Instram_branch_flag; + wire [831:0] csr_diff; cpu_top u_cpu_top( .clk(clock), .rst(reset), @@ -98,6 +101,7 @@ module SimTop( .debug_commit_reg_waddr_2(debug_commit_reg_waddr_o_2 ), .debug_commit_reg_wdata_2(debug_commit_reg_wdata_o_2 ), .debug_reg(debug_reg ), + .csr_diff(csr_diff), .Instram_branch_flag(Instram_branch_flag) ); @@ -129,41 +133,41 @@ module SimTop( `endif - //data_ram u_data_ram( - // .clk(clock), - // .ce_1(dram_ce_1), - // .we_1(dram_we_1), - // .pc_1(dram_pc_1), - // .addr_1(dram_addr_1), - // .sel_1(dram_sel_1), - // .data_i_1(dram_data_i_1), - // .data_o_1(dram_data_o_1), - // .ce_2(dram_ce_2), - // .we_2(dram_we_2), - // .pc_2(dram_pc_2), - // .addr_2(dram_addr_2), - // .sel_2(dram_sel_2), - // .data_i_2(dram_data_i_2), - // .data_o_2(dram_data_o_2) - // ); + data_ram u_data_ram( + .clk(clock), + .ce_1(dram_ce_1), + .we_1(dram_we_1), + .pc_1(dram_pc_1), + .addr_1(dram_addr_1), + .sel_1(dram_sel_1), + .data_i_1(dram_data_i_1), + .data_o_1(dram_data_o_1), + .ce_2(dram_ce_2), + .we_2(dram_we_2), + .pc_2(dram_pc_2), + .addr_2(dram_addr_2), + .sel_2(dram_sel_2), + .data_i_2(dram_data_i_2), + .data_o_2(dram_data_o_2) + ); - dual_data_rom u_dual_data_rom( - .clka(clock), - .rsta(reset), - .wea(dram_sel_1), - .addra(dram_addr_1), - .dina(dram_data_i_1), - .douta(dram_data_o_1), - .clkb(clock), - .rstb(reset), - .enb(1'b1), - .web(dram_sel_2), - .addrb(dram_addr_2), - .dinb(dram_data_i_2), - .doutb(dram_data_o_2) - - ); + //dual_data_rom u_dual_data_rom( + // .clka(clock), + // .rsta(reset), + // .wea(dram_sel_1), + // .addra(dram_addr_1), + // .dina(dram_data_i_1), + // .douta(dram_data_o_1), + // .clkb(clock), + // .rstb(reset), + // .enb(1'b1), + // .web(dram_sel_2), + // .addrb(dram_addr_2), + // .dinb(dram_data_i_2), + // .doutb(dram_data_o_2) + + //); `ifdef DIFFTEST diff --git a/src/vsrc/LLbit_reg.v b/src/vsrc/LLbit_reg.v index d4ef254..79c554c 100644 --- a/src/vsrc/LLbit_reg.v +++ b/src/vsrc/LLbit_reg.v @@ -5,7 +5,8 @@ module LLbit_reg( input wire flush, - input wire LLbit_i, + input wire LLbit_i_1, + input wire LLbit_i_2, input wire we, output reg LLbit_o @@ -18,7 +19,7 @@ module LLbit_reg( else if(flush) LLbit_o<=0; else if(we) - LLbit_o<=LLbit_i; + LLbit_o<=LLbit_i_1 | LLbit_i_2; else LLbit_o<=LLbit_o; end diff --git a/src/vsrc/cpu_top.v b/src/vsrc/cpu_top.v index 08a344d..2ef084b 100644 --- a/src/vsrc/cpu_top.v +++ b/src/vsrc/cpu_top.v @@ -1,7 +1,11 @@ `include "defines.v" `include "pc_reg.v" -`include "if_buffer.v" `include "regfile.v" +`include "csr_defines.v" +`include "cs_reg.v" +`include "tlb.v" +`include "tlb_entry.v" +`include "pipeline/1_fetch/if_buffer.v" `include "pipeline/1_fetch/if_id.v" `include "pipeline/2_decode/id.v" `include "pipeline/2_decode/id_ex.v" @@ -53,6 +57,7 @@ module cpu_top ( output wire[`RegAddrBus] debug_commit_reg_waddr_2, output wire[`RegBus] debug_commit_reg_wdata_2, output wire[1023:0] debug_reg, + output wire[831:0] csr_diff, output wire Instram_branch_flag ); @@ -69,7 +74,7 @@ module cpu_top ( wire branch_flag_1; wire branch_flag_2; - assign Instram_branch_flag=branch_flag; + assign Instram_branch_flag=branch_flag_1 | branch_flag_2; wire[`RegBus] branch_target_address_1; wire[`RegBus] branch_target_address_2; wire[`RegBus] link_addr; @@ -78,6 +83,120 @@ module cpu_top ( wire[6:0] stall1; // [pc_reg,if_buffer_1, if_id, id_ex, ex_mem, mem_wb, ctrl] wire[6:0] stall2; + + //tlb + wire inst_addr_trans_en; + wire data_addr_trans_en; + wire fetch_en; + wire [31:0] inst_vaddr; + wire inst_dmw0_en; + wire inst_dmw1_en; + wire [7:0] inst_index; + wire [19:0] inst_tag; + wire [3:0] inst_offset; + wire inst_tlb_found; + wire inst_tlb_v; + wire inst_tlb_d; + wire [1:0] inst_tlb_mat; + wire [1:0] inst_tlb_plv; + wire data_fetch; + wire [31:0] data_vaddr; + wire data_dmw0_en; + wire data_dmw1_en; + wire cacop_op_mode_di; + wire [7:0] data_index; + wire [19:0] data_tag; + wire [3:0] data_offset; + wire data_tlb_found; + wire [4:0] data_tlb_index; + wire data_tlb_v; + wire data_tlb_d; + wire [1:0] data_tlb_mat; + wire [1:0] data_tlb_plv; + wire tlbfill_en; + wire tlbwr_en; + wire [4:0] rand_index; + wire [31:0] tlbw_tlbehi; + wire [31:0] tlbw_tlbelo0; + wire [31:0] tlbw_tlbelo1; + wire [31:0] tlbw_r_tlbidx; + wire [5:0] tlbw_ecode; + wire [31:0] tlbr_tlbehi; + wire [31:0] tlbr_tlbelo0; + wire [31:0] tlbr_tlbelo1; + wire [31:0] tlbr_tlbidx; + wire [9:0] tlbr_asid; + wire invtlb_en; + wire [9:0] invtlb_asid; + wire [18:0] invtlb_vpn; + wire [4:0] invtlb_op; + + //csr + wire has_int; + wire excp_flush; + wire ertn_flush; + wire wb_csr_en; + wire [13:0] wb_csr_addr; + wire [31:0] wb_csr_data; + wire [31:0] wb_csr_era; + wire [8:0] wb_csr_esubcode; + wire [5:0] wb_csr_ecode; + wire wb_va_error; + wire [31:0] wb_bad_va; + wire tlbsrch_en; + wire tlbsrch_found; + wire [4:0] tlbsrch_index; + wire excp_tlbrefill; + wire excp_tlb; + wire [18:0] excp_tlb_vppn; + wire csr_llbit_i; + wire csr_llbit_set_i; + wire csr_llbit_o; + wire csr_llbit_set_o; + wire [`RegBus]csr_eentry; + wire [31:0] csr_tlbrentry; + wire [`RegBus] csr_era; + + wire [9:0] csr_asid; + wire csr_pg; + wire csr_da; + wire [31:0] csr_dmw0; + wire [31:0] csr_dmw1; + wire [1:0] csr_datf; + wire [1:0] csr_datm; + wire [1:0] csr_plv; + + wire [13:0] id_csr_addr_1; + wire [31:0] id_csr_data_1; + wire [13:0] id_csr_addr_2; + wire [31:0] id_csr_data_2; + wire [`RegBus] id_csr_data_o_1; + wire [`RegBus] id_csr_data_o_2; + wire id_csr_we_1; + wire id_csr_we_2; + wire [13:0] id_csr_addr_o_1; + wire [13:0] id_csr_addr_o_2; + wire [13:0] id_csr_read_addr_o_1; + wire [13:0] id_csr_read_addr_o_2; + + wire pc_excp_o; + wire [3:0] pc_excp_num_o; + + wire idle_flush; + wire[`InstAddrBus] idle_pc; + wire excp_flush_1; + wire ertn_flush_1; + wire excp_flush_2; + wire ertn_flush_2; + + assign excp_flush = excp_flush_1 | excp_flush_2; + assign ertn_flush = ertn_flush_1 | ertn_flush_2; + + wire [`RegBus] id_csr_data_i_1; + wire [`RegBus] id_csr_data_i_2; + + wire disable_cache; + pc_reg u_pc_reg( .clk(clk), .rst(rst), @@ -91,21 +210,61 @@ module cpu_top ( .flush(flush), .new_pc(new_pc), .stall1(stall1[0]), - .stall2(stall2[0]) + .stall2(stall2[0]), + .excp_flush(excp_flush), + .ertn_flush(ertn_flush), + .excp_tlbrefill(excp_tlbrefill), + .idle_flush(idle_flush), + .idle_pc(idle_pc), + + .excp_o(pc_excp_o), + .excp_num_o(pc_excp_num_o), + + .csr_pg(csr_pg), + .csr_da(csr_da), + .csr_dmw0(csr_dmw0), + .csr_dmw1(csr_dmw1), + .csr_plv(csr_plv), + .csr_datf(csr_datf), + .disable_cache(disable_cache), + .csr_eentry(csr_eentry), + .csr_era(csr_era), + .csr_tlbrentry(csr_tlbrentry), + + .inst_tlb_found(inst_tlb_found), + .inst_tlb_v(inst_tlb_v), + .inst_tlb_d(inst_tlb_d), + .inst_tlb_mat(inst_tlb_mat), + .inst_tlb_plv(inst_tlb_plv), + + .inst_addr(inst_vaddr), + .inst_addr_trans_en(inst_addr_trans_en), + .dmw0_en(inst_dmw0_en), + .dmw1_en(inst_dmw1_en) ); wire if_inst_valid_1; wire if_inst_valid_2; + wire if_excp_i_1; + wire [3:0] if_excp_num_i_1; + wire if_excp_i_2; + wire [3:0] if_excp_num_i_2; if_buffer if_buffer_1( .clk(clk), .rst(rst), .pc_i(pc_1), - .branch_flag_i(branch_flag), + .branch_flag_i(branch_flag_1 | branch_flag_2), .pc_valid(if_inst_valid_1), .pc_o(pc_buffer_1), .flush(flush), - .stall(stall1[1]) + .stall(stall1[1]), + .excp_i(pc_excp_o), + .excp_num_i(pc_excp_num_o), + .excp_o(if_excp_i_1), + .excp_num_o(if_excp_num_i_1), + .excp_flush(excp_flush), + .ertn_flush(ertn_flush) ); if_buffer if_buffer_2( @@ -116,7 +275,13 @@ module cpu_top ( .pc_valid(if_inst_valid_2), .pc_o(pc_buffer_2), .flush(flush), - .stall(stall2[1]) + .stall(stall2[1]), + .excp_i(pc_excp_o), + .excp_num_i(pc_excp_num_o), + .excp_o(if_excp_i_2), + .excp_num_o(if_excp_num_i_2), + .excp_flush(excp_flush), + .ertn_flush(ertn_flush) ); @@ -125,6 +290,11 @@ module cpu_top ( wire[`InstAddrBus] id_pc_2; wire[`InstBus] id_inst_2; + wire if_excp_o_1; + wire [3:0] if_excp_num_o_1; + wire if_excp_o_2; + wire [3:0] if_excp_num_o_2; + // wire if_id_instr_invalid; if_id u_if_id_1( .clk(clk), @@ -136,7 +306,11 @@ module cpu_top ( .if_inst_valid(if_inst_valid_1), .branch_flag_i(branch_flag), .flush(flush), - .stall(stall1[2]) + .stall(stall1[2]), + .excp_i(if_excp_i_1), + .excp_num_i(if_excp_num_i_1), + .excp_o(if_excp_o_1), + .excp_num_o(if_excp_num_o_1) ); if_id u_if_id_2( @@ -149,7 +323,11 @@ module cpu_top ( .if_inst_valid(if_inst_valid_2), .branch_flag_i(branch_flag), .flush(flush), - .stall(stall2[2]) + .stall(stall2[2]), + .excp_i(if_excp_i_2), + .excp_num_i(if_excp_num_i_2), + .excp_o(if_excp_o_2), + .excp_num_o(if_excp_num_o_2) ); wire[`AluOpBus] id_aluop_1; @@ -204,6 +382,11 @@ module cpu_top ( wire stallreq_to_next_1; wire stallreq_to_next_2; + wire id_excp_o_1; + wire [8:0] id_excp_num_o_1; + wire id_excp_o_2; + wire [8:0] id_excp_num_o_2; + id u_id_1( .rst(rst), @@ -248,12 +431,26 @@ module cpu_top ( .inst_valid(id_inst_valid_1), .inst_pc(id_inst_pc_1), .inst_o(id_inst_o_1), + .csr_we(id_csr_we_1), + .csr_addr_o(id_csr_addr_o_1), + .csr_data_o(id_csr_data_o_1), + + .csr_read_addr_o(id_csr_read_addr_o_1), + .csr_data_i(id_csr_data_1), + .has_int(has_int), + .csr_plv(csr_plv), + + .excp_i(if_excp_o_1), + .excp_num_i(if_excp_num_o_1), + .excp_o(id_excp_o_1), + .excp_num_o(id_excp_num_o_1), .branch_flag_o(branch_flag_1), .branch_target_address_o(branch_target_address_1), .link_addr_o(link_addr_1), .stallreq(stallreq_to_next_1), + .idle_stallreq(), .excepttype_o(id_excepttype_o_1), .current_inst_address_o(id_current_inst_address_o_1) @@ -328,11 +525,26 @@ module cpu_top ( .inst_pc(id_inst_pc_2), .inst_o(id_inst_o_2), + .csr_we(id_csr_we_2), + .csr_addr_o(id_csr_addr_o_2), + .csr_data_i(id_csr_data_2), + + .csr_read_addr_o(id_csr_read_addr_o_2), + .csr_data_o(id_csr_data_o_2), + .has_int(has_int), + .csr_plv(csr_plv), + + .excp_i(if_excp_o_2), + .excp_num_i(if_excp_num_o_2), + .excp_o(id_excp_o_2), + .excp_num_o(id_excp_num_o_2), + .branch_flag_o(branch_flag_2), .branch_target_address_o(branch_target_address_2), .link_addr_o(link_addr_2), .stallreq(stallreq_to_next_2), + .idle_stallreq(), .excepttype_o(id_excepttype_o_2), .current_inst_address_o(id_current_inst_address_o_2) @@ -351,6 +563,14 @@ module cpu_top ( wire[`RegBus] ex_inst_i_1; wire[1:0] ex_excepttype_i_1; wire[`RegBus] ex_current_inst_address_i_1; + wire ex_csr_we_i_1; + wire [13:0] ex_csr_addr_i_1; + wire [31:0] ex_csr_data_i_1; + + wire ex_excp_i_1; + wire [8:0] ex_excp_num_i_1; + wire ex_excp_o_1; + wire [8:0] ex_excp_num_i_2; id_ex id_ex_1( .clk(clk), @@ -370,6 +590,9 @@ module cpu_top ( .flush(flush), .id_excepttype(id_excepttype_o_1), .id_current_inst_address(id_current_inst_address_o_1), + .id_csr_we(id_csr_we_1), + .id_csr_addr(id_csr_addr_o_1), + .id_csr_data(id_csr_data_o_1), .ex_aluop(ex_aluop_1), .ex_alusel(ex_alusel_1), @@ -383,6 +606,9 @@ module cpu_top ( .ex_inst(ex_inst_i_1), .ex_excepttype(ex_excepttype_i_1), .ex_current_inst_address(ex_current_inst_address_i_1), + .ex_csr_we(ex_csr_we_i_1), + .ex_csr_addr(ex_csr_addr_i_1), + .ex_csr_data(ex_csr_data_i_1), .reg1_addr_i(reg1_addr_1), .reg2_addr_i(reg2_addr_1), @@ -392,7 +618,15 @@ module cpu_top ( .waddr_i_other(id_reg_waddr_2), .stallreq_from_id(stallreq_to_next_1), - .stallreq(stallreq_from_id_1) + .stallreq(stallreq_from_id_1), + + .excp_i(id_excp_o_1), + .excp_num_i(id_excp_num_o_1), + .excp_o(ex_excp_i_1), + .excp_num_o(ex_excp_num_i_1), + + .excp_flush(excp_flush), + .ertn_flush(ertn_flush) ); wire[`AluOpBus] ex_aluop_2; @@ -407,6 +641,14 @@ module cpu_top ( wire[`RegBus] ex_inst_i_2; wire[1:0] ex_excepttype_i_2; wire[`RegBus] ex_current_inst_address_i_2; + wire ex_csr_we_i_2; + wire [13:0] ex_csr_addr_i_2; + wire [31:0] ex_csr_data_i_2; + + wire ex_excp_i_2; + wire [9:0] ex_excp_num_o_1; + wire ex_excp_o_2; + wire [9:0] ex_excp_num_o_2; id_ex id_ex_2( .clk(clk), @@ -426,6 +668,9 @@ module cpu_top ( .flush(flush), .id_excepttype(id_excepttype_o_2), .id_current_inst_address(id_current_inst_address_o_2), + .id_csr_we(id_csr_we_2), + .id_csr_addr(id_csr_addr_o_2), + .id_csr_data(id_csr_data_o_2), .ex_aluop(ex_aluop_2), .ex_alusel(ex_alusel_2), @@ -439,6 +684,9 @@ module cpu_top ( .ex_inst(ex_inst_i_2), .ex_excepttype(ex_excepttype_i_2), .ex_current_inst_address(ex_current_inst_address_i_2), + .ex_csr_we(ex_csr_we_i_2), + .ex_csr_addr(ex_csr_addr_i_2), + .ex_csr_data(ex_csr_data_i_2), .reg1_addr_i(reg1_addr_2), .reg2_addr_i(reg2_addr_2), @@ -448,7 +696,15 @@ module cpu_top ( .waddr_i_other(id_reg_waddr_1), .stallreq_from_id(stallreq_to_next_2), - .stallreq(stallreq_from_id_2) + .stallreq(stallreq_from_id_2), + + .excp_i(id_excp_o_2), + .excp_num_i(id_excp_num_o_2), + .excp_o(ex_excp_i_2), + .excp_num_o(ex_excp_num_i_2), + + .excp_flush(excp_flush), + .ertn_flush(ertn_flush) ); @@ -458,6 +714,11 @@ module cpu_top ( wire[`RegBus] ex_reg2_o_1; wire[1:0] ex_excepttype_o_1; wire[`RegBus] ex_current_inst_address_o_1; + wire ex_csr_we_o_1; + wire [13:0] ex_csr_addr_o_1; + wire [31:0] ex_csr_data_o_1; + + ex u_ex_1( .rst(rst), @@ -474,6 +735,9 @@ module cpu_top ( .link_addr_i(ex_link_address_1), .excepttype_i(ex_excepttype_i_1), .current_inst_address_i(ex_current_inst_address_i_1), + .ex_csr_we_i(ex_csr_we_i_1), + .ex_csr_addr_i(ex_csr_addr_i_1), + .ex_csr_data_i(ex_csr_data_i_1), .wd_o(ex_reg_waddr_o_1), .wreg_o(ex_wreg_o_1), @@ -485,8 +749,16 @@ module cpu_top ( .reg2_o(ex_reg2_o_1), .excepttype_o(ex_excepttype_o_1), .current_inst_address_o(ex_current_inst_address_o_1), + .ex_csr_we_o(ex_csr_we_o_1), + .ex_csr_addr_o(ex_csr_addr_o_1), + .ex_csr_data_o(ex_csr_data_o_1), + + .stallreq(stallreq_from_ex_1), - .stallreq(stallreq_from_ex_1) + .excp_i(ex_excp_i_1), + .excp_num_i(ex_excp_num_i_1), + .excp_o(ex_excp_o_1), + .excp_num_o(ex_excp_num_o_1) ); wire ex_inst_valid_o_2; @@ -495,6 +767,10 @@ module cpu_top ( wire[`RegBus] ex_reg2_o_2; wire[1:0] ex_excepttype_o_2; wire[`RegBus] ex_current_inst_address_o_2; + wire ex_csr_we_o_2; + wire [13:0] ex_csr_addr_o_2; + wire [31:0] ex_csr_data_o_2; + ex u_ex_2( .rst(rst), @@ -511,6 +787,9 @@ module cpu_top ( .link_addr_i(ex_link_address_2), .excepttype_i(ex_excepttype_i_2), .current_inst_address_i(ex_current_inst_address_i_2), + .ex_csr_we_i(ex_csr_we_i_2), + .ex_csr_addr_i(ex_csr_addr_i_2), + .ex_csr_data_i(ex_csr_data_i_2), .wd_o(ex_reg_waddr_o_2), .wreg_o(ex_wreg_o_2), @@ -522,8 +801,16 @@ module cpu_top ( .reg2_o(ex_reg2_o_2), .excepttype_o(ex_excepttype_o_2), .current_inst_address_o(ex_current_inst_address_o_2), + .ex_csr_we_o(ex_csr_we_o_2), + .ex_csr_addr_o(ex_csr_addr_o_2), + .ex_csr_data_o(ex_csr_data_o_2), - .stallreq(stallreq_from_ex_2) + .stallreq(stallreq_from_ex_2), + + .excp_i(ex_excp_i_2), + .excp_num_i(ex_excp_num_i_2), + .excp_o(ex_excp_o_2), + .excp_num_o(ex_excp_num_o_2) ); @@ -540,6 +827,15 @@ module cpu_top ( wire[1:0] mem_excepttype_i_1; wire[`RegBus] mem_current_inst_address_i_1; + wire mem_csr_we_i_1; + wire [13:0] mem_csr_addr_i_1; + wire [31:0] mem_csr_data_i_1; + + wire mem_excp_i_1; + wire [9:0] mem_excp_num_i_1; + wire mem_excp_i_2; + wire [9:0] mem_excp_num_i_2; + ex_mem u_ex_mem_1( .clk(clk ), .rst(rst ), @@ -556,6 +852,9 @@ module cpu_top ( .flush(flush), .ex_excepttype(ex_excepttype_o_1), .ex_current_inst_address(ex_current_inst_address_o_1), + .ex_csr_we(ex_csr_we_o_1), + .ex_csr_addr(ex_csr_addr_o_1), + .ex_csr_data(ex_csr_data_o_1), .mem_wd(mem_reg_waddr_i_1 ), .mem_wreg(mem_wreg_i_1 ), @@ -566,7 +865,19 @@ module cpu_top ( .mem_mem_addr(mem_addr_i_1), .mem_reg2(mem_reg2_i_1), .mem_excepttype(mem_excepttype_i_1), - .mem_current_inst_address(mem_current_inst_address_i_1) + .mem_current_inst_address(mem_current_inst_address_i_1), + .mem_csr_we(mem_csr_we_i_1), + .mem_csr_addr(mem_csr_addr_i_1), + .mem_csr_data(mem_csr_data_i_1), + + .excp_i(ex_excp_o_1), + .excp_num_i(ex_excp_num_o_1), + .excp_o(mem_excp_i_1), + .excp_num_o(mem_excp_num_i_1), + + .excp_flush(excp_flush), + .ertn_flush(ertn_flush) + ); @@ -582,6 +893,9 @@ module cpu_top ( wire[`RegBus] mem_reg2_i_2; wire[1:0] mem_excepttype_i_2; wire[`RegBus] mem_current_inst_address_i_2; + wire mem_csr_we_i_2; + wire [13:0] mem_csr_addr_i_2; + wire [31:0] mem_csr_data_i_2; ex_mem u_ex_mem_2( @@ -600,6 +914,9 @@ module cpu_top ( .flush(flush), .ex_excepttype(ex_excepttype_o_2), .ex_current_inst_address(ex_current_inst_address_o_2), + .ex_csr_we(ex_csr_we_o_1), + .ex_csr_addr(ex_csr_addr_o_1), + .ex_csr_data(ex_csr_data_o_1), .mem_wd(mem_reg_waddr_i_2 ), .mem_wreg(mem_wreg_i_2 ), @@ -610,7 +927,19 @@ module cpu_top ( .mem_mem_addr(mem_addr_i_2), .mem_reg2(mem_reg2_i_2), .mem_excepttype(mem_excepttype_i_2), - .mem_current_inst_address(mem_current_inst_address_i_2) + .mem_current_inst_address(mem_current_inst_address_i_2), + .mem_csr_we(mem_csr_we_i_2), + .mem_csr_addr(mem_csr_addr_i_2), + .mem_csr_data(mem_csr_data_i_2), + + .excp_i(ex_excp_o_2), + .excp_num_i(ex_excp_num_o_2), + .excp_o(mem_excp_i_2), + .excp_num_o(mem_excp_num_i_2), + + .excp_flush(excp_flush), + .ertn_flush(ertn_flush) + ); wire LLbit_o_1; @@ -622,6 +951,27 @@ module cpu_top ( wire[1:0] mem_excepttype_o_2; wire[`RegBus] mem_current_inst_address_o_1; wire[`InstAddrBus] wb_inst_pc_1; + wire mem_csr_we_o_1; + wire [13:0] mem_csr_addr_o_1; + wire [31:0] mem_csr_data_o_1; + + wire mem_excp_o_1; + wire [15:0] mem_excp_num_o_1; + wire mem_excp_o_2; + wire [15:0] mem_excp_num_o_2; + + wire[`AluOpBus] mem_aluop_o_1; + wire[`AluOpBus] mem_aluop_o_2; + + wire data_addr_trans_en_1; + wire data_dmw0_en_1; + wire data_dmw1_en_1; + + wire data_addr_trans_en_2; + wire data_dmw0_en_2; + wire data_dmw1_en_2; + + mem u_mem_1( .rst (rst ), @@ -643,10 +993,15 @@ module cpu_top ( .excepttype_i(mem_excepttype_i_1), .current_inst_address_i(mem_current_inst_address_i_1), + .mem_csr_we_i(mem_csr_we_i_1), + .mem_csr_addr_i(mem_csr_addr_i_1), + .mem_csr_data_i(mem_csr_data_i_1), + .inst_pc_o(wb_inst_pc_1), .wd_o (mem_reg_waddr_o_1), .wreg_o (mem_wreg_o_1 ), .wdata_o (mem_reg_wdata_o_1 ), + .aluop_o(mem_aluop_i_1), .mem_addr_o(dram_addr_o_1), .mem_we_o(dram_we_o_1), @@ -658,7 +1013,36 @@ module cpu_top ( .LLbit_value_o(mem_LLbit_value_o_1), .excepttype_o(mem_excepttype_o_1), - .current_inst_address_o(mem_current_inst_address_o_1) + .current_inst_address_o(mem_current_inst_address_o_1), + + .mem_csr_we_o(mem_csr_we_o_1), + .mem_csr_addr_o(mem_csr_addr_o_1), + .mem_csr_data_o(mem_csr_data_o_1), + + .excp_i(mem_excp_i_1), + .excp_num_i(mem_excp_num_i_1), + .excp_o(mem_excp_o_1), + .excp_num_o(mem_excp_num_o_1), + + .csr_pg(csr_pg), + .csr_da(csr_da), + .csr_dmw0(csr_dmw0), + .csr_dmw1(csr_dmw1), + .csr_plv(csr_plv), + .csr_datf(csr_datf), + .disable_cache(1'b0), + + .data_addr_trans_en(data_addr_trans_en_1), + .dmw0_en(data_dmw0_en_1), + .dmw1_en(data_dmw1_en_1), + .cacop_op_mode_di(cacop_op_mode_di), + + .data_tlb_found(data_tlb_found), + .data_tlb_index(data_tlb_index), + .data_tlb_v(data_tlb_v), + .data_tlb_d(data_tlb_d), + .data_tlb_mat(data_tlb_mat), + .data_tlb_plv(data_tlb_plv) ); @@ -669,6 +1053,11 @@ module cpu_top ( wire mem_LLbit_value_o_2; wire[`RegBus] mem_current_inst_address_o_2 ; wire[`InstAddrBus] wb_inst_pc_2; + wire mem_csr_we_o_2; + wire [13:0] mem_csr_addr_o_2; + wire [31:0] mem_csr_data_o_2; + + mem u_mem_2( .rst (rst ), @@ -690,10 +1079,15 @@ module cpu_top ( .excepttype_i(mem_excepttype_i_2), .current_inst_address_i(mem_current_inst_address_i_2), + .mem_csr_we_i(mem_csr_we_i_2), + .mem_csr_addr_i(mem_csr_addr_i_2), + .mem_csr_data_i(mem_csr_data_i_2), + .inst_pc_o(wb_inst_pc_2), .wd_o (mem_reg_waddr_o_2), .wreg_o (mem_wreg_o_2 ), .wdata_o (mem_reg_wdata_o_2 ), + .aluop_o(mem_aluop_o_2), .mem_addr_o(dram_addr_o_2), .mem_we_o(dram_we_o_2), @@ -705,7 +1099,36 @@ module cpu_top ( .LLbit_value_o(mem_LLbit_value_o_2), .excepttype_o(mem_excepttype_o_2), - .current_inst_address_o(mem_current_inst_address_o_2) + .current_inst_address_o(mem_current_inst_address_o_2), + + .mem_csr_we_o(mem_csr_we_o_2), + .mem_csr_addr_o(mem_csr_addr_o_2), + .mem_csr_data_o(mem_csr_data_o_2), + + .excp_i(mem_excp_i_2), + .excp_num_i(mem_excp_num_i_2), + .excp_o(mem_excp_o_2), + .excp_num_o(mem_excp_num_o_2), + + .csr_pg(csr_pg), + .csr_da(csr_da), + .csr_dmw0(csr_dmw0), + .csr_dmw1(csr_dmw1), + .csr_plv(csr_plv), + .csr_datf(csr_datf), + .disable_cache(1'b0), + + .data_addr_trans_en(data_addr_trans_en_2), + .dmw0_en(data_dmw0_en_2), + .dmw1_en(data_dmw1_en_2), + .cacop_op_mode_di(cacop_op_mode_di), + + .data_tlb_found(data_tlb_found), + .data_tlb_index(data_tlb_index), + .data_tlb_v(data_tlb_v), + .data_tlb_d(data_tlb_d), + .data_tlb_mat(data_tlb_mat), + .data_tlb_plv(data_tlb_plv) ); @@ -716,11 +1139,28 @@ module cpu_top ( wire[`RegAddrBus] wb_reg_waddr_1; wire[`RegBus] wb_reg_wdata_1; + wire wb_csr_we_1; + wire[13:0] wb_csr_addr_1; + wire[`RegBus] wb_csr_data_1; + assign debug_commit_wreg_1 = wb_wreg_1; assign debug_commit_reg_waddr_1 = wb_reg_waddr_1; assign debug_commit_reg_wdata_1 = wb_reg_wdata_1; + wire wb_excp_o_1; + wire [15:0] wb_excp_num_o_1; + wire wb_excp_o_2; + wire [15:0] wb_excp_num_o_2; + + wire [`RegBus] wb_csr_era_1; + wire [8:0] wb_csr_esubcode_1; + wire [5:0] wb_csr_ecode_1; + + wire wb_va_error_1; + wire [`RegBus]wb_bad_va_1; + wire excp_tlbrefill_1; + wire [18:0] excp_tlb_vppn_1; mem_wb mem_wb_1( .clk(clk), @@ -732,12 +1172,17 @@ module cpu_top ( .mem_wdata(mem_reg_wdata_o_1), .mem_inst_pc (mem_inst_pc_1 ), .mem_instr ( ), + .mem_aluop(mem_aluop_o_1), .mem_inst_valid (mem_inst_valid_1 ), .mem_LLbit_we(mem_LLbit_we_o_1), .mem_LLbit_value(mem_LLbit_value_o_1), .flush(flush), + + .mem_csr_we(mem_csr_we_o_1), + .mem_csr_addr(mem_csr_addr_o_1), + .mem_csr_data(mem_csr_data_o_1), .wb_wd(wb_reg_waddr_1), .wb_wreg(wb_wreg_1), @@ -746,19 +1191,51 @@ module cpu_top ( .wb_LLbit_we(wb_LLbit_we_i_1), .wb_LLbit_value(wb_LLbit_value_i_1), + .wb_csr_we(wb_csr_we_1), + .wb_csr_addr(wb_csr_addr_1), + .wb_csr_data(wb_csr_data_1), + .debug_commit_pc (debug_commit_pc_1 ), .debug_commit_valid (debug_commit_valid_1 ), - .debug_commit_instr (debug_commit_instr_1 ) + .debug_commit_instr (debug_commit_instr_1 ), + + .excp_i(mem_excp_o_1), + .excp_num_i(mem_excp_num_o_1), + .excp_o(wb_excp_o_1), + .excp_num_o(wb_excp_num_o_1), + + .csr_era(wb_csr_era_1), + .csr_esubcode(wb_csr_esubcode_1), + .csr_ecode(wb_csr_ecode_1), + .excp_flush(excp_flush_1), + .ertn_flush(ertn_flush_1), + .va_error(wb_va_error_1), + .bad_va(wb_bad_va_1), + .excp_tlbrefill(excp_tlbrefill_1), + .excp_tlb_vppn(excp_tlb_vppn_1) ); wire wb_wreg_2; wire[`RegAddrBus] wb_reg_waddr_2; wire[`RegBus] wb_reg_wdata_2; + wire wb_csr_we_2; + wire[13:0] wb_csr_addr_2; + wire[`RegBus] wb_csr_data_2; + assign debug_commit_wreg_2 = wb_wreg_2; assign debug_commit_reg_waddr_2 = wb_reg_waddr_2; assign debug_commit_reg_wdata_2 = wb_reg_wdata_2; + wire [`RegBus] wb_csr_era_2; + wire [8:0] wb_csr_esubcode_2; + wire [5:0] wb_csr_ecode_2; + + wire wb_va_error_2; + wire [`RegBus]wb_bad_va_2; + wire excp_tlbrefill_2; + wire [18:0] excp_tlb_vppn_2; + mem_wb mem_wb_2( .clk(clk), .rst(rst), @@ -769,6 +1246,7 @@ module cpu_top ( .mem_wdata(mem_reg_wdata_o_2), .mem_inst_pc (mem_inst_pc_2 ), .mem_instr ( ), + .mem_aluop(mem_aluop_o_2), .mem_inst_valid (mem_inst_valid_2 ), .mem_LLbit_we(mem_LLbit_we_o_2), @@ -776,6 +1254,10 @@ module cpu_top ( .flush(flush), + .mem_csr_we(mem_csr_we_o_2), + .mem_csr_addr(mem_csr_addr_o_2), + .mem_csr_data(mem_csr_data_o_2), + .wb_wd(wb_reg_waddr_2), .wb_wreg(wb_wreg_2), .wb_wdata(wb_reg_wdata_2), @@ -783,14 +1265,33 @@ module cpu_top ( .wb_LLbit_we(wb_LLbit_we_i), .wb_LLbit_value(wb_LLbit_value_2), + .wb_csr_we(wb_csr_we_2), + .wb_csr_addr(wb_csr_addr_2), + .wb_csr_data(wb_csr_data_2), + .debug_commit_pc (debug_commit_pc_2 ), .debug_commit_valid (debug_commit_valid_2 ), - .debug_commit_instr (debug_commit_instr_2 ) + .debug_commit_instr (debug_commit_instr_2 ), + + .excp_i(mem_excp_o_2), + .excp_num_i(mem_excp_num_o_2), + .excp_o(wb_excp_o_2), + .excp_num_o(wb_excp_num_o_2), + + .csr_era(wb_csr_era_2), + .csr_esubcode(wb_csr_esubcode_2), + .csr_ecode(wb_csr_ecode_2), + .excp_flush(excp_flush_2), + .ertn_flush(ertn_flush_2), + .va_error(wb_va_error_2), + .bad_va(wb_bad_va_2), + .excp_tlbrefill(excp_tlbrefill_2), + .excp_tlb_vppn(excp_tlb_vppn_2) ); regfile u_regfile( - .clk(clk ), - .rst(rst ), + .clk(clk), + .rst(rst), .we_1 (wb_wreg_1), .pc_i_1 (), @@ -813,18 +1314,19 @@ module cpu_top ( .re2_2 (reg2_read_2), .raddr2_2 (reg2_addr_2), .rdata2_2 (reg2_data_2), - .debug_reg (debug_reg) + .debug_reg(debug_reg) ); ctrl u_ctrl( - .clk (clk ), - .rst (rst ), + .clk(clk), + .rst(rst), .stall1(stall1), .stallreq_from_id_1(stallreq_from_id_1), .stallreq_from_ex_1(stallreq_from_ex_1), .stall2(stall2), .stallreq_from_id_2(stallreq_from_id_2), .stallreq_from_ex_2(stallreq_from_ex_2), + .idle_stallreq(), .excepttype_i_1(mem_excepttype_o_1), .excepttype_i_2(mem_excepttype_o_2), .new_pc(new_pc), @@ -835,10 +1337,140 @@ module cpu_top ( .clk(clk), .rst(rst), .flush(1'b0), - .LLbit_i(wb_LLbit_value_i), + .LLbit_i_1(wb_LLbit_value_i_1), + .LLbit_i_2(wb_LLbit_value_i_2), .we(wb_LLbit_we_i), .LLbit_o(LLbit_o) ); + //目前没有进行冲突处理,是假设不会同时出现两条异常同时发生 + assign wb_csr_era = wb_csr_era_1 | wb_csr_era_2; + assign wb_csr_ecode = wb_csr_ecode_1 | wb_csr_ecode_2; + assign wb_csr_esubcode = wb_csr_esubcode_1 | wb_csr_esubcode_2; + assign excp_flush = excp_flush_1 | excp_flush_2; + assign ertn_flush = ertn_flush_1 | ertn_flush_2; + assign wb_va_error = wb_va_error_1 | wb_va_error_2; + assign wb_bad_va = wb_bad_va_1 | wb_bad_va_2; + assign excp_tlbrefill = excp_tlbrefill_1 | excp_tlbrefill_2; + assign excp_tlb_vppn = excp_tlb_vppn_1 | excp_tlb_vppn_2; + + cs_reg u_cs_reg( + .clk(clk), + .rst(rst), + .waddr_1(wb_csr_addr_1), + .waddr_2(wb_csr_addr_2), + .excp_flush(excp_flush), + .ertn_flush(ertn_flush), + .we_1(wb_csr_we_1), + .we_2(wb_csr_we_2), + .wdata_1(wb_csr_data_1), + .wdata_2(wb_csr_data_2), + .raddr_1(id_csr_read_addr_o_1), + .raddr_2(id_csr_read_addr_o_2), + .rdata_1(id_csr_data_1), + .rdata_2(id_csr_data_2), + .era_i(wb_csr_era), + .esubcode_i(wb_csr_esubcode), + .va_error_i(wb_va_error), + .bad_va_i(wb_bad_va), + .tlbsrch_en(tlbsrch_en), + .tlbsrch_found(tlbsrch_found), + .tlbsrch_index(tlbsrch_index), + .excp_tlbrefill(excp_tlbrefill), + .excp_tlb(excp_tlb), + .excp_tlb_vppn(excp_tlb_vppn), + .has_int(has_int), + .eentry_out(csr_eentry), + .era_out(csr_era), + .tlbrentry_out(csr_tlbrentry), + .asid_out(csr_asid), + .rand_index(rand_index), + .tlbehi_out(tlbw_tlbehi), + .tlbelo0_out(tlbw_tlbelo0), + .tlbelo1_out(tlbw_tlbelo1), + .tlbidx_out(tlbw_r_tlbidx), + .pg_out(csr_pg), + .da_out(csr_da), + .dmw0_out(csr_dmw0), + .dmw1_out(csr_dmw1), + .datf_out(csr_datf), + .datm_out(csr_datm), + .ecode_out(tlbw_ecode), + .tlbrd_en(tlbrd_en), + .tlbehi_in(tlbr_tlbehi), + .tlbelo0_in(tlbr_tlbelo0), + .tlbelo1_in(tlbr_tlbelo1), + .tlbidx_in(tlbr_tlbidx), + .asid_in(tlbr_asid), + .csr_diff(csr_diff) + ); + + + assign data_addr_trans_en = data_addr_trans_en_1 | data_addr_trans_en_2; + assign data_dmw0_en = data_dmw0_en_1 | data_dmw0_en_2; + assign data_dmw1_en = data_dmw1_en_1 | data_dmw1_en_2; + + tlb u_tlb( + .clk(clk), + .asid(csr_asid), + //trans mode + .inst_addr_trans_en(inst_addr_trans_en), + .data_addr_trans_en(data_addr_trans_en), + //inst addr trans + .inst_fetch(fetch_en), + .inst_vaddr(inst_vaddr), + .inst_dmw0_en(inst_dmw0_en), + .inst_dmw1_en(inst_dmw1_en), + .inst_index(inst_index), + .inst_tag (inst_tag), + .inst_offset(inst_offset), + .inst_tlb_found(inst_tlb_found), + .inst_tlb_v(inst_tlb_v), + .inst_tlb_d(inst_tlb_d), + .inst_tlb_mat(inst_tlb_mat), + .inst_tlb_plv(inst_tlb_plv), + //data addr trans + .data_fetch(data_fetch), + .data_vaddr(data_vaddr), + .data_dmw0_en(data_dmw0_en), + .data_dmw1_en(data_dmw1_en), + .cacop_op_mode_di (cacop_op_mode_di), + .data_index (data_index ), + .data_tag (data_tag ), + .data_offset (data_offset ), + .data_tlb_found (data_tlb_found ), + .data_tlb_index (data_tlb_index ), + .data_tlb_v (data_tlb_v ), + .data_tlb_d (data_tlb_d ), + .data_tlb_mat (data_tlb_mat ), + .data_tlb_plv (data_tlb_plv ), + //tlbwr tlbfill tlb write + .tlbfill_en (tlbfill_en ), + .tlbwr_en (tlbwr_en ), + .rand_index (rand_index ), + .tlbehi_in (tlbw_tlbehi ), + .tlbelo0_in (tlbw_tlbelo0 ), + .tlbelo1_in (tlbw_tlbelo1 ), + .tlbidx_in (tlbw_r_tlbidx ), + .ecode_in (tlbw_ecode ), + //tlbp tlb read + .tlbehi_out (tlbr_tlbehi ), + .tlbelo0_out (tlbr_tlbelo0 ), + .tlbelo1_out (tlbr_tlbelo1 ), + .tlbidx_out (tlbr_tlbidx ), + .asid_out (tlbr_asid ), + //invtlb + .invtlb_en (invtlb_en ), + .invtlb_asid (invtlb_asid ), + .invtlb_vpn (invtlb_vpn ), + .invtlb_op (invtlb_op ), + //from csr + .csr_dmw0 (csr_dmw0 ), + .csr_dmw1 (csr_dmw1 ), + .csr_da (csr_da ), + .csr_pg (csr_pg ) + ); + + endmodule diff --git a/src/vsrc/cs_reg.v b/src/vsrc/cs_reg.v index 9779baa..06d8770 100644 --- a/src/vsrc/cs_reg.v +++ b/src/vsrc/cs_reg.v @@ -1,17 +1,75 @@ +`timescale 1ns/1ns + `include "defines.v" `include "csr_defines.v" module cs_reg ( input wire clk, - input wire rst, + input wire rst, + + input wire we_1, + input wire[13:0] waddr_1, + input wire[`RegBus] wdata_1, + input wire we_2, + input wire[13:0] waddr_2, + input wire[`RegBus] wdata_2, + + + input wire excp_flush, + input wire ertn_flush, + input wire [8:0] interrupt_i, + input wire [31:0]era_i, + input wire [8:0] esubcode_i, + input wire [5:0] ecode_i, + input wire va_error_i, + input wire [31:0] bad_va_i, + input wire tlbsrch_en, + input wire tlbsrch_found, + input wire [4:0] tlbsrch_index, + input wire excp_tlbrefill, + input wire excp_tlb, + input wire [18:0] excp_tlb_vppn, - input wire[`AluOpBus] aluop_i, - input wire[13:0] csr_num, - input wire[1:0]exception_i, + input wire[13:0] raddr_1, + output wire[`RegBus] rdata_1, + input wire[13:0] raddr_2, + output wire[`RegBus] rdata_2, - input wire we, - input wire[`RegBus] wdata, + input wire llbit_i, + input wire llbit_set_i, - output reg[`RegBus] rdata + output wire llbit_o, + output wire[18:0]vppn_o, + + //to pc_reg + output wire has_int, + output wire[31:0] eentry_out, + output wire[31:0] era_out, + output wire[31:0] tlbrentry_out, + + //to tlb + output wire[ 9:0] asid_out, + output wire[ 4:0] rand_index, + output wire[31:0] tlbehi_out, + output wire[31:0] tlbelo0_out, + output wire[31:0] tlbelo1_out, + output wire[31:0] tlbidx_out, + output wire pg_out, + output wire da_out, + output wire[31:0] dmw0_out, + output wire[31:0] dmw1_out, + output wire[1:0] datf_out, + output wire[1:0] datm_out, + output wire[5:0] ecode_out, + //from tlb + input wire tlbrd_en, + input wire[31:0] tlbehi_in, + input wire[31:0] tlbelo0_in, + input wire[31:0] tlbelo1_in, + input wire[31:0] tlbidx_in, + input wire[ 9:0] asid_in, + + //csr output for difftest + output [831:0] csr_diff ); reg [31:0] csr_crmd; @@ -25,6 +83,13 @@ reg [31:0] csr_tlbidx; reg [31:0] csr_tlbehi; reg [31:0] csr_tlbelo0; reg [31:0] csr_tlbelo1; +reg [31:0] csr_tlbrentry; +reg [31:0] csr_tid; +reg [31:0] csr_tcfg; +reg [31:0] csr_tval; +reg [31:0] csr_cntc; +reg [31:0] csr_ticlr; +reg [31:0] csr_llbctl; reg [31:0] csr_asid; reg [31:0] csr_cpuid; reg [31:0] csr_pgdl; @@ -33,6 +98,142 @@ reg [31:0] csr_save0; reg [31:0] csr_save1; reg [31:0] csr_save2; reg [31:0] csr_save3; +reg [31:0] csr_dmw0; +reg [31:0] csr_dmw1; + +wire [31:0] csr_pgd; +reg timer_en; +reg [63:0] timer_64; + +reg llbit; + +wire eret_tlbrefill_excp; +wire tlbrd_valid_wr_en; +wire tlbrd_invalid_wr_en; +wire no_forward; + +//选择有写入信号的进行赋值,同样假设不会有写冲突 +reg we; +reg [13:0]waddr; +reg [`RegBus] wdata; + +always @(*) begin + if(rst)begin + we = 1'b0; + waddr = 14'b0; + wdata = `ZeroWord; + end + else if(we_1 == 1'b1)begin + we = we_1; + waddr = waddr_1; + wdata = wdata_1; + end + else if(we_2 == 1'b1)begin + we = we_2; + waddr = waddr_2; + wdata = wdata_2; + end + else begin + we = 1'b0; + waddr = 14'b0; + wdata = `ZeroWord; + end +end + + +//csr_difftest output +assign csr_diff = {csr_crmd,csr_prmd,csr_ectl,csr_estat,csr_era,csr_badv,csr_eentry,csr_tlbidx, + csr_tlbehi,csr_tlbelo0,csr_tlbelo1,csr_asid,csr_save0,csr_save1,csr_save2, + csr_save3,csr_tid,csr_tcfg,csr_tval,csr_ticlr,{csr_llbctl[31:1], llbit}, + csr_tlbrentry,csr_dmw0,csr_dmw1,csr_pgdl,csr_pgdh }; +//data to pc_reg +assign no_forward = !excp_tlbrefill && !(eret_tlbrefill_excp && ertn_flush) && !(we == 1'b1 && waddr == `CRMD); + +assign pg_out = excp_tlbrefill & 1'b0 | + (eret_tlbrefill_excp && ertn_flush) & 1'b1 | + (we == 1'b1 && waddr == `CRMD) & wdata[`PG] | + no_forward & csr_crmd[`PG]; + +assign da_out = excp_tlbrefill & 1'b1 | + (eret_tlbrefill_excp && ertn_flush) & 1'b0 | + (we == 1'b1 && waddr == `CRMD) & wdata[`DA] | + no_forward & csr_crmd[`DA]; + +assign eret_tlbrefill_excp = csr_estat[`ECODE] == 6'h3f; + +assign tlbrd_valid_wr_en = tlbrd_en && !tlbidx_in[`NE]; +assign tlbrd_invalid_wr_en = tlbrd_en && tlbidx_in[`NE]; + + +assign dmw0_out = we == 1'b1 && waddr == `DMW0 ? wdata : csr_dmw0; +assign dmw1_out = we == 1'b1 && waddr == `DMW1 ? wdata : csr_dmw1; + +assign has_int = ((csr_ectl[`LIE] & csr_estat[`IS]) != 13'b0) & csr_crmd[`IE]; + +assign plv_out = {2{excp_flush}} & 2'b0 | + {2{ertn_flush}} & csr_prmd[`PPLV] | + {2{(we == 1'b1 && waddr == `CRMD) }} & wdata[`PLV] | + {2{!excp_flush && !ertn_flush && !(we == 1'b1 && waddr == `CRMD)}} & csr_crmd[`PLV]; + + assign rdata_1 = {32{raddr_1 == `CRMD }} & csr_crmd | + {32{raddr_1 == `PRMD }} & csr_prmd | + {32{raddr_1 == `ECTL }} & csr_ectl | + {32{raddr_1 == `ESTAT }} & csr_estat | + {32{raddr_1 == `ERA }} & csr_era | + {32{raddr_1 == `BADV }} & csr_badv | + {32{raddr_1 == `EENTRY}} & csr_eentry | + {32{raddr_1 == `TLBIDX}} & csr_tlbidx | + {32{raddr_1 == `TLBEHI}} & csr_tlbehi | + {32{raddr_1 == `TLBELO0}} & csr_tlbelo0 | + {32{raddr_1 == `TLBELO1}} & csr_tlbelo1 | + {32{raddr_1 == `ASID }} & csr_asid | + {32{raddr_1 == `PGDL }} & csr_pgdl | + {32{raddr_1 == `PGDH }} & csr_pgdh | + {32{raddr_1 == `PGD }} & csr_pgd | + {32{raddr_1 == `CPUID }} & csr_cpuid | + {32{raddr_1 == `SAVE0 }} & csr_save0 | + {32{raddr_1 == `SAVE1 }} & csr_save1 | + {32{raddr_1 == `SAVE2 }} & csr_save2 | + {32{raddr_1 == `SAVE3 }} & csr_save3 | + {32{raddr_1 == `TID }} & csr_tid | + {32{raddr_1 == `TCFG }} & csr_tcfg | + {32{raddr_1 == `CNTC }} & csr_cntc | + {32{raddr_1 == `TICLR }} & csr_ticlr | + {32{raddr_1 == `LLBCTL}} & {csr_llbctl[31:1], llbit} | + {32{raddr_1 == `TVAL }} & csr_tval | + {32{raddr_1 == `TLBRENTRY}} & csr_tlbrentry | + {32{raddr_1 == `DMW0}} & csr_dmw0 | + {32{raddr_1 == `DMW1}} & csr_dmw1 ; + + assign rdata_2 = {32{raddr_2 == `CRMD }} & csr_crmd | + {32{raddr_2 == `PRMD }} & csr_prmd | + {32{raddr_2 == `ECTL }} & csr_ectl | + {32{raddr_2 == `ESTAT }} & csr_estat | + {32{raddr_2 == `ERA }} & csr_era | + {32{raddr_2 == `BADV }} & csr_badv | + {32{raddr_2 == `EENTRY}} & csr_eentry | + {32{raddr_2 == `TLBIDX}} & csr_tlbidx | + {32{raddr_2 == `TLBEHI}} & csr_tlbehi | + {32{raddr_2 == `TLBELO0}} & csr_tlbelo0 | + {32{raddr_2 == `TLBELO1}} & csr_tlbelo1 | + {32{raddr_2 == `ASID }} & csr_asid | + {32{raddr_2 == `PGDL }} & csr_pgdl | + {32{raddr_2 == `PGDH }} & csr_pgdh | + {32{raddr_2 == `PGD }} & csr_pgd | + {32{raddr_2 == `CPUID }} & csr_cpuid | + {32{raddr_2 == `SAVE0 }} & csr_save0 | + {32{raddr_2 == `SAVE1 }} & csr_save1 | + {32{raddr_2 == `SAVE2 }} & csr_save2 | + {32{raddr_2 == `SAVE3 }} & csr_save3 | + {32{raddr_2 == `TID }} & csr_tid | + {32{raddr_2 == `TCFG }} & csr_tcfg | + {32{raddr_2 == `CNTC }} & csr_cntc | + {32{raddr_2 == `TICLR }} & csr_ticlr | + {32{raddr_2 == `LLBCTL}} & {csr_llbctl[31:1], llbit} | + {32{raddr_2 == `TVAL }} & csr_tval | + {32{raddr_2 == `TLBRENTRY}} & csr_tlbrentry | + {32{raddr_2 == `DMW0}} & csr_dmw0 | + {32{raddr_2 == `DMW1}} & csr_dmw1 ; //crmd @@ -46,7 +247,7 @@ always @(posedge clk) begin csr_crmd[`DATM] <= 2'b0; csr_crmd[31:9] <= 23'b0; end - else if (excp_flush) begin + else if (ertn_flush) begin csr_crmd[`PLV] <= 2'b0; csr_crmd[`IE] <= 1'b0; if (excp_tlbrefill) begin @@ -54,7 +255,7 @@ always @(posedge clk) begin csr_crmd [`PG] <= 1'b0; end end - else if(exception_i)begin + else if(excp_flush)begin csr_crmd[`PLV] <= csr_prmd[`PPLV]; csr_crmd[`IE] <= csr_prmd[`PIE]; if(eret_tlbrefill_excp)begin @@ -62,7 +263,7 @@ always @(posedge clk) begin csr_crmd[`PG] <= 1'b1; end end - else if (we == 1'b1 && csr_num == `CRMD) begin + else if (we == 1'b1 && waddr == `CRMD) begin csr_crmd[`PLV] <= wdata[`PLV]; csr_crmd[`IE] <= wdata[`IE]; csr_crmd[`DA] <= wdata[`DA]; @@ -77,11 +278,11 @@ always @(posedge clk) begin if (rst) begin csr_prmd[31:3] <= 29'b0; end - else if (exception_i) begin + else if (excp_flush) begin csr_prmd[`PPLV] <= csr_crmd[`PLV]; csr_prmd[`PIE] <= csr_crmd[`IE]; end - else if (we == 1'b1 && csr_num == `PRMD) begin + else if (we == 1'b1 && waddr == `PRMD) begin csr_prmd[`PPLV] <= wdata[`PPLV]; csr_prmd[`PIE] <= wdata[`PIE]; end @@ -91,7 +292,7 @@ end always @(posedge clk) begin if (rst) csr_ectl <= 32'b0; - else if(we == 1'b1 && csr_num == `ECTL) + else if(we == 1'b1 && waddr == `ECTL) csr_ectl[`LIE] <= wdata[`LIE]; end @@ -99,23 +300,51 @@ always @(posedge clk) begin end +//estate +always @(posedge clk) begin + if(rst)begin + csr_estat[1:0] <= 2'b0; + csr_estat[15:13] <= 3'b0; + csr_estat[31] <= 1'b0; + timer_en <= 1'b0; + end + else begin + if (we == 1'b1 && waddr == `TICLR && wdata[`CLR]) + csr_estat[11] <= 1'b0; + else if (we == 1'b1 && waddr == `TCFG) + timer_en <= wdata[`EN]; + else if (timer_en && (csr_tval == 32'b0)) begin + csr_estat[11] <= 1'b1; + timer_en <= csr_tcfg[`PERIODIC]; + end + csr_estat[10:2] <= interrupt_i; + if (excp_flush) begin + csr_estat[`ECODE] <= ecode_i; + csr_estat[`ESUBCODE] <= esubcode_i; + end + else if (we == 1'b1 && waddr == `ESTAT) begin + csr_estat[ 1:0] <= wdata[ 1:0]; + end + end +end + //era always @(posedge clk) begin if (excp_flush) begin - + csr_era <= era_i; end - else if (we == 1'b1 && csr_num == `ERA) begin + else if (we == 1'b1 && waddr == `ERA) begin csr_era <= wdata; end end //badv always @(posedge clk) begin - if (we == 1'b1 && csr_num == `BADV) begin + if (we == 1'b1 && waddr == `BADV) begin csr_badv <= wdata; end - else if (va_error_in) begin - csr_badv <= bad_va_in; + else if (va_error_i) begin + csr_badv <= bad_va_i; end end @@ -124,7 +353,7 @@ always @(posedge clk) begin if (rst) begin csr_eentry[5:0] <= 6'b0; end - else if (we == 1'b1 && csr_num == `EENTRY) begin + else if (we == 1'b1 && waddr == `EENTRY) begin csr_eentry[31:6] <= wdata[31:6]; end end @@ -138,32 +367,263 @@ end //save0 always @(posedge clk) begin - if (we == 1'b1 && csr_num == `SAVE0) csr_save0 <= wdata; + if (we == 1'b1 && waddr == `SAVE0) csr_save0 <= wdata; end //save1 always @(posedge clk) begin - if (we == 1'b1 && csr_num == `SAVE1) csr_save1 <= wdata; + if (we == 1'b1 && waddr == `SAVE1) csr_save1 <= wdata; end //save2 always @(posedge clk) begin - if (we == 1'b1 && csr_num == `SAVE2) csr_save2 <= wdata; + if (we == 1'b1 && waddr == `SAVE2) csr_save2 <= wdata; end //save3 always @(posedge clk) begin - if (we == 1'b1 && csr_num == `SAVE3) csr_save3 <= wdata; + if (we == 1'b1 && waddr == `SAVE3) csr_save3 <= wdata; +end + +//pgdl +always @(posedge clk) begin + if (we == 1'b1 && waddr == `PGDL) csr_pgdl[`BASE] <= wdata[`BASE]; +end + +//pgdh +always @(posedge clk) begin + if (we == 1'b1 && waddr == `PGDH) csr_pgdh[`BASE] <= wdata[`BASE]; +end + +//tlbidx +always @(posedge clk) begin + if(rst)begin + csr_tlbidx[23:5] <= 19'b0; + csr_tlbidx[30] <= 1'b0; + end + else if (we == 1'b1 && waddr == `TLBIDX) begin + csr_tlbidx[`INDEX] <= wdata[`INDEX]; + csr_tlbidx[`PS] <= wdata[`PS]; + csr_tlbidx[`NE] <= wdata[`NE]; + end + else if (tlbsrch_en) begin + if (tlbsrch_found) begin + csr_tlbidx[`INDEX] <= tlbsrch_index; + csr_tlbidx[`NE] <= 1'b0; + end + else begin + csr_tlbidx[`NE] <= 1'b1; + end + end + else if (tlbrd_en && !tlbidx_in[`NE]) begin + csr_tlbidx[`PS] <= tlbidx_in[`PS]; + csr_tlbidx[`NE] <= tlbidx_in[`NE]; + end + else if (tlbrd_en && tlbidx_in[`NE]) begin + csr_tlbidx[`NE] <= tlbidx_in[`NE]; + end +end + +//tlbehi +always @(posedge clk) begin + if(rst) + csr_tlbehi[12:0] <= 13'b0; + else if(we == 1'b1 && waddr == `TLBEHI) + csr_tlbehi[`VPPN] <= wdata[`VPPN]; + else if(excp_tlb) + csr_tlbehi[`VPPN] <= excp_tlb_vppn; +end + +//tlbelo0 +always @(posedge clk) begin + if(rst) + csr_tlbelo0[7] <= 1'b0; + else if(we == 1'b1 && waddr == `TLBELO0)begin + csr_tlbelo0[`TLB_V] <= wdata[`TLB_V]; + csr_tlbelo0[`TLB_D] <= wdata[`TLB_D]; + csr_tlbelo0[`TLB_PLV] <= wdata[`TLB_PLV]; + csr_tlbelo0[`TLB_MAT] <= wdata[`TLB_MAT]; + csr_tlbelo0[`TLB_G] <= wdata[`TLB_G]; + csr_tlbelo0[`TLB_PPN] <= wdata[`TLB_PPN]; + end + else if (tlbrd_valid_wr_en) begin + csr_tlbelo0[`TLB_V] <= tlbelo0_in[`TLB_V]; + csr_tlbelo0[`TLB_D] <= tlbelo0_in[`TLB_D]; + csr_tlbelo0[`TLB_PLV] <= tlbelo0_in[`TLB_PLV]; + csr_tlbelo0[`TLB_MAT] <= tlbelo0_in[`TLB_MAT]; + csr_tlbelo0[`TLB_G] <= tlbelo0_in[`TLB_G]; + csr_tlbelo0[`TLB_PPN] <= tlbelo0_in[`TLB_PPN]; + end +end + +//tlbelo1 +always @(posedge clk) begin + if(rst) + csr_tlbelo1[7] <= 1'b0; + else if(we == 1'b1 && waddr == `TLBELO1)begin + csr_tlbelo1[`TLB_V] <= wdata[`TLB_V]; + csr_tlbelo1[`TLB_D] <= wdata[`TLB_D]; + csr_tlbelo1[`TLB_PLV] <= wdata[`TLB_PLV]; + csr_tlbelo1[`TLB_MAT] <= wdata[`TLB_MAT]; + csr_tlbelo1[`TLB_G] <= wdata[`TLB_G]; + csr_tlbelo1[`TLB_PPN] <= wdata[`TLB_PPN]; + end + else if (tlbrd_valid_wr_en) begin + csr_tlbelo1[`TLB_V] <= tlbelo1_in[`TLB_V]; + csr_tlbelo1[`TLB_D] <= tlbelo1_in[`TLB_D]; + csr_tlbelo1[`TLB_PLV] <= tlbelo1_in[`TLB_PLV]; + csr_tlbelo1[`TLB_MAT] <= tlbelo1_in[`TLB_MAT]; + csr_tlbelo1[`TLB_G] <= tlbelo1_in[`TLB_G]; + csr_tlbelo1[`TLB_PPN] <= tlbelo1_in[`TLB_PPN]; + end +end + +//asid +always @(posedge clk) begin + if(rst) + csr_asid[31:10] <= 22'h280; + else if(we == 1'b1 && waddr == `ASID) + csr_asid[`TLB_ASID] <= wdata[`TLB_ASID]; + else if(tlbrd_valid_wr_en) + csr_asid[`TLB_ASID] <= asid_in; end //pgdl always @(posedge clk) begin - if (we == 1'b1 && csr_num == `PGDL) csr_pgdl[`BASE] <= wr_data[`BASE]; + if (we == 1'b1 && waddr == `PGDL) begin + csr_pgdl[`BASE] <= wdata[`BASE]; + end end //pgdh always @(posedge clk) begin - if (we == 1'b1 && csr_num == `PGDH) csr_pgdh[`BASE] <= wr_data[`BASE]; + if (we == 1'b1 && waddr == `PGDH) begin + csr_pgdh[`BASE] <= wdata[`BASE]; + end +end + +//llbctl +always @(posedge clk) begin + if (rst) begin + csr_llbctl[`KLO] <= 1'b0; + csr_llbctl[31:3] <= 29'b0; + llbit <= 1'b0; + end + else if (ertn_flush) begin + if (csr_llbctl[`KLO]) begin + csr_llbctl[`KLO] <= 1'b0; + end + else begin + llbit <= 1'b0; + end + end + else if (we == 1'b1 && waddr == `LLBCTL) begin + csr_llbctl[ `KLO] <= wdata[ `KLO]; + if (wdata[`WCLLB] == 1'b1) begin + llbit <= 1'b0; + end + end + else if (llbit_set_i) begin + llbit <= llbit_i; + end +end + +//tlbrentry +always @(posedge clk) begin + if(rst) + csr_tlbrentry[5:0] <= 6'b0; + else if(we == 1'b1 && waddr == `TLBRENTRY) + csr_tlbrentry[`TLBRENTRY] <= wdata[`TLBRENTRY_PA]; +end + + +//dmw0 +always @(posedge clk) begin + if(rst)begin + csr_dmw0[2:1] <= 2'b0; + csr_dmw0[24:6] <= 19'b0; + csr_dmw0[28] <= 1'b0; + end + else if(we == 1'b1 && waddr == `DMW0)begin + csr_dmw0[`PLV0] <= wdata[`PLV0]; + csr_dmw0[`PLV3] <= wdata[`PLV3]; + csr_dmw0[`DMW_MAT] <= wdata[`DMW_MAT]; + csr_dmw0[`PSEG] <= wdata[`PSEG]; + csr_dmw0[`VSEG] <= wdata[`VSEG]; + end end + +//dmw1 +always @(posedge clk) begin + if(rst)begin + csr_dmw1[2:1] <= 2'b0; + csr_dmw1[24:6] <= 19'b0; + csr_dmw1[28] <= 1'b0; + end + else if(we == 1'b1 && waddr == `DMW0)begin + csr_dmw1[`PLV0] <= wdata[`PLV0]; + csr_dmw1[`PLV3] <= wdata[`PLV3]; + csr_dmw1[`DMW_MAT] <= wdata[`DMW_MAT]; + csr_dmw1[`PSEG] <= wdata[`PSEG]; + csr_dmw1[`VSEG] <= wdata[`VSEG]; + end +end + + +//tid +always @(posedge clk) begin + if(rst) + csr_tid <= 32'b0; + else if(we == 1 && waddr == `TID) + csr_tid <= wdata; +end + +//tcfg +always @(posedge clk) begin + if(rst) + csr_tcfg[`EN] <= 1'b0; + else if(we == 1'b1 && waddr == `TCFG)begin + csr_tcfg[`EN] <= wdata[`EN]; + csr_tcfg[`PERIODIC] <= wdata[`PERIODIC]; + csr_tcfg[ `INITVAL] <= wdata[ `INITVAL]; + end +end + +//cntc +always @(posedge clk) begin + if (rst) begin + csr_cntc <= 32'b0; + end + else if (we == 1'b1 && waddr == `CNTC) begin + csr_cntc <= wdata; + end +end + +//tval +always @(posedge clk) begin + if(rst) + csr_ticlr <= 32'b0; +end + +//llbitc +always @(posedge clk) begin + if(rst)begin + csr_llbctl[`KLO] <= 1'b0; + csr_llbctl[31:3] <= 29'b0; + llbit <= 1'b0; + end + else if (ertn_flush) begin + if (csr_llbctl[`KLO]) csr_llbctl[`KLO] <= 1'b0; + else llbit <= 1'b0; + end + else if (we == 1'b1 && waddr == `LLBCTL) begin + csr_llbctl[`KLO] <= wdata[`KLO]; + if (wdata[`WCLLB] == 1'b1)llbit <= 1'b0; + end + else if (llbit_set_i) llbit <= llbit_i; + +end + + endmodule \ No newline at end of file diff --git a/src/vsrc/csr_defines.v b/src/vsrc/csr_defines.v index 8234a79..e46151d 100644 --- a/src/vsrc/csr_defines.v +++ b/src/vsrc/csr_defines.v @@ -76,8 +76,8 @@ `define EENTRY 14'hc `define TLBIDX 14'h10 `define TLBEHI 14'h11 -`define TLBELO014'h12 -`define TLBELO114'h13 +`define TLBELO0 14'h12 +`define TLBELO1 14'h13 `define ASID 14'h18 `define PGDL 14'h19 `define PGDH 14'h1a @@ -94,7 +94,36 @@ `define TICLR 14'h44 `define LLBCTL 14'h60 `define TLBRENTRY 14'h88 +`define TLBRBADV 14'h89 +`define TLBRERA 14'h8a +`define TLBRSAVE 14'h8bb +`define TLBRLO0 14'h8c +`define TLBRLO1 14'h8d +`define TLBREHI 14'h8e +`define TLBRPRMD 14'h8f `define DMW0 14'h180 `define DMW1 14'h181 +`define DMW2 14'h182 +`define DMW3 14'h183 `define BRK 14'h100 -`define DISABLE_CACHE 14'h101 \ No newline at end of file +`define DISABLE_CACHE 14'h101 + +//error code +`define ECODE_INT 6'h0 +`define ECODE_PIL 6'h1 +`define ECODE_PIS 6'h2 +`define ECODE_PIF 6'h3 +`define ECODE_PME 6'h4 +`define ECODE_PPI 6'h7 +`define ECODE_ADEF 6'h8 +`define ECODE_ADEM 6'h8 +`define ECODE_ALE 6'h9 +`define ECODE_SYS 6'hb +`define ECODE_BRK 6'hc +`define ECODE_INE 6'hd +`define ECODE_IPE 6'he +`define ECODE_FPD 6'hf +`define ECODE_TLBR 6'h3f + +`define ESUBCODE_ADEF 9'h0 +`define ESUBCODE_ADEM 9'h1 \ No newline at end of file diff --git a/src/vsrc/ctrl.v b/src/vsrc/ctrl.v index 64af4a5..cfec828 100644 --- a/src/vsrc/ctrl.v +++ b/src/vsrc/ctrl.v @@ -7,9 +7,12 @@ module ctrl ( input wire stallreq_from_id_2, input wire stallreq_from_ex_2, + input wire idle_stallreq, + input wire has_int_stallreq, input wire[1:0] excepttype_i_1, input wire[1:0] excepttype_i_2, + output reg[6:0]stall1, output reg[6:0]stall2, output reg[`RegBus] new_pc, @@ -63,7 +66,9 @@ module ctrl ( begin if (!rst_n) stall1 = 7'b0000000; - else if(stallreq_from_ex_1 == `Stop) + else if(idle_stallreq) + stall1 = 7'b1111111; + else if(stallreq_from_ex_1 == `Stop || has_int_stallreq == `Stop) stall1 = 7'b0011111; else if(stallreq_from_id_1 == `Stop) stall1 = 7'b0011111; @@ -75,7 +80,9 @@ module ctrl ( begin if (!rst_n) stall2 = 7'b0000000; - else if(stallreq_from_ex_2 == `Stop) + else if(idle_stallreq) + stall2 = 7'b1111111; + else if(stallreq_from_ex_2 == `Stop || has_int_stallreq == `Stop) stall2 = 7'b0011111; else if(stallreq_from_id_2 == `Stop) stall2 = 7'b0011111; diff --git a/src/vsrc/if_buffer.v b/src/vsrc/if_buffer.v deleted file mode 100644 index 29d70fc..0000000 --- a/src/vsrc/if_buffer.v +++ /dev/null @@ -1,44 +0,0 @@ -//to keep PC and inst_o corresponding -`include "defines.v" -module if_buffer ( - input wire clk, - input wire rst, - input wire [`InstAddrBus] pc_i, - input wire flush, - input wire stall, - - input wire branch_flag_i, - output reg [`InstAddrBus] pc_o, - output reg pc_valid - ); - - always @(posedge clk) - begin - if(rst) - begin - pc_o <= `ZeroWord; - pc_valid <= `InstInvalid; - end - else if(branch_flag_i == `Branch) - begin - pc_o <= `ZeroWord; - pc_valid <= `InstInvalid; - end - else if(flush == 1'b1) - begin - pc_o <= `ZeroWord; - pc_valid <= `InstInvalid; - end - else if(stall == `Stop) // Stall, hold output - begin - pc_o <= pc_o; - pc_valid <= pc_valid; - end - else - begin - pc_o <= pc_i; - pc_valid <= `InstValid; - end - end - -endmodule diff --git a/src/vsrc/pc_reg.v b/src/vsrc/pc_reg.v index f2849d0..708cb10 100644 --- a/src/vsrc/pc_reg.v +++ b/src/vsrc/pc_reg.v @@ -1,4 +1,5 @@ `include "defines.v" +`include "csr_defines.v" module pc_reg ( input wire clk, input wire rst, @@ -12,17 +13,104 @@ module pc_reg ( input wire[`RegBus] branch_target_address_2, input wire flush, - input wire[`RegBus] new_pc, + input wire excp_flush, + input wire ertn_flush, + input wire excp_tlbrefill, + input wire[`InstAddrBus] new_pc, + input wire idle_flush, + input wire[`InstAddrBus] idle_pc, output reg[`InstAddrBus] pc_1, output reg[`InstAddrBus] pc_2, - output reg ce + output reg ce, + + output wire excp_o, + output wire[3:0]excp_num_o, + + //from csr + input wire csr_pg, + input wire csr_da, + input wire [31:0] csr_dmw0, + input wire [31:0] csr_dmw1, + input wire [1:0] csr_plv, + input wire [1:0] csr_datf, + input wire disable_cache, + input wire [`RegBus] csr_eentry, + input wire [`RegBus] csr_era, + input wire [`RegBus] csr_tlbrentry, + + //from tlb + input wire inst_tlb_found, + input wire inst_tlb_v, + input wire inst_tlb_d, + input wire [1:0]inst_tlb_mat, + input wire [1:0]inst_tlb_plv, + + //to tlb + output wire[31:0]inst_addr, + output wire inst_addr_trans_en, + output wire dmw0_en, + output wire dmw1_en + ); +reg if_valid; +wire if_ready_go; +wire if_allowin; +wire to_if_valid; +wire pif_ready_go; +wire [31:0] seq_pc; +wire [31:0] nextpc; +wire [31:0] real_nextpc; +wire pif_excp_adef; +wire if_excp_tlbr; +wire if_excp_pif; +wire if_excp_ppi; +reg if_excp; +reg if_excp_num; +wire excp; +wire [3:0] excp_num; +wire pif_excp; +wire pif_excp_num; +wire flush_sign; +reg [31:0] inst_rd_buff; +reg inst_buff_enable; +wire da_mode; +wire flush_inst_delay; +wire flush_inst_go_dirt; +wire fetch_btb_target; +reg idle_lock; +wire tlb_excp_lock_pc; +wire if_excp_adef; + + assign inst_addr_trans_en = csr_pg && !csr_da && !dmw0_en && !dmw1_en; + + assign dmw0_en = ((csr_dmw0[`PLV0] && csr_plv == 2'd0) || (csr_dmw0[`PLV3] && csr_plv == 2'd3)) && (pc_1[31:29] == csr_dmw0[`VSEG]); + assign dmw1_en = ((csr_dmw1[`PLV0] && csr_plv == 2'd0) || (csr_dmw1[`PLV3] && csr_plv == 2'd3)) && (pc_2[31:29] == csr_dmw1[`VSEG]); + + + //异常处理 + + //未找到tlb + assign if_excp_tlbr = !inst_tlb_found && inst_addr_trans_en; + //load操作页无效 + assign if_excp_pif = !inst_tlb_v && inst_addr_trans_en; + //页特权不合法 + assign if_excp_ppi = (csr_plv > inst_tlb_plv) && inst_addr_trans_en; + //取指地址错误 + assign if_excp_adef = (pc_1[31] || pc_2[31]) && (csr_plv == 2'd3) && inst_addr_trans_en; + + + assign excp_o = if_excp || if_excp_tlbr || if_excp_pif || if_excp_ppi || if_excp_adef; + assign excp_num_o = {if_excp_ppi, if_excp_pif, if_excp_tlbr, if_excp_num || if_excp_adef}; + + always @(posedge clk) begin if(ce == `ChipDisable) pc_1 <= 32'h1c000000; + else if(idle_flush) + pc_1 = idle_pc; else if(flush == 1'b1) pc_1 <= new_pc; else if(stall1 == `Stop) // Hold output @@ -35,6 +123,12 @@ module pc_reg ( pc_1 <= branch_target_address_1; else if(branch_flag_i_2 == `Branch) pc_1 <= branch_target_address_2; + else if(excp_flush && !excp_tlbrefill) + pc_1 <= csr_eentry; + else if(excp_flush && excp_tlbrefill) + pc_1 <= csr_tlbrentry; + else if(ertn_flush) + pc_1 <= csr_era; else pc_1 <= pc_1 + 32'h8; end @@ -44,6 +138,8 @@ module pc_reg ( begin if(ce == `ChipDisable) pc_2 <= 32'h1c000004; + else if(idle_flush) + pc_2 = idle_pc + 4'h4; else if(flush == 1'b1) pc_2 <= new_pc + 4'h4; else if(stall2 == `Stop) // Hold output @@ -54,8 +150,14 @@ module pc_reg ( begin if(branch_flag_i_1 == `Branch) pc_2 <= branch_target_address_1 + 4'h4; - if(branch_flag_i_2 == `Branch) + else if(branch_flag_i_2 == `Branch) pc_2 <= branch_target_address_2 + 4'h4; + else if(excp_flush && !excp_tlbrefill) + pc_2 <= csr_eentry + 4'h4; + else if(excp_flush && excp_tlbrefill) + pc_2 <= csr_tlbrentry + 4'h4; + else if(ertn_flush) + pc_2 <= csr_era +4'h4; else pc_2 <= pc_2 + 32'h8; end diff --git a/src/vsrc/pipeline/1_fetch/if_buffer.v b/src/vsrc/pipeline/1_fetch/if_buffer.v index 052e01a..76d65a5 100644 --- a/src/vsrc/pipeline/1_fetch/if_buffer.v +++ b/src/vsrc/pipeline/1_fetch/if_buffer.v @@ -6,10 +6,17 @@ module if_buffer ( input wire [`InstAddrBus] pc_i, input wire flush, input wire stall, + input wire excp_flush, + input wire ertn_flush, input wire branch_flag_i, output reg [`InstAddrBus] pc_o, - output reg pc_valid + output reg pc_valid, + + input wire excp_i, + input wire [3:0] excp_num_i, + output reg excp_o, + output reg [3:0] excp_num_o ); always @(posedge clk) @@ -18,26 +25,36 @@ module if_buffer ( begin pc_o <= `ZeroWord; pc_valid <= `InstInvalid; + excp_o <= 1'b0; + excp_num_o <= 4'b0; end else if(branch_flag_i == `Branch) begin pc_o <= `ZeroWord; pc_valid <= `InstInvalid; + excp_o <= 1'b0; + excp_num_o <= 4'b0; end - else if(flush == 1'b1) + else if(flush == 1'b1 || excp_flush == 1'b1 || ertn_flush == 1'b1) begin pc_o <= `ZeroWord; pc_valid <= `InstInvalid; + excp_o <= 1'b0; + excp_num_o <= 4'b0; end else if(stall == `Stop) // Stall, hold output begin pc_o <= pc_o; pc_valid <= pc_valid; + excp_o <= excp_i; + excp_num_o <= excp_num_i; end else begin pc_o <= pc_i; pc_valid <= `InstValid; + excp_o <= excp_i; + excp_num_o <= excp_num_i; end end diff --git a/src/vsrc/pipeline/1_fetch/if_id.v b/src/vsrc/pipeline/1_fetch/if_id.v index 5aab6df..a61aa9e 100644 --- a/src/vsrc/pipeline/1_fetch/if_id.v +++ b/src/vsrc/pipeline/1_fetch/if_id.v @@ -1,4 +1,4 @@ -`include "defines.v" +`include "../../defines.v" module if_id ( input wire clk, input wire rst, @@ -10,7 +10,12 @@ module if_id ( input wire flush, input wire stall, // current stage stall, hold output output reg[`InstAddrBus] id_pc_o, - output reg[`InstBus] id_inst_o + output reg[`InstBus] id_inst_o, + + input wire excp_i, + input wire [3:0] excp_num_i, + output reg excp_o, + output reg [3:0] excp_num_o ); @@ -20,26 +25,36 @@ module if_id ( begin id_pc_o <= `ZeroWord; id_inst_o <= `ZeroWord; + excp_o <= 1'b0; + excp_num_o <= 4'b0; end else if(flush == 1'b1) begin id_pc_o <= `ZeroWord; id_inst_o <= `ZeroWord; + excp_o <= 1'b0; + excp_num_o <= 4'b0; end else if(branch_flag_i || if_inst_valid == `InstInvalid) begin id_pc_o <= `ZeroWord; id_inst_o <= `ZeroWord; + excp_o <= 1'b0; + excp_num_o <= 4'b0; end else if(stall == `Stop) begin id_inst_o <= id_inst_o; id_pc_o <= id_pc_o; + excp_o <= excp_i; + excp_num_o <= excp_num_i; end else begin id_inst_o <= if_inst_i; id_pc_o <= if_pc_i; + excp_o <= excp_i; + excp_num_o <= excp_num_i; end end diff --git a/src/vsrc/pipeline/2_decode/id.v b/src/vsrc/pipeline/2_decode/id.v index ebe9b2f..3b95dac 100644 --- a/src/vsrc/pipeline/2_decode/id.v +++ b/src/vsrc/pipeline/2_decode/id.v @@ -1,10 +1,14 @@ -`include "defines.v" +`timescale 1ns/1ns + +`include "../../defines.v" module id( input wire rst, // <- IF input wire[`InstAddrBus] pc_i, input wire[`InstBus] inst_i, + input wire excp_i, + input wire [3:0]excp_num_i, // <- Regfile input wire[`RegBus] reg1_data_i, @@ -51,16 +55,32 @@ module id( output reg inst_valid, output reg[`InstAddrBus] inst_pc, output wire[`RegBus] inst_o, - output wire[1:0] excepttype_o, output wire[`RegBus] current_inst_address_o, + output reg csr_we, + output reg [13:0] csr_addr_o, + output reg [`RegBus]csr_data_o, + output wire [1:0] excepttype_o, + + output wire excp_o, + output wire[8:0] excp_num_o, + + // <- CSR + input wire has_int, + input wire [`RegBus] csr_data_i, + input wire [1:0] csr_plv, + + // -> CSR + output reg [13:0]csr_read_addr_o, // -> PC output reg branch_flag_o, output reg[`RegBus] branch_target_address_o, output reg[`RegBus] link_addr_o, + output reg[`InstAddrBus] idle_pc, // ->Ctrl - output wire stallreq + output wire stallreq, + output reg idle_stallreq ); wire[5:0] opcode_6 = inst_i[31:26]; @@ -99,6 +119,8 @@ module id( wire pre_inst_is_load; + reg res_from_csr; + assign pre_inst_is_load = (((ex_aluop_i_1 == `EXE_LD_B_OP) || (ex_aluop_i_1 == `EXE_LD_H_OP) || (ex_aluop_i_1 == `EXE_LD_W_OP) || @@ -116,13 +138,21 @@ module id( (ex_aluop_i_2 == `EXE_ST_H_OP) || (ex_aluop_i_2 == `EXE_ST_W_OP)) && (pc_i == pc_i_other + 4)) ? 1'b1 : 1'b0; - reg excepttype_is_syscall; - reg excepttype_is_break; + reg inst_syscall; + reg inst_break; + reg kernel_inst; - assign excepttype_o = {excepttype_is_syscall,excepttype_is_break}; + assign excepttype_o = {inst_syscall,inst_break}; assign current_inst_address_o = pc_i; + assign excp_ine = ~inst_valid; + assign excp_ipe = kernel_inst && (csr_plv == 2'b11); + + assign excp_o = excp_ipe | inst_syscall | inst_break | excp_i | excp_ine | has_int; + assign excp_num_o = {excp_ipe, excp_ine, inst_break, inst_syscall, excp_num_i, has_int}; + + always @(*) begin if(rst == `RstEnable) @@ -165,8 +195,9 @@ module id( branch_flag_o = `NotBranch; branch_target_address_o = `ZeroWord; link_addr_o = `ZeroWord; - excepttype_is_break = `False_v; - excepttype_is_syscall = `False_v; + inst_break = `False_v; + inst_syscall = `False_v; + idle_stallreq = 1'b0; end else begin @@ -183,7 +214,7 @@ module id( branch_flag_o = `NotBranch; branch_target_address_o = `ZeroWord; link_addr_o = `ZeroWord; - + idle_stallreq = 1'b0; case (opcode_1) `EXE_JIRL: begin @@ -465,11 +496,14 @@ module id( `EXE_CSRRD:begin wreg_o = `WriteEnable; aluop_o = `EXE_CSRRD_OP; - reg1_read_o = 1'b0; + reg1_read_o = 1'b1; reg2_read_o = 1'b0; imm = {18'b0,imm_14}; + csr_addr_o = imm_14; reg_waddr_o = op1; inst_valid = `InstValid; + res_from_csr = 1'b1; + kernel_inst = 1'b1; end `EXE_CSRWR:begin wreg_o = `WriteEnable; @@ -477,9 +511,13 @@ module id( reg1_read_o = 1'b1; reg2_read_o = 1'b0; imm = {18'b0,imm_14}; + csr_addr_o = imm_14; + csr_data_o = reg1_data_i; reg1_addr_o = op1; reg_waddr_o = op1; inst_valid = `InstValid; + res_from_csr = 1'b1; + kernel_inst = 1'b1; end default:begin wreg_o = `WriteEnable; @@ -487,8 +525,12 @@ module id( reg1_read_o = 1'b0; reg2_read_o = 1'b0; imm = {18'b0,imm_14}; + csr_addr_o = imm_14; + csr_data_o = reg1_data_i; reg_waddr_o = op1; inst_valid = `InstValid; + res_from_csr = 1'b1; + kernel_inst = 1'b1; end endcase end @@ -502,6 +544,7 @@ module id( reg1_read_o = 1'b0; reg2_read_o = 1'b0; inst_valid = `InstValid; + kernel_inst = 1'b1; end `EXE_TLBRD:begin wreg_o = `WriteDisable; @@ -509,6 +552,7 @@ module id( reg1_read_o = 1'b0; reg2_read_o = 1'b0; inst_valid = `InstValid; + kernel_inst = 1'b1; end `EXE_TLBSRCH:begin wreg_o = `WriteDisable; @@ -516,6 +560,7 @@ module id( reg1_read_o = 1'b0; reg2_read_o = 1'b0; inst_valid = `InstValid; + kernel_inst = 1'b1; end `EXE_TLBWR:begin wreg_o = `WriteDisable; @@ -523,6 +568,7 @@ module id( reg1_read_o = 1'b0; reg2_read_o = 1'b0; inst_valid = `InstValid; + kernel_inst = 1'b1; end `EXE_ERTN:begin wreg_o = `WriteDisable; @@ -530,6 +576,7 @@ module id( reg1_read_o = 1'b0; reg2_read_o = 1'b0; inst_valid = `InstValid; + kernel_inst = 1'b1; end default:begin end @@ -542,7 +589,10 @@ module id( aluop_o = `EXE_IDLE_OP; reg1_read_o = 1'b0; reg2_read_o = 1'b0; + idle_stallreq = 1; + idle_pc = pc_i + 4'h4; inst_valid = `InstValid; + kernel_inst = 1'b1; end `EXE_INVTLB:begin wreg_o = `WriteDisable; @@ -550,6 +600,7 @@ module id( reg1_read_o = 1'b0; reg2_read_o = 1'b0; inst_valid = `InstValid; + kernel_inst = 1'b1; end default: begin end @@ -831,7 +882,7 @@ module id( reg1_read_o = 1'b0; reg2_read_o = 1'b0; inst_valid = `InstValid; - excepttype_is_break = `True_v; + inst_break = `True_v; end `EXE_SYSCALL: begin @@ -841,7 +892,7 @@ module id( reg1_read_o = 1'b0; reg2_read_o = 1'b0; inst_valid = `InstValid; - excepttype_is_syscall = `True_v; + inst_syscall = `True_v; end default: begin @@ -906,6 +957,8 @@ module id( begin if (rst == `RstEnable) reg1_o = `ZeroWord; + else if(opcode_2 == `EXE_CSR_RELATED) + reg1_o = csr_data_i; else if ((reg1_read_o == 1'b1) && (reg1_addr_o == 0)) reg1_o = `ZeroWord; else if((reg1_read_o == 1'b1) && (ex_wreg_i_2 == 1'b1) && (ex_waddr_i_2 == reg1_addr_o)) @@ -928,6 +981,8 @@ module id( begin if (rst == `RstEnable) reg2_o = `ZeroWord; + else if(opcode_2 == `EXE_CSR_RELATED) + reg2_o = `ZeroWord; else if ((reg2_read_o == 1'b1) && (reg2_addr_o == 0)) reg2_o = `ZeroWord; else if((reg2_read_o == 1'b1) && (ex_wreg_i_2 == 1'b1) && (ex_waddr_i_2 == reg2_addr_o)) diff --git a/src/vsrc/pipeline/2_decode/id_ex.v b/src/vsrc/pipeline/2_decode/id_ex.v index a56151d..b8f2952 100644 --- a/src/vsrc/pipeline/2_decode/id_ex.v +++ b/src/vsrc/pipeline/2_decode/id_ex.v @@ -1,8 +1,10 @@ -`include "defines.v" +`include "../../defines.v" module id_ex ( input wire clk, input wire rst, input wire stall, + input wire excp_flush, + input wire ertn_flush, input wire[`AluOpBus] id_aluop, input wire[`AluSelBus] id_alusel, @@ -17,6 +19,9 @@ module id_ex ( input wire flush, input wire[1:0] id_excepttype, input wire[`RegBus] id_current_inst_address, + input wire id_csr_we, + input wire[13:0] id_csr_addr, + input wire[`RegBus] id_csr_data, output reg[`AluOpBus] ex_aluop, output reg[`AluSelBus] ex_alusel, @@ -30,6 +35,9 @@ module id_ex ( output reg[`RegBus] ex_inst, output reg[1:0]ex_excepttype, output reg[`RegBus] ex_current_inst_address, + output reg ex_csr_we, + output reg[13:0] ex_csr_addr, + output reg[`RegBus] ex_csr_data, input wire[`RegAddrBus] reg1_addr_i, input wire[`RegAddrBus] reg2_addr_i, @@ -37,9 +45,14 @@ module id_ex ( input wire[`RegAddrBus] reg1_addr_i_other, input wire[`RegAddrBus] reg2_addr_i_other, input wire[`RegAddrBus] waddr_i_other, - + input stallreq_from_id, - output reg stallreq + output reg stallreq, + + input wire excp_i, + input wire[8:0] excp_num_i, + output reg excp_o, + output reg[8:0] excp_num_o ); @@ -68,8 +81,13 @@ module id_ex ( ex_inst <= `ZeroWord; ex_excepttype <= 2'b00; ex_current_inst_address <= `ZeroWord; + ex_csr_we <= 1'b0; + ex_csr_addr <= 14'b0; + ex_csr_data <= `ZeroWord; + excp_o <= 1'b0; + excp_num_o <= 9'b0; end - else if(flush == 1'b1) + else if(flush == 1'b1 || excp_flush == 1'b1 || ertn_flush == 1'b1) begin ex_aluop <= `EXE_NOP_OP; ex_alusel <= `EXE_RES_NOP; @@ -83,6 +101,11 @@ module id_ex ( ex_inst <= `ZeroWord; ex_excepttype <= 2'b00; ex_current_inst_address <= `ZeroWord; + ex_csr_we <= 1'b0; + ex_csr_addr <= 14'b0; + ex_csr_data <= `ZeroWord; + excp_o <= 1'b0; + excp_num_o <= 9'b0; end else if(stall == `Stop || stallreq == `Stop) begin @@ -102,6 +125,11 @@ module id_ex ( ex_inst <= id_inst; ex_excepttype <= id_excepttype; ex_current_inst_address <= id_current_inst_address; + ex_csr_we <= id_csr_we; + ex_csr_addr <= id_csr_addr; + ex_csr_data <= id_csr_data; + excp_o <= excp_i; + excp_num_o <= excp_num_i; end end diff --git a/src/vsrc/pipeline/3_execution/ex.v b/src/vsrc/pipeline/3_execution/ex.v index 57045e2..bed3dde 100644 --- a/src/vsrc/pipeline/3_execution/ex.v +++ b/src/vsrc/pipeline/3_execution/ex.v @@ -1,4 +1,4 @@ -`include "defines.v" +`include "../../defines.v" module ex ( input wire rst, @@ -15,6 +15,11 @@ module ex ( input wire[`RegBus] link_addr_i, input wire[1:0] excepttype_i, input wire[`RegBus] current_inst_address_i, + input wire ex_csr_we_i, + input wire [13:0]ex_csr_addr_i, + input wire [`RegBus]ex_csr_data_i, + + input wire[18:0] csr_vppn, output reg[`RegAddrBus] wd_o, output reg wreg_o, @@ -26,8 +31,16 @@ module ex ( output wire[`RegBus] reg2_o, output wire[1:0] excepttype_o, output wire[`RegBus] current_inst_address_o, + output wire ex_csr_we_o, + output wire [13:0]ex_csr_addr_o, + output wire [`RegBus]ex_csr_data_o, + + output wire stallreq, - output wire stallreq + input wire excp_i, + input wire [8:0] excp_num_i, + output wire excp_o, + output wire [9:0] excp_num_o ); reg[`RegBus] logicout; @@ -42,6 +55,13 @@ module ex ( assign excepttype_o = excepttype_i; assign current_inst_address_o = current_inst_address_i; + assign ex_csr_we_o = ex_csr_we_i; + assign ex_csr_addr_o = ex_csr_addr_i; + assign ex_csr_data_o = ex_csr_data_i; + + assign excp_o = excp_i || 1'b0; + assign excp_num_o = {1'b0, excp_num_i}; + always @(*) begin if(rst == `RstEnable) diff --git a/src/vsrc/pipeline/3_execution/ex_mem.v b/src/vsrc/pipeline/3_execution/ex_mem.v index a23ce64..14ca363 100644 --- a/src/vsrc/pipeline/3_execution/ex_mem.v +++ b/src/vsrc/pipeline/3_execution/ex_mem.v @@ -1,9 +1,11 @@ -`include "defines.v" +`include "../../defines.v" module ex_mem ( input wire clk, input wire rst, input wire stall, + input wire excp_flush, + input wire ertn_flush, input wire[`RegAddrBus] ex_wd, input wire ex_wreg, @@ -16,6 +18,11 @@ module ex_mem ( input wire flush, input wire[1:0] ex_excepttype, input wire[`RegBus] ex_current_inst_address, + input wire ex_csr_we, + input wire [13:0]ex_csr_addr, + input wire [`RegBus]ex_csr_data, + input wire excp_i, + input wire [9:0] excp_num_i, output reg[`RegAddrBus] mem_wd, output reg mem_wreg, @@ -26,7 +33,12 @@ module ex_mem ( output reg[`RegBus] mem_mem_addr, output reg[`RegBus] mem_reg2, output reg[1:0] mem_excepttype, - output reg[`RegBus] mem_current_inst_address + output reg[`RegBus] mem_current_inst_address, + output reg mem_csr_we, + output reg[13:0] mem_csr_addr, + output reg[`RegBus] mem_csr_data, + output reg excp_o, + output reg [9:0] excp_num_o ); always @ (posedge clk) @@ -43,8 +55,13 @@ module ex_mem ( mem_reg2 <= `ZeroWord; mem_excepttype <= 2'b00; mem_current_inst_address <= `ZeroWord; + mem_csr_we <= 1'b1; + mem_csr_addr <= 14'b0; + mem_csr_data <= `ZeroWord; + excp_o <= 1'b0; + excp_num_o <= 10'b0; end - else if(flush == 1'b1) + else if(flush == 1'b1 || excp_flush == 1'b1 || ertn_flush == 1'b1) begin mem_wd <= `NOPRegAddr; mem_wreg <= `WriteDisable; @@ -56,6 +73,11 @@ module ex_mem ( mem_reg2 <= `ZeroWord; mem_excepttype <= 2'b00; mem_current_inst_address <= `ZeroWord; + mem_csr_we <= 1'b1; + mem_csr_addr <= 14'b0; + mem_csr_data <= `ZeroWord; + excp_o <= 1'b0; + excp_num_o <= 10'b0; end else if(stall == `Stop) begin @@ -72,6 +94,11 @@ module ex_mem ( mem_reg2 <= ex_reg2; mem_excepttype <= ex_excepttype; mem_current_inst_address <= ex_current_inst_address; + mem_csr_we <= ex_csr_we; + mem_csr_addr <= ex_csr_addr; + mem_csr_data <= ex_csr_data; + excp_o <= excp_i; + excp_num_o <= excp_num_i; end end diff --git a/src/vsrc/pipeline/4_mem/mem.v b/src/vsrc/pipeline/4_mem/mem.v index d59cb47..e2c7f84 100644 --- a/src/vsrc/pipeline/4_mem/mem.v +++ b/src/vsrc/pipeline/4_mem/mem.v @@ -1,4 +1,7 @@ -`include "defines.v" +`timescale 1ns/1ns + +`include "../../defines.v" +`include "../../csr_defines.v" module mem ( input wire rst, @@ -20,10 +23,41 @@ module mem ( input wire[1:0] excepttype_i, input wire[`RegBus] current_inst_address_i, + input wire mem_csr_we_i, + input wire[13:0] mem_csr_addr_i, + input wire[`RegBus] mem_csr_data_i, + + input wire excp_i, + input wire [9:0] excp_num_i, + + //from csr + input wire csr_pg, + input wire csr_da, + input wire [31:0]csr_dmw0, + input wire [31:0]csr_dmw1, + input wire [1:0]csr_plv, + input wire [1:0]csr_datf, + input wire disable_cache, + + //to addr trans + output wire data_addr_trans_en, + output wire dmw0_en, + output wire dmw1_en, + output wire cacop_op_mode_di, + + //tlb + input wire data_tlb_found, + input wire [4:0]data_tlb_index, + input wire data_tlb_v, + input wire data_tlb_d, + input wire [1:0] data_tlb_mat, + input wire [1:0] data_tlb_plv, + output reg[`InstAddrBus] inst_pc_o, output reg[`RegAddrBus] wd_o, output reg wreg_o, output reg[`RegBus] wdata_o, + output reg[`AluOpBus] aluop_o, output reg[`RegBus] mem_addr_o, output wire mem_we_o, @@ -35,17 +69,64 @@ module mem ( output reg LLbit_value_o, output wire[1:0] excepttype_o, - output wire[`RegBus] current_inst_address_o + output wire[`RegBus] current_inst_address_o, + + output wire mem_csr_we_o, + output wire[13:0] mem_csr_addr_o, + output wire[`RegBus] mem_csr_data_o, + + output wire excp_o, + output wire[15:0] excp_num_o ); reg mem_we; reg LLbit; + wire access_mem; + wire mem_store_op; + wire mem_load_op; + wire excp_adem; + wire pg_mode; + wire da_mode; + wire excp_tlbr; + wire excp_pil; + wire excp_pis; + wire excp_pme; + wire excp_ppi; + + assign access_mem = mem_load_op || mem_store_op; + + assign mem_load_op = aluop_i == `EXE_LD_B_OP || aluop_i == `EXE_LD_BU_OP || aluop_i == `EXE_LD_H_OP || aluop_i == `EXE_LD_HU_OP || + aluop_i == `EXE_LD_W_OP || aluop_i == `EXE_LL_OP; + + assign mem_store_op = aluop_i == `EXE_ST_B_OP || aluop_i == `EXE_ST_H_OP || aluop_i == `EXE_ST_W_OP || aluop_i == `EXE_SC_OP; assign mem_we_o = mem_we & (~(|excepttype_i)); assign excepttype_o = excepttype_i; assign current_inst_address_o = current_inst_address_i; + assign mem_csr_we_o = mem_csr_we_i; + assign mem_csr_addr_o = mem_csr_we_o; + assign mem_csr_data_o = mem_csr_data_i; + + //addr dmw trans + assign dmw0_en = ((csr_dmw0[`PLV0] && csr_plv == 2'd0) || (csr_dmw0[`PLV3] && csr_plv == 2'd3)) && (wdata_i[31:29] == csr_dmw0[`VSEG]); + assign dmw1_en = ((csr_dmw1[`PLV0] && csr_plv == 2'd0) || (csr_dmw1[`PLV3] && csr_plv == 2'd3)) && (wdata_i[31:29] == csr_dmw1[`VSEG]); + + assign pg_mode = !csr_da && csr_pg; + assign da_mode = csr_da && !csr_pg; + + assign data_addr_trans_en = pg_mode && !dmw0_en && !dmw1_en && !cacop_op_mode_di; + + assign excp_tlbr = access_mem && !data_tlb_found && data_addr_trans_en; + assign excp_pil = mem_load_op && !data_tlb_v && data_addr_trans_en; //cache will generate pil exception?? + assign excp_pis = mem_store_op && !data_tlb_v && data_addr_trans_en; + assign excp_ppi = access_mem && data_tlb_v && (csr_plv > data_tlb_plv) && data_addr_trans_en; + assign excp_pme = mem_store_op && data_tlb_v && (csr_plv <= data_tlb_plv) && !data_tlb_d && data_addr_trans_en; + + assign excp_o = excp_tlbr || excp_pil || excp_pis || excp_ppi || excp_pme || excp_adem || excp_i; + assign excp_num_o = {excp_pil, excp_pis, excp_ppi, excp_pme, excp_tlbr, excp_adem, excp_num_i}; + always @(*) begin if(rst == `RstEnable) diff --git a/src/vsrc/pipeline/4_mem/mem_wb.v b/src/vsrc/pipeline/4_mem/mem_wb.v index 17196d4..9a06760 100644 --- a/src/vsrc/pipeline/4_mem/mem_wb.v +++ b/src/vsrc/pipeline/4_mem/mem_wb.v @@ -1,4 +1,5 @@ -`include "defines.v" +`include "../../csr_defines.v" +`include "../../defines.v" module mem_wb ( input wire clk, @@ -10,6 +11,7 @@ module mem_wb ( input wire[`RegBus] mem_wdata, input wire[`InstAddrBus] mem_inst_pc, input wire[`InstBus] mem_instr, + input wire[`AluOpBus] mem_aluop, input wire mem_inst_valid, input wire mem_LLbit_we, @@ -17,22 +19,92 @@ module mem_wb ( input wire flush, + input wire [15:0] excp_num, + + input wire mem_csr_we, + input wire[13:0] mem_csr_addr, + input wire[`RegBus] mem_csr_data, + output reg[`RegAddrBus] wb_wd, output reg wb_wreg, output reg[`RegBus] wb_wdata, + output reg wb_csr_we, + output reg[13:0] wb_csr_addr, + output reg[`RegBus] wb_csr_data, + output reg[`InstAddrBus] debug_commit_pc, output reg debug_commit_valid, output reg[`InstBus] debug_commit_instr, output reg wb_LLbit_we, - output reg wb_LLbit_value + output reg wb_LLbit_value, + + input wire excp_i, + input wire[15:0] excp_num_i, + output reg excp_o, + output reg[15:0] excp_num_o, + + //to csr + output wire[31:0] csr_era, + output wire[8:0] csr_esubcode, + output wire[5:0] csr_ecode, + output wire excp_flush, + output wire ertn_flush, + output wire va_error, + output wire[31:0] bad_va, + output wire excp_tlbrefill, + output wire excp_tlb, + output wire[18:0] excp_tlb_vppn ); reg debug_commit_valid_0; reg debug_commit_valid_1; reg [`InstBus] debug_commit_pc_0; + reg wb_valid; + + assign csr_era = mem_inst_pc; + assign excp_flush = excp_i; + assign ertn_flush = mem_instr == `EXE_ERTN_OP; + + + assign csr_ecode = excp_num[0] ? `ECODE_INT : excp_num[1] ? `ECODE_ADEF : excp_num[2] ? `ECODE_TLBR : excp_num[3] ? `ECODE_PIF : + excp_num[4] ? `ECODE_PPI : excp_num[5] ? `ECODE_SYS :excp_num[6] ? `ECODE_BRK : excp_num[7] ? `ECODE_INE : + excp_num[8] ? `ECODE_IPE :excp_num[9] ? `ECODE_ALE : excp_num[10] ? `ECODE_ADEM : excp_num[11] ? `ECODE_TLBR : + excp_num[12] ? `ECODE_PME :excp_num[13] ? `ECODE_PPI : excp_num[14] ? `ECODE_PIS :excp_num[15] ? `ECODE_PIL : 6'b0 ; + + assign va_error = excp_num[0] ? 1'b0 : excp_num[1] ? wb_valid : excp_num[2] ? wb_valid : excp_num[3] ? wb_valid : + excp_num[4] ? wb_valid : excp_num[5] ? 1'b0 :excp_num[6] ? 1'b0 : excp_num[7] ? 1'b0 : + excp_num[8] ? 1'b0 :excp_num[9] ? wb_valid : excp_num[10] ? wb_valid : excp_num[11] ? wb_valid : + excp_num[12] ? wb_valid :excp_num[13] ? wb_valid : excp_num[14] ? wb_valid :excp_num[15] ? wb_valid : 1'b0 ; + + assign bad_va = excp_num[0] ? 32'b0 : excp_num[1] ? mem_inst_pc : excp_num[2] ? mem_inst_pc : excp_num[3] ? mem_inst_pc : + excp_num[4] ? mem_inst_pc : excp_num[5] ? 32'b0 :excp_num[6] ? 32'b0 : excp_num[7] ? 32'b0 : + excp_num[8] ? 32'b0 :excp_num[9] ? wb_wdata : excp_num[10] ? wb_wdata : excp_num[11] ? wb_wdata : + excp_num[12] ? wb_wdata :excp_num[13] ? wb_wdata : excp_num[14] ? wb_wdata :excp_num[15] ? wb_wdata : 32'b0 ; + + assign csr_esubcode = excp_num[0] ? 9'b0 : excp_num[1] ? `ESUBCODE_ADEF : excp_num[2] ? 9'b0 : excp_num[3] ? 9'b0 : + excp_num[4] ? 9'b0 : excp_num[5] ? 9'b0 :excp_num[6] ? 9'b0 : excp_num[7] ? 9'b0 : + excp_num[8] ? 9'b0 :excp_num[9] ? 9'b0 : excp_num[10] ? `ESUBCODE_ADEM : excp_num[11] ? 9'b0 : + excp_num[12] ? 9'b0 :excp_num[13] ? 9'b0 : excp_num[14] ? 9'b0 :excp_num[15] ? 9'b0 : 9'b0 ; + + assign csr_esubcode = excp_num[0] ? 1'b0 : excp_num[1] ? 1'b0 : excp_num[2] ? wb_valid : excp_num[3] ? 1'b0 : + excp_num[4] ? 1'b0 : excp_num[5] ? 1'b0 :excp_num[6] ? 1'b0 : excp_num[7] ? 1'b0 : + excp_num[8] ? 1'b0 :excp_num[9] ? 1'b0 : excp_num[10] ? 1'b0 : excp_num[11] ? wb_valid : + excp_num[12] ? 1'b0 :excp_num[13] ? 1'b0 : excp_num[14] ? 1'b0 :excp_num[15] ? 1'b0 : 1'b0 ; + + assign excp_tlb = excp_num[0] ? 1'b0 : excp_num[1] ? 1'b0 : excp_num[2] ? wb_valid : excp_num[3] ? wb_valid : + excp_num[4] ? wb_valid : excp_num[5] ? 1'b0 :excp_num[6] ? 1'b0 : excp_num[7] ? 1'b0 : + excp_num[8] ? 1'b0 :excp_num[9] ? 1'b0 : excp_num[10] ? 1'b0 : excp_num[11] ? wb_valid : + excp_num[12] ? wb_valid :excp_num[13] ? wb_valid : excp_num[14] ? wb_valid :excp_num[15] ? wb_valid : 1'b0 ; + + assign excp_tlb_vppn = excp_num[0] ? 19'b0 : excp_num[1] ? 19'b0 : excp_num[2] ? mem_inst_pc[31:13] : excp_num[3] ? mem_inst_pc[31:13] : + excp_num[4] ? mem_inst_pc[31:13] : excp_num[5] ? 19'b0 :excp_num[6] ? 19'b0 : excp_num[7] ? 19'b0 : + excp_num[8] ? 19'b0 :excp_num[9] ? 19'b0 : excp_num[10] ? 19'b0 : excp_num[11] ? wb_wdata[31:13] : + excp_num[12] ? wb_wdata[31:13] :excp_num[13] ? wb_wdata[31:13] : excp_num[14] ? wb_wdata[31:13] :excp_num[15] ? wb_wdata[31:13] : 1'b0 ; + + always @ (posedge clk) begin if (rst == `RstEnable) @@ -40,19 +112,27 @@ module mem_wb ( wb_wd <= `NOPRegAddr; wb_wreg <= `WriteDisable; wb_wdata <= `ZeroWord; + wb_valid <= 1'b0; wb_LLbit_we <= 1'b0; wb_LLbit_value <= 1'b0; + wb_csr_we <= 1'b0; + wb_csr_addr <= 14'b0; + wb_csr_data <= `ZeroWord; debug_commit_instr <= `ZeroWord; debug_commit_pc <= `ZeroWord; debug_commit_valid <= `InstInvalid; end - else if(flush == 1'b1) + else if(flush == 1'b1 || excp_i == 1'b1 || mem_instr == `EXE_ERTN_OP) begin wb_wd <= `NOPRegAddr; wb_wreg <= `WriteDisable; wb_wdata <= `ZeroWord; + wb_valid <= 1'b0; wb_LLbit_we <= 1'b0; wb_LLbit_value <= 1'b0; + wb_csr_we <= 1'b0; + wb_csr_addr <= 14'b0; + wb_csr_data <= `ZeroWord; debug_commit_instr <= `ZeroWord; debug_commit_pc <= `ZeroWord; debug_commit_valid <= `InstInvalid; @@ -68,8 +148,12 @@ module mem_wb ( wb_wd <= mem_wd; wb_wreg <= mem_wreg; wb_wdata <= mem_wdata; + wb_valid <= 1'b1; wb_LLbit_we <= mem_LLbit_we; wb_LLbit_value <= mem_LLbit_value; + wb_csr_we <= mem_csr_we; + wb_csr_addr <= mem_csr_addr; + wb_csr_data <= mem_csr_data; debug_commit_pc <= mem_inst_pc; // debug_commit_pc <= debug_commit_pc_0; debug_commit_valid <= ~mem_inst_valid; @@ -79,4 +163,5 @@ module mem_wb ( end end -endmodule + + endmodule diff --git a/src/vsrc/tlb.v b/src/vsrc/tlb.v index 4c1a0ea..1607935 100644 --- a/src/vsrc/tlb.v +++ b/src/vsrc/tlb.v @@ -1,19 +1,245 @@ `include "defines.v" +`include "csr_defines.v" + module tlb #( - parameter TLBNum = 32; -)( - input wire clk, - input wire rst, - - input wire[] asid, - - input wire inst_en, - input wire data_en, - - input wire inst_match, - input wire inst_vaddr, - input + parameter TLBNUM = 32 +) +( + input wire clk , + input wire [ 9:0] asid , + //trans mode + input wire inst_addr_trans_en , + input wire data_addr_trans_en , + //inst addr trans + input wire inst_fetch , + input wire [31:0] inst_vaddr , + input wire inst_dmw0_en , + input wire inst_dmw1_en , + output wire [ 7:0] inst_index , + output wire [19:0] inst_tag , + output wire [ 3:0] inst_offset , + output wire inst_tlb_found , + output wire inst_tlb_v , + output wire inst_tlb_d , + output wire [ 1:0] inst_tlb_mat , + output wire [ 1:0] inst_tlb_plv , + //data addr trans + input wire data_fetch , + input wire [31:0] data_vaddr , + input wire data_dmw0_en , + input wire data_dmw1_en , + input wire cacop_op_mode_di , + output wire [ 7:0] data_index , + output wire [19:0] data_tag , + output wire [ 3:0] data_offset , + output wire data_tlb_found , + output wire [ 4:0] data_tlb_index , + output wire data_tlb_v , + output wire data_tlb_d , + output wire [ 1:0] data_tlb_mat , + output wire [ 1:0] data_tlb_plv , + //tlbwi tlbwr tlb write + input wire tlbfill_en , + input wire tlbwr_en , + input wire [ 4:0] rand_index , + input wire [31:0] tlbehi_in , + input wire [31:0] tlbelo0_in , + input wire [31:0] tlbelo1_in , + input wire [31:0] tlbidx_in , + input wire [ 5:0] ecode_in , + //tlbr tlb read + output wire [31:0] tlbehi_out , + output wire [31:0] tlbelo0_out , + output wire [31:0] tlbelo1_out , + output wire [31:0] tlbidx_out , + output wire [ 9:0] asid_out , + //invtlb + input wire invtlb_en , + input wire [ 9:0] invtlb_asid , + input wire [18:0] invtlb_vpn , + input wire [ 4:0] invtlb_op , + //from csr + input wire [31:0] csr_dmw0 , + input wire [31:0] csr_dmw1 , + input wire csr_da , + input wire csr_pg +); + +wire [18:0] s0_vppn ; +wire s0_odd_page ; +wire [ 5:0] s0_ps ; +wire [19:0] s0_ppn ; + +wire [18:0] s1_vppn ; +wire s1_odd_page ; +wire [ 5:0] s1_ps ; +wire [19:0] s1_ppn ; + +wire we ; +wire [ 4:0] w_index ; +wire [18:0] w_vppn ; +wire w_g ; +wire [ 5:0] w_ps ; +wire w_e ; +wire w_v0 ; +wire w_d0 ; +wire [ 1:0] w_mat0 ; +wire [ 1:0] w_plv0 ; +wire [19:0] w_ppn0 ; +wire w_v1 ; +wire w_d1 ; +wire [ 1:0] w_mat1 ; +wire [ 1:0] w_plv1 ; +wire [19:0] w_ppn1 ; + +wire [ 4:0] r_index ; +wire [18:0] r_vppn ; +wire [ 9:0] r_asid ; +wire r_g ; +wire [ 5:0] r_ps ; +wire r_e ; +wire r_v0 ; +wire r_d0 ; +wire [ 1:0] r_mat0 ; +wire [ 1:0] r_plv0 ; +wire [19:0] r_ppn0 ; +wire r_v1 ; +wire r_d1 ; +wire [ 1:0] r_mat1 ; +wire [ 1:0] r_plv1 ; +wire [19:0] r_ppn1 ; + +reg [31:0] inst_vaddr_buffer ; +reg [31:0] data_vaddr_buffer ; +wire [31:0] inst_paddr; +wire [31:0] data_paddr; + +wire pg_mode; +wire da_mode; + +always @(posedge clk) begin + inst_vaddr_buffer <= inst_vaddr; + data_vaddr_buffer <= data_vaddr; +end + +//trans search port sig +assign s0_vppn = inst_vaddr[31:13]; +assign s0_odd_page = inst_vaddr[12]; + +assign s1_vppn = data_vaddr[31:13]; +assign s1_odd_page = data_vaddr[12]; + +//trans write port sig +assign we = tlbfill_en || tlbwr_en; +assign w_index = ({5{tlbfill_en}} & rand_index) | ({5{tlbwr_en}} & tlbidx_in[`INDEX]); +assign w_vppn = tlbehi_in[`VPPN]; +assign w_g = tlbelo0_in[`TLB_G] && tlbelo1_in[`TLB_G]; +assign w_ps = tlbidx_in[`PS]; +assign w_e = (ecode_in == 6'h3f) ? 1'b1 : !tlbidx_in[`NE]; +assign w_v0 = tlbelo0_in[`TLB_V]; +assign w_d0 = tlbelo0_in[`TLB_D]; +assign w_plv0 = tlbelo0_in[`TLB_PLV]; +assign w_mat0 = tlbelo0_in[`TLB_MAT]; +assign w_ppn0 = tlbelo0_in[`TLB_PPN_EN]; +assign w_v1 = tlbelo1_in[`TLB_V]; +assign w_d1 = tlbelo1_in[`TLB_D]; +assign w_plv1 = tlbelo1_in[`TLB_PLV]; +assign w_mat1 = tlbelo1_in[`TLB_MAT]; +assign w_ppn1 = tlbelo1_in[`TLB_PPN_EN]; + +//trans read port sig +assign r_index = tlbidx_in[`INDEX]; +assign tlbehi_out = {r_vppn, 13'b0}; +assign tlbelo0_out = {4'b0, r_ppn0, 1'b0, r_g, r_mat0, r_plv0, r_d0, r_v0}; +assign tlbelo1_out = {4'b0, r_ppn1, 1'b0, r_g, r_mat1, r_plv1, r_d1, r_v1}; +assign tlbidx_out = {!r_e, 1'b0, r_ps, 24'b0}; //note do not write index +assign asid_out = r_asid; + +tlb_entry tlb_entry( + .clk (clk ), + // search port 0 + .s0_fetch (inst_fetch ), + .s0_vppn (s0_vppn ), + .s0_odd_page (s0_odd_page ), + .s0_asid (asid ), + .s0_found (inst_tlb_found ), + .s0_index (), + .s0_ps (s0_ps ), + .s0_ppn (s0_ppn ), + .s0_v (inst_tlb_v ), + .s0_d (inst_tlb_d ), + .s0_mat (inst_tlb_mat ), + .s0_plv (inst_tlb_plv ), + // search port 1 + .s1_fetch (data_fetch ), + .s1_vppn (s1_vppn ), + .s1_odd_page (s1_odd_page ), + .s1_asid (asid ), + .s1_found (data_tlb_found ), + .s1_index (data_tlb_index ), + .s1_ps (s1_ps ), + .s1_ppn (s1_ppn ), + .s1_v (data_tlb_v ), + .s1_d (data_tlb_d ), + .s1_mat (data_tlb_mat ), + .s1_plv (data_tlb_plv ), + // write port + .we (we ), + .w_index (w_index ), + .w_vppn (w_vppn ), + .w_asid (asid ), + .w_g (w_g ), + .w_ps (w_ps ), + .w_e (w_e ), + .w_v0 (w_v0 ), + .w_d0 (w_d0 ), + .w_plv0 (w_plv0 ), + .w_mat0 (w_mat0 ), + .w_ppn0 (w_ppn0 ), + .w_v1 (w_v1 ), + .w_d1 (w_d1 ), + .w_plv1 (w_plv1 ), + .w_mat1 (w_mat1 ), + .w_ppn1 (w_ppn1 ), + //read port + .r_index (r_index ), + .r_vppn (r_vppn ), + .r_asid (r_asid ), + .r_g (r_g ), + .r_ps (r_ps ), + .r_e (r_e ), + .r_v0 (r_v0 ), + .r_d0 (r_d0 ), + .r_mat0 (r_mat0 ), + .r_plv0 (r_plv0 ), + .r_ppn0 (r_ppn0 ), + .r_v1 (r_v1 ), + .r_d1 (r_d1 ), + .r_mat1 (r_mat1 ), + .r_plv1 (r_plv1 ), + .r_ppn1 (r_ppn1 ), + //invalid port + .inv_en (invtlb_en ), + .inv_op (invtlb_op ), + .inv_asid (invtlb_asid ), + .inv_vpn (invtlb_vpn ) ); +assign pg_mode = !csr_da && csr_pg; +assign da_mode = csr_da && !csr_pg; + +assign inst_paddr = (pg_mode && inst_dmw0_en) ? {csr_dmw0[`PSEG], inst_vaddr_buffer[28:0]} : + (pg_mode && inst_dmw1_en) ? {csr_dmw1[`PSEG], inst_vaddr_buffer[28:0]} : inst_vaddr_buffer; + +assign inst_offset = inst_vaddr[3:0]; +assign inst_index = inst_vaddr[11:4]; +assign inst_tag = inst_addr_trans_en ? ((s0_ps == 6'd12) ? s0_ppn : {s0_ppn[19:10], inst_paddr[21:12]}) : inst_paddr[31:12]; + +assign data_paddr = (pg_mode && data_dmw0_en && !cacop_op_mode_di) ? {csr_dmw0[`PSEG], data_vaddr_buffer[28:0]} : + (pg_mode && data_dmw1_en && !cacop_op_mode_di) ? {csr_dmw1[`PSEG], data_vaddr_buffer[28:0]} : data_vaddr_buffer; + +assign data_offset = data_vaddr[3:0]; +assign data_index = data_vaddr[11:4]; +assign data_tag = data_addr_trans_en ? ((s1_ps == 6'd12) ? s1_ppn : {s1_ppn[19:10], data_paddr[21:12]}) : data_paddr[31:12]; endmodule \ No newline at end of file diff --git a/src/vsrc/tlb_entry.v b/src/vsrc/tlb_entry.v index 3c5b201..e7eb61b 100644 --- a/src/vsrc/tlb_entry.v +++ b/src/vsrc/tlb_entry.v @@ -1,96 +1,326 @@ -module tlb_entry +module tlb_entry #( - parameter TLBNum = 32; - parameter EntryLen = 88:0; - parameter TLB_e = 0; - parameter TLB_asid = 10:1; - parameter TLB_g = 11; - parameter TLB_ps = 17:12; - parameter TLB_vppn = 36:18; - parameter TLB_v0 = 37; - parameter TLB_d0 = 38; - parameter TLB_mat0 = 40:39; - parameter TLB_plv0 = 42:41; - parameter TLB_ppn0 = 62:43; - parameter TLB_v1 = 63; - parameter TLB_d1 = 64; - parameter TLB_mat1 = 66:65; - parameter TLB_plv1 = 68:67; - parameter TLB_ppn1 = 88:69; + parameter TLBNUM = 32 ) ( - input wire clk, - input wire rst, + input clk, + // search port 0 + input s0_fetch , + input [18:0] s0_vppn , + input s0_odd_page , + input [ 9:0] s0_asid , + output s0_found , + output [$clog2(TLBNUM)-1:0] s0_index , + output [ 5:0] s0_ps , + output [19:0] s0_ppn , + output s0_v , + output s0_d , + output [ 1:0] s0_mat , + output [ 1:0] s0_plv , + //search port 1 + input s1_fetch , + input [18:0] s1_vppn , + input s1_odd_page , + input [ 9:0] s1_asid , + output s1_found , + output [$clog2(TLBNUM)-1:0] s1_index , + output [ 5:0] s1_ps , + output [19:0] s1_ppn , + output s1_v , + output s1_d , + output [ 1:0] s1_mat , + output [ 1:0] s1_plv , + // write port + input we , + input [$clog2(TLBNUM)-1:0] w_index , + input [18:0] w_vppn , + input [ 9:0] w_asid , + input w_g , + input [ 5:0] w_ps , + input w_e , + input w_v0 , + input w_d0 , + input [ 1:0] w_mat0 , + input [ 1:0] w_plv0 , + input [19:0] w_ppn0 , + input w_v1 , + input w_d1 , + input [ 1:0] w_mat1 , + input [ 1:0] w_plv1 , + input [19:0] w_ppn1 , + // read port + input [$clog2(TLBNUM)-1:0] r_index , + output [18:0] r_vppn , + output [ 9:0] r_asid , + output r_g , + output [ 5:0] r_ps , + output r_e , + output r_v0 , + output r_d0 , + output [ 1:0] r_mat0 , + output [ 1:0] r_plv0 , + output [19:0] r_ppn0 , + output r_v1 , + output r_d1 , + output [ 1:0] r_mat1 , + output [ 1:0] r_plv1 , + output [19:0] r_ppn1 , + // invalid port + input inv_en , + input [ 4:0] inv_op , + input [ 9:0] inv_asid , + input [18:0] inv_vpn +); - input wire s0_match, - input wire [18:0] s0_vppn, - input wire s0_odd_page, - input wire [9:0]s0_asid, - - output reg s0_found, - output reg[$clog2(TLBNUM)-1:0] s0_index , - output reg[5:0] s0_ps, - output reg[19:0] s0_ppn, - output reg s0_v, - output reg s0_d, - output reg[1:0] s0_mat, - output reg[1:0] s0_plv, +reg [18:0] tlb_vppn [TLBNUM-1:0]; +reg tlb_e [TLBNUM-1:0]; +reg [ 9:0] tlb_asid [TLBNUM-1:0]; +reg tlb_g [TLBNUM-1:0]; +reg [ 5:0] tlb_ps [TLBNUM-1:0]; +reg [19:0] tlb_ppn0 [TLBNUM-1:0]; +reg [ 1:0] tlb_plv0 [TLBNUM-1:0]; +reg [ 1:0] tlb_mat0 [TLBNUM-1:0]; +reg tlb_d0 [TLBNUM-1:0]; +reg tlb_v0 [TLBNUM-1:0]; +reg [19:0] tlb_ppn1 [TLBNUM-1:0]; +reg [ 1:0] tlb_plv1 [TLBNUM-1:0]; +reg [ 1:0] tlb_mat1 [TLBNUM-1:0]; +reg tlb_d1 [TLBNUM-1:0]; +reg tlb_v1 [TLBNUM-1:0]; - input wire s1_match, - input wire [18:0] s1_vppn, - input wire s1_odd_page, - input wire [9:0]s1_asid, - - output reg s1_found, - output reg[$clog2(TLBNUM)-1:0] s1_index , - output reg[5:0] s1_ps, - output reg[19:0] s1_ppn, - output reg s1_v, - output reg s1_d, - output reg[1:0] s1_mat, - output reg[1:0] s1_plv, +reg [TLBNUM-1:0] match0; +reg [TLBNUM-1:0] match1; - input wire we, - input wire[$clog2(TLBNUM)-1:0] w_index, - input wire[18:0] w_vppn, - input wire[ 9:0] w_asid, - input wire w_g , - input wire [5:0]w_ps, - input wire w_e, - input wire w_v0, - input wire w_d0, - input wire [1:0] w_mat0, - input wire [1:0] w_plv0, - input wire [19:0] w_ppn0, - input wire w_v1, - input wire w_d1, - input wire [1:0] w_mat1, - input wire [1:0] w_plv1, - input wire [19:0] w_ppn1, +reg [TLBNUM-1:0] s0_odd_page_buffer; +reg [TLBNUM-1:0] s1_odd_page_buffer; - input wire[$clog2(TLBNUM)-1:0] r_index, - output wire[18:0] r_vppn, - output wire[ 9:0] r_asid, - output wire r_g , - output wire[5:0] r_ps, - output wire r_e, - output wire r_v0, - output wire r_d0, - output wire[1:0]r_mat0, - output wire[1:0]r_plv0, - output wire[19:0]r_ppn0, - output wire r_v1, - output wire r_d1, - output wire[1:0] r_mat1, - output wire[1:0] r_plv1 , - output wire[19:0] r_ppn1, +genvar i; +generate + for (i = 0; i < TLBNUM; i = i + 1) + begin: match + always @(posedge clk) begin + if (s0_fetch) begin + s0_odd_page_buffer[i] <= (tlb_ps[i] == 6'd12) ? s0_odd_page : s0_vppn[9]; + match0[i] <= (tlb_e[i] == 1'b1) && ((tlb_ps[i] == 6'd12) ? s0_vppn == tlb_vppn[i] : s0_vppn[18:10] == tlb_vppn[i][18:10]) && ((s0_asid == tlb_asid[i]) || tlb_g[i]); + end + if (s1_fetch) begin + s1_odd_page_buffer[i] <= (tlb_ps[i] == 6'd12) ? s1_odd_page : s1_vppn[9]; + match1[i] <= (tlb_e[i] == 1'b1) && ((tlb_ps[i] == 6'd12) ? s1_vppn == tlb_vppn[i] : s1_vppn[18:10] == tlb_vppn[i][18:10]) && ((s1_asid == tlb_asid[i]) || tlb_g[i]); + end + end + end +endgenerate - input wire inv_en, - input wire[ 4:0] inv_op, - input wire[ 9:0] inv_asid, - input wire[18:0] inv_vpn -); +assign s0_found = !(!match0); +assign s1_found = !(!match1); + +assign {s0_index, s0_ps, s0_ppn, s0_v, s0_d, s0_mat, s0_plv} = {37{match0[0] & s0_odd_page_buffer[0] }} & {5'd0, tlb_ps[0], tlb_ppn1[0], tlb_v1[0], tlb_d1[0], tlb_mat1[0], tlb_plv1[0]} | + {37{match0[1] & s0_odd_page_buffer[1] }} & {5'd1, tlb_ps[1], tlb_ppn1[1], tlb_v1[1], tlb_d1[1], tlb_mat1[1], tlb_plv1[1]} | + {37{match0[2] & s0_odd_page_buffer[2] }} & {5'd2, tlb_ps[2], tlb_ppn1[2], tlb_v1[2], tlb_d1[2], tlb_mat1[2], tlb_plv1[2]} | + {37{match0[3] & s0_odd_page_buffer[3] }} & {5'd3, tlb_ps[3], tlb_ppn1[3], tlb_v1[3], tlb_d1[3], tlb_mat1[3], tlb_plv1[3]} | + {37{match0[4] & s0_odd_page_buffer[4] }} & {5'd4, tlb_ps[4], tlb_ppn1[4], tlb_v1[4], tlb_d1[4], tlb_mat1[4], tlb_plv1[4]} | + {37{match0[5] & s0_odd_page_buffer[5] }} & {5'd5, tlb_ps[5], tlb_ppn1[5], tlb_v1[5], tlb_d1[5], tlb_mat1[5], tlb_plv1[5]} | + {37{match0[6] & s0_odd_page_buffer[6] }} & {5'd6, tlb_ps[6], tlb_ppn1[6], tlb_v1[6], tlb_d1[6], tlb_mat1[6], tlb_plv1[6]} | + {37{match0[7] & s0_odd_page_buffer[7] }} & {5'd7, tlb_ps[7], tlb_ppn1[7], tlb_v1[7], tlb_d1[7], tlb_mat1[7], tlb_plv1[7]} | + {37{match0[8] & s0_odd_page_buffer[8] }} & {5'd8, tlb_ps[8], tlb_ppn1[8], tlb_v1[8], tlb_d1[8], tlb_mat1[8], tlb_plv1[8]} | + {37{match0[9] & s0_odd_page_buffer[9] }} & {5'd9, tlb_ps[9], tlb_ppn1[9], tlb_v1[9], tlb_d1[9], tlb_mat1[9], tlb_plv1[9]} | + {37{match0[10] & s0_odd_page_buffer[10]}} & {5'd10, tlb_ps[10], tlb_ppn1[10], tlb_v1[10], tlb_d1[10], tlb_mat1[10], tlb_plv1[10]} | + {37{match0[11] & s0_odd_page_buffer[11]}} & {5'd11, tlb_ps[11], tlb_ppn1[11], tlb_v1[11], tlb_d1[11], tlb_mat1[11], tlb_plv1[11]} | + {37{match0[12] & s0_odd_page_buffer[12]}} & {5'd12, tlb_ps[12], tlb_ppn1[12], tlb_v1[12], tlb_d1[12], tlb_mat1[12], tlb_plv1[12]} | + {37{match0[13] & s0_odd_page_buffer[13]}} & {5'd13, tlb_ps[13], tlb_ppn1[13], tlb_v1[13], tlb_d1[13], tlb_mat1[13], tlb_plv1[13]} | + {37{match0[14] & s0_odd_page_buffer[14]}} & {5'd14, tlb_ps[14], tlb_ppn1[14], tlb_v1[14], tlb_d1[14], tlb_mat1[14], tlb_plv1[14]} | + {37{match0[15] & s0_odd_page_buffer[15]}} & {5'd15, tlb_ps[15], tlb_ppn1[15], tlb_v1[15], tlb_d1[15], tlb_mat1[15], tlb_plv1[15]} | + {37{match0[16] & s0_odd_page_buffer[16]}} & {5'd16, tlb_ps[16], tlb_ppn1[16], tlb_v1[16], tlb_d1[16], tlb_mat1[16], tlb_plv1[16]} | + {37{match0[17] & s0_odd_page_buffer[17]}} & {5'd17, tlb_ps[17], tlb_ppn1[17], tlb_v1[17], tlb_d1[17], tlb_mat1[17], tlb_plv1[17]} | + {37{match0[18] & s0_odd_page_buffer[18]}} & {5'd18, tlb_ps[18], tlb_ppn1[18], tlb_v1[18], tlb_d1[18], tlb_mat1[18], tlb_plv1[18]} | + {37{match0[19] & s0_odd_page_buffer[19]}} & {5'd19, tlb_ps[19], tlb_ppn1[19], tlb_v1[19], tlb_d1[19], tlb_mat1[19], tlb_plv1[19]} | + {37{match0[20] & s0_odd_page_buffer[20]}} & {5'd20, tlb_ps[20], tlb_ppn1[20], tlb_v1[20], tlb_d1[20], tlb_mat1[20], tlb_plv1[20]} | + {37{match0[21] & s0_odd_page_buffer[21]}} & {5'd21, tlb_ps[21], tlb_ppn1[21], tlb_v1[21], tlb_d1[21], tlb_mat1[21], tlb_plv1[21]} | + {37{match0[22] & s0_odd_page_buffer[22]}} & {5'd22, tlb_ps[22], tlb_ppn1[22], tlb_v1[22], tlb_d1[22], tlb_mat1[22], tlb_plv1[22]} | + {37{match0[23] & s0_odd_page_buffer[23]}} & {5'd23, tlb_ps[23], tlb_ppn1[23], tlb_v1[23], tlb_d1[23], tlb_mat1[23], tlb_plv1[23]} | + {37{match0[24] & s0_odd_page_buffer[24]}} & {5'd24, tlb_ps[24], tlb_ppn1[24], tlb_v1[24], tlb_d1[24], tlb_mat1[24], tlb_plv1[24]} | + {37{match0[25] & s0_odd_page_buffer[25]}} & {5'd25, tlb_ps[25], tlb_ppn1[25], tlb_v1[25], tlb_d1[25], tlb_mat1[25], tlb_plv1[25]} | + {37{match0[26] & s0_odd_page_buffer[26]}} & {5'd26, tlb_ps[26], tlb_ppn1[26], tlb_v1[26], tlb_d1[26], tlb_mat1[26], tlb_plv1[26]} | + {37{match0[27] & s0_odd_page_buffer[27]}} & {5'd27, tlb_ps[27], tlb_ppn1[27], tlb_v1[27], tlb_d1[27], tlb_mat1[27], tlb_plv1[27]} | + {37{match0[28] & s0_odd_page_buffer[28]}} & {5'd28, tlb_ps[28], tlb_ppn1[28], tlb_v1[28], tlb_d1[28], tlb_mat1[28], tlb_plv1[28]} | + {37{match0[29] & s0_odd_page_buffer[29]}} & {5'd29, tlb_ps[29], tlb_ppn1[29], tlb_v1[29], tlb_d1[29], tlb_mat1[29], tlb_plv1[29]} | + {37{match0[30] & s0_odd_page_buffer[30]}} & {5'd30, tlb_ps[30], tlb_ppn1[30], tlb_v1[30], tlb_d1[30], tlb_mat1[30], tlb_plv1[30]} | + {37{match0[31] & s0_odd_page_buffer[31]}} & {5'd31, tlb_ps[31], tlb_ppn1[31], tlb_v1[31], tlb_d1[31], tlb_mat1[31], tlb_plv1[31]} | + {37{match0[0] & ~s0_odd_page_buffer[0] }} & {5'd0, tlb_ps[0], tlb_ppn0[0], tlb_v0[0], tlb_d0[0], tlb_mat0[0], tlb_plv0[0]} | + {37{match0[1] & ~s0_odd_page_buffer[1] }} & {5'd1, tlb_ps[1], tlb_ppn0[1], tlb_v0[1], tlb_d0[1], tlb_mat0[1], tlb_plv0[1]} | + {37{match0[2] & ~s0_odd_page_buffer[2] }} & {5'd2, tlb_ps[2], tlb_ppn0[2], tlb_v0[2], tlb_d0[2], tlb_mat0[2], tlb_plv0[2]} | + {37{match0[3] & ~s0_odd_page_buffer[3] }} & {5'd3, tlb_ps[3], tlb_ppn0[3], tlb_v0[3], tlb_d0[3], tlb_mat0[3], tlb_plv0[3]} | + {37{match0[4] & ~s0_odd_page_buffer[4] }} & {5'd4, tlb_ps[4], tlb_ppn0[4], tlb_v0[4], tlb_d0[4], tlb_mat0[4], tlb_plv0[4]} | + {37{match0[5] & ~s0_odd_page_buffer[5] }} & {5'd5, tlb_ps[5], tlb_ppn0[5], tlb_v0[5], tlb_d0[5], tlb_mat0[5], tlb_plv0[5]} | + {37{match0[6] & ~s0_odd_page_buffer[6] }} & {5'd6, tlb_ps[6], tlb_ppn0[6], tlb_v0[6], tlb_d0[6], tlb_mat0[6], tlb_plv0[6]} | + {37{match0[7] & ~s0_odd_page_buffer[7] }} & {5'd7, tlb_ps[7], tlb_ppn0[7], tlb_v0[7], tlb_d0[7], tlb_mat0[7], tlb_plv0[7]} | + {37{match0[8] & ~s0_odd_page_buffer[8] }} & {5'd8, tlb_ps[8], tlb_ppn0[8], tlb_v0[8], tlb_d0[8], tlb_mat0[8], tlb_plv0[8]} | + {37{match0[9] & ~s0_odd_page_buffer[9] }} & {5'd9, tlb_ps[9], tlb_ppn0[9], tlb_v0[9], tlb_d0[9], tlb_mat0[9], tlb_plv0[9]} | + {37{match0[10] & ~s0_odd_page_buffer[10]}} & {5'd10, tlb_ps[10], tlb_ppn0[10], tlb_v0[10], tlb_d0[10], tlb_mat0[10], tlb_plv0[10]} | + {37{match0[11] & ~s0_odd_page_buffer[11]}} & {5'd11, tlb_ps[11], tlb_ppn0[11], tlb_v0[11], tlb_d0[11], tlb_mat0[11], tlb_plv0[11]} | + {37{match0[12] & ~s0_odd_page_buffer[12]}} & {5'd12, tlb_ps[12], tlb_ppn0[12], tlb_v0[12], tlb_d0[12], tlb_mat0[12], tlb_plv0[12]} | + {37{match0[13] & ~s0_odd_page_buffer[13]}} & {5'd13, tlb_ps[13], tlb_ppn0[13], tlb_v0[13], tlb_d0[13], tlb_mat0[13], tlb_plv0[13]} | + {37{match0[14] & ~s0_odd_page_buffer[14]}} & {5'd14, tlb_ps[14], tlb_ppn0[14], tlb_v0[14], tlb_d0[14], tlb_mat0[14], tlb_plv0[14]} | + {37{match0[15] & ~s0_odd_page_buffer[15]}} & {5'd15, tlb_ps[15], tlb_ppn0[15], tlb_v0[15], tlb_d0[15], tlb_mat0[15], tlb_plv0[15]} | + {37{match0[16] & ~s0_odd_page_buffer[16]}} & {5'd16, tlb_ps[16], tlb_ppn0[16], tlb_v0[16], tlb_d0[16], tlb_mat0[16], tlb_plv0[16]} | + {37{match0[17] & ~s0_odd_page_buffer[17]}} & {5'd17, tlb_ps[17], tlb_ppn0[17], tlb_v0[17], tlb_d0[17], tlb_mat0[17], tlb_plv0[17]} | + {37{match0[18] & ~s0_odd_page_buffer[18]}} & {5'd18, tlb_ps[18], tlb_ppn0[18], tlb_v0[18], tlb_d0[18], tlb_mat0[18], tlb_plv0[18]} | + {37{match0[19] & ~s0_odd_page_buffer[19]}} & {5'd19, tlb_ps[19], tlb_ppn0[19], tlb_v0[19], tlb_d0[19], tlb_mat0[19], tlb_plv0[19]} | + {37{match0[20] & ~s0_odd_page_buffer[20]}} & {5'd20, tlb_ps[20], tlb_ppn0[20], tlb_v0[20], tlb_d0[20], tlb_mat0[20], tlb_plv0[20]} | + {37{match0[21] & ~s0_odd_page_buffer[21]}} & {5'd21, tlb_ps[21], tlb_ppn0[21], tlb_v0[21], tlb_d0[21], tlb_mat0[21], tlb_plv0[21]} | + {37{match0[22] & ~s0_odd_page_buffer[22]}} & {5'd22, tlb_ps[22], tlb_ppn0[22], tlb_v0[22], tlb_d0[22], tlb_mat0[22], tlb_plv0[22]} | + {37{match0[23] & ~s0_odd_page_buffer[23]}} & {5'd23, tlb_ps[23], tlb_ppn0[23], tlb_v0[23], tlb_d0[23], tlb_mat0[23], tlb_plv0[23]} | + {37{match0[24] & ~s0_odd_page_buffer[24]}} & {5'd24, tlb_ps[24], tlb_ppn0[24], tlb_v0[24], tlb_d0[24], tlb_mat0[24], tlb_plv0[24]} | + {37{match0[25] & ~s0_odd_page_buffer[25]}} & {5'd25, tlb_ps[25], tlb_ppn0[25], tlb_v0[25], tlb_d0[25], tlb_mat0[25], tlb_plv0[25]} | + {37{match0[26] & ~s0_odd_page_buffer[26]}} & {5'd26, tlb_ps[26], tlb_ppn0[26], tlb_v0[26], tlb_d0[26], tlb_mat0[26], tlb_plv0[26]} | + {37{match0[27] & ~s0_odd_page_buffer[27]}} & {5'd27, tlb_ps[27], tlb_ppn0[27], tlb_v0[27], tlb_d0[27], tlb_mat0[27], tlb_plv0[27]} | + {37{match0[28] & ~s0_odd_page_buffer[28]}} & {5'd28, tlb_ps[28], tlb_ppn0[28], tlb_v0[28], tlb_d0[28], tlb_mat0[28], tlb_plv0[28]} | + {37{match0[29] & ~s0_odd_page_buffer[29]}} & {5'd29, tlb_ps[29], tlb_ppn0[29], tlb_v0[29], tlb_d0[29], tlb_mat0[29], tlb_plv0[29]} | + {37{match0[30] & ~s0_odd_page_buffer[30]}} & {5'd30, tlb_ps[30], tlb_ppn0[30], tlb_v0[30], tlb_d0[30], tlb_mat0[30], tlb_plv0[30]} | + {37{match0[31] & ~s0_odd_page_buffer[31]}} & {5'd31, tlb_ps[31], tlb_ppn0[31], tlb_v0[31], tlb_d0[31], tlb_mat0[31], tlb_plv0[31]} ; + +assign {s1_index, s1_ps, s1_ppn, s1_v, s1_d, s1_mat, s1_plv} = {37{match1[0] & s1_odd_page_buffer[0] }} & {5'd0, tlb_ps[0], tlb_ppn1[0], tlb_v1[0], tlb_d1[0], tlb_mat1[0], tlb_plv1[0]} | + {37{match1[1] & s1_odd_page_buffer[1] }} & {5'd1, tlb_ps[1], tlb_ppn1[1], tlb_v1[1], tlb_d1[1], tlb_mat1[1], tlb_plv1[1]} | + {37{match1[2] & s1_odd_page_buffer[2] }} & {5'd2, tlb_ps[2], tlb_ppn1[2], tlb_v1[2], tlb_d1[2], tlb_mat1[2], tlb_plv1[2]} | + {37{match1[3] & s1_odd_page_buffer[3] }} & {5'd3, tlb_ps[3], tlb_ppn1[3], tlb_v1[3], tlb_d1[3], tlb_mat1[3], tlb_plv1[3]} | + {37{match1[4] & s1_odd_page_buffer[4] }} & {5'd4, tlb_ps[4], tlb_ppn1[4], tlb_v1[4], tlb_d1[4], tlb_mat1[4], tlb_plv1[4]} | + {37{match1[5] & s1_odd_page_buffer[5] }} & {5'd5, tlb_ps[5], tlb_ppn1[5], tlb_v1[5], tlb_d1[5], tlb_mat1[5], tlb_plv1[5]} | + {37{match1[6] & s1_odd_page_buffer[6] }} & {5'd6, tlb_ps[6], tlb_ppn1[6], tlb_v1[6], tlb_d1[6], tlb_mat1[6], tlb_plv1[6]} | + {37{match1[7] & s1_odd_page_buffer[7] }} & {5'd7, tlb_ps[7], tlb_ppn1[7], tlb_v1[7], tlb_d1[7], tlb_mat1[7], tlb_plv1[7]} | + {37{match1[8] & s1_odd_page_buffer[8] }} & {5'd8, tlb_ps[8], tlb_ppn1[8], tlb_v1[8], tlb_d1[8], tlb_mat1[8], tlb_plv1[8]} | + {37{match1[9] & s1_odd_page_buffer[9] }} & {5'd9, tlb_ps[9], tlb_ppn1[9], tlb_v1[9], tlb_d1[9], tlb_mat1[9], tlb_plv1[9]} | + {37{match1[10] & s1_odd_page_buffer[10]}} & {5'd10, tlb_ps[10], tlb_ppn1[10], tlb_v1[10], tlb_d1[10], tlb_mat1[10], tlb_plv1[10]} | + {37{match1[11] & s1_odd_page_buffer[11]}} & {5'd11, tlb_ps[11], tlb_ppn1[11], tlb_v1[11], tlb_d1[11], tlb_mat1[11], tlb_plv1[11]} | + {37{match1[12] & s1_odd_page_buffer[12]}} & {5'd12, tlb_ps[12], tlb_ppn1[12], tlb_v1[12], tlb_d1[12], tlb_mat1[12], tlb_plv1[12]} | + {37{match1[13] & s1_odd_page_buffer[13]}} & {5'd13, tlb_ps[13], tlb_ppn1[13], tlb_v1[13], tlb_d1[13], tlb_mat1[13], tlb_plv1[13]} | + {37{match1[14] & s1_odd_page_buffer[14]}} & {5'd14, tlb_ps[14], tlb_ppn1[14], tlb_v1[14], tlb_d1[14], tlb_mat1[14], tlb_plv1[14]} | + {37{match1[15] & s1_odd_page_buffer[15]}} & {5'd15, tlb_ps[15], tlb_ppn1[15], tlb_v1[15], tlb_d1[15], tlb_mat1[15], tlb_plv1[15]} | + {37{match1[16] & s1_odd_page_buffer[16]}} & {5'd16, tlb_ps[16], tlb_ppn1[16], tlb_v1[16], tlb_d1[16], tlb_mat1[16], tlb_plv1[16]} | + {37{match1[17] & s1_odd_page_buffer[17]}} & {5'd17, tlb_ps[17], tlb_ppn1[17], tlb_v1[17], tlb_d1[17], tlb_mat1[17], tlb_plv1[17]} | + {37{match1[18] & s1_odd_page_buffer[18]}} & {5'd18, tlb_ps[18], tlb_ppn1[18], tlb_v1[18], tlb_d1[18], tlb_mat1[18], tlb_plv1[18]} | + {37{match1[19] & s1_odd_page_buffer[19]}} & {5'd19, tlb_ps[19], tlb_ppn1[19], tlb_v1[19], tlb_d1[19], tlb_mat1[19], tlb_plv1[19]} | + {37{match1[20] & s1_odd_page_buffer[20]}} & {5'd20, tlb_ps[20], tlb_ppn1[20], tlb_v1[20], tlb_d1[20], tlb_mat1[20], tlb_plv1[20]} | + {37{match1[21] & s1_odd_page_buffer[21]}} & {5'd21, tlb_ps[21], tlb_ppn1[21], tlb_v1[21], tlb_d1[21], tlb_mat1[21], tlb_plv1[21]} | + {37{match1[22] & s1_odd_page_buffer[22]}} & {5'd22, tlb_ps[22], tlb_ppn1[22], tlb_v1[22], tlb_d1[22], tlb_mat1[22], tlb_plv1[22]} | + {37{match1[23] & s1_odd_page_buffer[23]}} & {5'd23, tlb_ps[23], tlb_ppn1[23], tlb_v1[23], tlb_d1[23], tlb_mat1[23], tlb_plv1[23]} | + {37{match1[24] & s1_odd_page_buffer[24]}} & {5'd24, tlb_ps[24], tlb_ppn1[24], tlb_v1[24], tlb_d1[24], tlb_mat1[24], tlb_plv1[24]} | + {37{match1[25] & s1_odd_page_buffer[25]}} & {5'd25, tlb_ps[25], tlb_ppn1[25], tlb_v1[25], tlb_d1[25], tlb_mat1[25], tlb_plv1[25]} | + {37{match1[26] & s1_odd_page_buffer[26]}} & {5'd26, tlb_ps[26], tlb_ppn1[26], tlb_v1[26], tlb_d1[26], tlb_mat1[26], tlb_plv1[26]} | + {37{match1[27] & s1_odd_page_buffer[27]}} & {5'd27, tlb_ps[27], tlb_ppn1[27], tlb_v1[27], tlb_d1[27], tlb_mat1[27], tlb_plv1[27]} | + {37{match1[28] & s1_odd_page_buffer[28]}} & {5'd28, tlb_ps[28], tlb_ppn1[28], tlb_v1[28], tlb_d1[28], tlb_mat1[28], tlb_plv1[28]} | + {37{match1[29] & s1_odd_page_buffer[29]}} & {5'd29, tlb_ps[29], tlb_ppn1[29], tlb_v1[29], tlb_d1[29], tlb_mat1[29], tlb_plv1[29]} | + {37{match1[30] & s1_odd_page_buffer[30]}} & {5'd30, tlb_ps[30], tlb_ppn1[30], tlb_v1[30], tlb_d1[30], tlb_mat1[30], tlb_plv1[30]} | + {37{match1[31] & s1_odd_page_buffer[31]}} & {5'd31, tlb_ps[31], tlb_ppn1[31], tlb_v1[31], tlb_d1[31], tlb_mat1[31], tlb_plv1[31]} | + {37{match1[0] & ~s1_odd_page_buffer[0] }} & {5'd0, tlb_ps[0], tlb_ppn0[0], tlb_v0[0], tlb_d0[0], tlb_mat0[0], tlb_plv0[0]} | + {37{match1[1] & ~s1_odd_page_buffer[1] }} & {5'd1, tlb_ps[1], tlb_ppn0[1], tlb_v0[1], tlb_d0[1], tlb_mat0[1], tlb_plv0[1]} | + {37{match1[2] & ~s1_odd_page_buffer[2] }} & {5'd2, tlb_ps[2], tlb_ppn0[2], tlb_v0[2], tlb_d0[2], tlb_mat0[2], tlb_plv0[2]} | + {37{match1[3] & ~s1_odd_page_buffer[3] }} & {5'd3, tlb_ps[3], tlb_ppn0[3], tlb_v0[3], tlb_d0[3], tlb_mat0[3], tlb_plv0[3]} | + {37{match1[4] & ~s1_odd_page_buffer[4] }} & {5'd4, tlb_ps[4], tlb_ppn0[4], tlb_v0[4], tlb_d0[4], tlb_mat0[4], tlb_plv0[4]} | + {37{match1[5] & ~s1_odd_page_buffer[5] }} & {5'd5, tlb_ps[5], tlb_ppn0[5], tlb_v0[5], tlb_d0[5], tlb_mat0[5], tlb_plv0[5]} | + {37{match1[6] & ~s1_odd_page_buffer[6] }} & {5'd6, tlb_ps[6], tlb_ppn0[6], tlb_v0[6], tlb_d0[6], tlb_mat0[6], tlb_plv0[6]} | + {37{match1[7] & ~s1_odd_page_buffer[7] }} & {5'd7, tlb_ps[7], tlb_ppn0[7], tlb_v0[7], tlb_d0[7], tlb_mat0[7], tlb_plv0[7]} | + {37{match1[8] & ~s1_odd_page_buffer[8] }} & {5'd8, tlb_ps[8], tlb_ppn0[8], tlb_v0[8], tlb_d0[8], tlb_mat0[8], tlb_plv0[8]} | + {37{match1[9] & ~s1_odd_page_buffer[9] }} & {5'd9, tlb_ps[9], tlb_ppn0[9], tlb_v0[9], tlb_d0[9], tlb_mat0[9], tlb_plv0[9]} | + {37{match1[10] & ~s1_odd_page_buffer[10]}} & {5'd10, tlb_ps[10], tlb_ppn0[10], tlb_v0[10], tlb_d0[10], tlb_mat0[10], tlb_plv0[10]} | + {37{match1[11] & ~s1_odd_page_buffer[11]}} & {5'd11, tlb_ps[11], tlb_ppn0[11], tlb_v0[11], tlb_d0[11], tlb_mat0[11], tlb_plv0[11]} | + {37{match1[12] & ~s1_odd_page_buffer[12]}} & {5'd12, tlb_ps[12], tlb_ppn0[12], tlb_v0[12], tlb_d0[12], tlb_mat0[12], tlb_plv0[12]} | + {37{match1[13] & ~s1_odd_page_buffer[13]}} & {5'd13, tlb_ps[13], tlb_ppn0[13], tlb_v0[13], tlb_d0[13], tlb_mat0[13], tlb_plv0[13]} | + {37{match1[14] & ~s1_odd_page_buffer[14]}} & {5'd14, tlb_ps[14], tlb_ppn0[14], tlb_v0[14], tlb_d0[14], tlb_mat0[14], tlb_plv0[14]} | + {37{match1[15] & ~s1_odd_page_buffer[15]}} & {5'd15, tlb_ps[15], tlb_ppn0[15], tlb_v0[15], tlb_d0[15], tlb_mat0[15], tlb_plv0[15]} | + {37{match1[16] & ~s1_odd_page_buffer[16]}} & {5'd16, tlb_ps[16], tlb_ppn0[16], tlb_v0[16], tlb_d0[16], tlb_mat0[16], tlb_plv0[16]} | + {37{match1[17] & ~s1_odd_page_buffer[17]}} & {5'd17, tlb_ps[17], tlb_ppn0[17], tlb_v0[17], tlb_d0[17], tlb_mat0[17], tlb_plv0[17]} | + {37{match1[18] & ~s1_odd_page_buffer[18]}} & {5'd18, tlb_ps[18], tlb_ppn0[18], tlb_v0[18], tlb_d0[18], tlb_mat0[18], tlb_plv0[18]} | + {37{match1[19] & ~s1_odd_page_buffer[19]}} & {5'd19, tlb_ps[19], tlb_ppn0[19], tlb_v0[19], tlb_d0[19], tlb_mat0[19], tlb_plv0[19]} | + {37{match1[20] & ~s1_odd_page_buffer[20]}} & {5'd20, tlb_ps[20], tlb_ppn0[20], tlb_v0[20], tlb_d0[20], tlb_mat0[20], tlb_plv0[20]} | + {37{match1[21] & ~s1_odd_page_buffer[21]}} & {5'd21, tlb_ps[21], tlb_ppn0[21], tlb_v0[21], tlb_d0[21], tlb_mat0[21], tlb_plv0[21]} | + {37{match1[22] & ~s1_odd_page_buffer[22]}} & {5'd22, tlb_ps[22], tlb_ppn0[22], tlb_v0[22], tlb_d0[22], tlb_mat0[22], tlb_plv0[22]} | + {37{match1[23] & ~s1_odd_page_buffer[23]}} & {5'd23, tlb_ps[23], tlb_ppn0[23], tlb_v0[23], tlb_d0[23], tlb_mat0[23], tlb_plv0[23]} | + {37{match1[24] & ~s1_odd_page_buffer[24]}} & {5'd24, tlb_ps[24], tlb_ppn0[24], tlb_v0[24], tlb_d0[24], tlb_mat0[24], tlb_plv0[24]} | + {37{match1[25] & ~s1_odd_page_buffer[25]}} & {5'd25, tlb_ps[25], tlb_ppn0[25], tlb_v0[25], tlb_d0[25], tlb_mat0[25], tlb_plv0[25]} | + {37{match1[26] & ~s1_odd_page_buffer[26]}} & {5'd26, tlb_ps[26], tlb_ppn0[26], tlb_v0[26], tlb_d0[26], tlb_mat0[26], tlb_plv0[26]} | + {37{match1[27] & ~s1_odd_page_buffer[27]}} & {5'd27, tlb_ps[27], tlb_ppn0[27], tlb_v0[27], tlb_d0[27], tlb_mat0[27], tlb_plv0[27]} | + {37{match1[28] & ~s1_odd_page_buffer[28]}} & {5'd28, tlb_ps[28], tlb_ppn0[28], tlb_v0[28], tlb_d0[28], tlb_mat0[28], tlb_plv0[28]} | + {37{match1[29] & ~s1_odd_page_buffer[29]}} & {5'd29, tlb_ps[29], tlb_ppn0[29], tlb_v0[29], tlb_d0[29], tlb_mat0[29], tlb_plv0[29]} | + {37{match1[30] & ~s1_odd_page_buffer[30]}} & {5'd30, tlb_ps[30], tlb_ppn0[30], tlb_v0[30], tlb_d0[30], tlb_mat0[30], tlb_plv0[30]} | + {37{match1[31] & ~s1_odd_page_buffer[31]}} & {5'd31, tlb_ps[31], tlb_ppn0[31], tlb_v0[31], tlb_d0[31], tlb_mat0[31], tlb_plv0[31]} ; + +always @(posedge clk) begin + if (we) begin + tlb_vppn [w_index] <= w_vppn; + tlb_asid [w_index] <= w_asid; + tlb_g [w_index] <= w_g; + tlb_ps [w_index] <= w_ps; + tlb_ppn0 [w_index] <= w_ppn0; + tlb_plv0 [w_index] <= w_plv0; + tlb_mat0 [w_index] <= w_mat0; + tlb_d0 [w_index] <= w_d0; + tlb_v0 [w_index] <= w_v0; + tlb_ppn1 [w_index] <= w_ppn1; + tlb_plv1 [w_index] <= w_plv1; + tlb_mat1 [w_index] <= w_mat1; + tlb_d1 [w_index] <= w_d1; + tlb_v1 [w_index] <= w_v1; + end +end + +assign r_vppn = tlb_vppn [r_index]; +assign r_asid = tlb_asid [r_index]; +assign r_g = tlb_g [r_index]; +assign r_ps = tlb_ps [r_index]; +assign r_e = tlb_e [r_index]; +assign r_v0 = tlb_v0 [r_index]; +assign r_d0 = tlb_d0 [r_index]; +assign r_mat0 = tlb_mat0 [r_index]; +assign r_plv0 = tlb_plv0 [r_index]; +assign r_ppn0 = tlb_ppn0 [r_index]; +assign r_v1 = tlb_v1 [r_index]; +assign r_d1 = tlb_d1 [r_index]; +assign r_mat1 = tlb_mat1 [r_index]; +assign r_plv1 = tlb_plv1 [r_index]; +assign r_ppn1 = tlb_ppn1 [r_index]; + +//tlb entry invalid +generate + for (i = 0; i < TLBNUM; i = i + 1) + begin: invalid_tlb_entry + always @(posedge clk) begin + if (we && (w_index == i)) begin + tlb_e[i] <= w_e; + end + else if (inv_en) begin + if (inv_op == 5'd0 || inv_op == 5'd1) begin + tlb_e[i] <= 1'b0; + end + else if (inv_op == 5'd2) begin + if (tlb_g[i]) begin + tlb_e[i] <= 1'b0; + end + end + else if (inv_op == 5'd3) begin + if (!tlb_g[i]) begin + tlb_e[i] <= 1'b0; + end + end + else if (inv_op == 5'd4) begin + if (!tlb_g[i] && (tlb_asid[i] == inv_asid)) begin + tlb_e[i] <= 1'b0; + end + end + else if (inv_op == 5'd5) begin + if (!tlb_g[i] && (tlb_asid[i] == inv_asid) && + ((tlb_ps[i] == 6'd12) ? (tlb_vppn[i] == inv_vpn) : (tlb_vppn[i][18:10] == inv_vpn[18:10]))) begin + tlb_e[i] <= 1'b0; + end + end + else if (inv_op == 5'd6) begin + if ((tlb_g[i] || (tlb_asid[i] == inv_asid)) && + ((tlb_ps[i] == 6'd12) ? (tlb_vppn[i] == inv_vpn) : (tlb_vppn[i][18:10] == inv_vpn[18:10]))) begin + tlb_e[i] <= 1'b0; + end + end + end + end + end +endgenerate -reg [EntryLen] entry [TLBNum-1:0]; - endmodule \ No newline at end of file From b6e1620bb4253977bd6292d3b45503bef68a5d32 Mon Sep 17 00:00:00 2001 From: 250HandsomeLiang <74249519+250HandsomeLiang@users.noreply.github.com> Date: Mon, 2 May 2022 15:23:05 +0800 Subject: [PATCH 039/114] feat: AXI --- src/vsrc/AXI/README.md | 164 +++ src/vsrc/AXI/axi_defines.v | 30 + src/vsrc/AXI/axi_master.v | 374 +++++ src/vsrc/cpu_top.v | 2668 ++++++++++++++++++------------------ 4 files changed, 1902 insertions(+), 1334 deletions(-) create mode 100644 src/vsrc/AXI/README.md create mode 100644 src/vsrc/AXI/axi_defines.v create mode 100644 src/vsrc/AXI/axi_master.v diff --git a/src/vsrc/AXI/README.md b/src/vsrc/AXI/README.md new file mode 100644 index 0000000..0ccaa10 --- /dev/null +++ b/src/vsrc/AXI/README.md @@ -0,0 +1,164 @@ +# AXI总线说明 + +## 目录结构 +``` + AXI + AXI_Master/ 主机接口文件夹 + axi_Master axi主机接口,接入cpu_top + axi_MasterThree 失败版本,不用管 + + AXI_Slave/ 空文件夹 + + axi_defines.v 定义了宏的文件 +``` + +## 接口说明 +``` + 时钟和复位信号 + input wire aclk, + input wire aresetn, //low is valid + + 来自cpu和输出到cpu的信号,其中只有cpu_data_o和stallreq是输出的。 + //CPU + input wire [`ADDR]cpu_addr_i, + input wire cpu_ce_i, + input wire [`Data]cpu_data_i, + input wire cpu_we_i , + input wire [3:0]cpu_sel_i, + input wire stall_i, + input wire flush_i, + output reg [`Data]cpu_data_o,//指令 + output wire stallreq,//暂停信号 + input wire [3:0]id,//决定是读数据还是取指令 + + + AXI标准信号接口,输出到从机或从从机输入,无需关心内部逻辑,照着接线就好,s是前缀。 + //Slave + + //ar + output reg [`ID]s_arid, //arbitration + output reg [`ADDR]s_araddr, + output wire [`Len]s_arlen, + output reg [`Size]s_arsize, + output wire [`Burst]s_arburst, + output wire [`Lock]s_arlock, + output wire [`Cache]s_arcache, + output wire [`Prot]s_arprot, + output reg s_arvalid, + input wire s_arready, + + //r + input wire [`ID]s_rid, + input wire [`Data]s_rdata, + input wire [`Resp]s_rresp, + input wire s_rlast,//the last read data + input wire s_rvalid, + output reg s_rready, + + //aw + output wire [`ID]s_awid, + output reg [`ADDR]s_awaddr, + output wire [`Len]s_awlen, + output reg [`Size]s_awsize, + output wire [`Burst]s_awburst, + output wire [`Lock]s_awlock, + output wire [`Cache]s_awcache, + output wire [`Prot]s_awprot, + output reg s_awvalid, + input wire s_awready, + + //w + output wire [`ID]s_wid, + output reg [`Data]s_wdata, + output wire [3:0]s_wstrb,//字节选通位和sel差不多 + output wire s_wlast, + output reg s_wvalid, + input wire s_wready, + + //b + input wire [`ID]s_bid, + input wire [`Resp]s_bresp, + input wire s_bvalid, + output reg s_bready +``` + +## 使用说明 +1. 把axi_Master主机接口放到cpuTop中实例化 + * 仅验证读功能的axi接口,取值id接口`4’b0000`,取数id接口`4'b0001` + ``` + //AXI Master interface for fetch instruction channel + wire aresetn=~rst; + wire axi_stall=&stall; + wire stallreq_from_if; + wire [31:0]inst_data_from_axi; + + //接口实例化 + axi_Master inst_interface( + .aclk(clk), + .aresetn(aresetn), //low is valid + + //CPU + .cpu_addr_i(pc), + .cpu_ce_i(chip_enable), + .cpu_data_i(0), + .cpu_we_i(0) , + .cpu_sel_i(4'b1111), + .stall_i(axi_stall), + .flush_i(0), + .cpu_data_o(inst_data_from_axi), + .stallreq(stallreq_from_if), + .id(4'b0000),//决定是读数据还是取指令 + + //ar + .s_arid(i_arid), //arbitration + .s_araddr(i_araddr), + .s_arlen(i_arlen), + .s_arsize(i_arsize), + .s_arburst(i_arburst), + .s_arlock(i_arlock), + .s_arcache(i_arcache), + .s_arprot(i_arprot), + .s_arvalid(i_arvalid), + .s_arready(i_arready), + + //r + .s_rid(i_rid), + .s_rdata(i_rdata), + .s_rresp(i_rresp), + .s_rlast(i_rlast),//the last read data + .s_rvalid(i_rvalid), + .s_rready(i_rready), + + //aw + .s_awid(i_awid), + .s_awaddr(i_awaddr), + .s_awlen(i_awlen), + .s_awsize(i_awsize), + .s_awburst(i_awburst), + .s_awlock(i_awlock), + .s_awcache(i_awcache), + .s_awprot(i_awprot), + .s_awvalid(i_awvalid), + .s_awready(i_awready), + + //w + .s_wid(i_wid), + .s_wdata(i_wdata), + .s_wstrb(i_wstrb),//字节选通位和sel差不多 + .s_wlast(i_wlast), + .s_wvalid(i_wvalid), + .s_wready(i_wready), + + //b + .s_bid(i_bid), + .s_bresp(i_bresp), + .s_bvalid(i_bvalid), + .s_bready(i_bready) + + ); + ``` + + +2. inst_data_from_axi为从ram中取到的数据,建议直接放到if_buffer中,以实现pc和inst的对齐。stallreq_if为暂停请求,连接到CTRL中。ctrl和if_buffer的暂停逻辑重写。详情看具体的文件。 +* [ctrl文件](../vsrc/ctrl.v) +* [if_buffer](../vsrc/if_buffer.v) diff --git a/src/vsrc/AXI/axi_defines.v b/src/vsrc/AXI/axi_defines.v new file mode 100644 index 0000000..1da48db --- /dev/null +++ b/src/vsrc/AXI/axi_defines.v @@ -0,0 +1,30 @@ +// signal width +`define ID 3:0 +`define ADDR 31:0 +`define Len 7:0 +`define Size 2:0 +`define Burst 1:0 +`define Lock 1:0 +`define Cache 3:0 +`define Prot 2:0 +`define Data 31:0 +`define Resp 1:0 + +//stall state +`define STALL 4'b1111 //哈佛结构增加的暂停缓存状态,用于处理暂停信号 + +//Master read state +`define R_FREE 4'b0000 +`define R_ADDR 4'b0001 +`define R_DATA 4'b0010 + +//Master write state +`define W_FREE 4'b0011 +`define W_ADDR 4'b0100 +`define W_DATA 4'b0101 +`define W_RESP 4'b0110 + +//burst +`define FIXED 2'b00 +`define INCR 2'b01 +`define WRAP 2'b10 \ No newline at end of file diff --git a/src/vsrc/AXI/axi_master.v b/src/vsrc/AXI/axi_master.v new file mode 100644 index 0000000..df9fe47 --- /dev/null +++ b/src/vsrc/AXI/axi_master.v @@ -0,0 +1,374 @@ +`include "axi_defines.v" +module axi_master ( + input wire aclk, + input wire aresetn, //low is valid + + //CPU + input wire [`ADDR] cpu_addr_i, + input wire cpu_ce_i, + input wire [`Data] cpu_data_i, + input wire cpu_we_i, + input wire [3:0] cpu_sel_i, + input wire stall_i, + input wire flush_i, + output reg [`Data] cpu_data_o, + output wire stallreq, + input wire [3:0] id, //决定是读数据还是取指令 + + //Master + + //ar + + //r + + //aw + + //w + + //b + + //Slave + + //ar + output reg [`ID] s_arid, //arbitration + output reg [`ADDR] s_araddr, + output wire [`Len] s_arlen, + output reg [`Size] s_arsize, + output wire [`Burst] s_arburst, + output wire [`Lock] s_arlock, + output wire [`Cache] s_arcache, + output wire [`Prot] s_arprot, + output reg s_arvalid, + input wire s_arready, + + //r + input wire [`ID] s_rid, + input wire [`Data] s_rdata, + input wire [`Resp] s_rresp, + input wire s_rlast, //the last read data + input wire s_rvalid, + output reg s_rready, + + //aw + output wire [`ID] s_awid, + output reg [`ADDR] s_awaddr, + output wire [`Len] s_awlen, + output reg [`Size] s_awsize, + output wire [`Burst] s_awburst, + output wire [`Lock] s_awlock, + output wire [`Cache] s_awcache, + output wire [`Prot] s_awprot, + output reg s_awvalid, + input wire s_awready, + + //w + output wire [`ID] s_wid, + output reg [`Data] s_wdata, + output wire [3:0] s_wstrb, //字节选通位和sel差不多 + output wire s_wlast, + output reg s_wvalid, + input wire s_wready, + + //b + input wire [`ID] s_bid, + input wire [`Resp] s_bresp, + input wire s_bvalid, + output reg s_bready + +); + reg stall_req_r; + reg stall_req_w; + + assign stallreq = stall_req_r || stall_req_w; + reg [31:0] data_buffer; + + + + reg [ 3:0] r_state; + + //改变输出 + always @(*) begin + if (!aresetn) begin + stall_req_r = 0; + cpu_data_o = 0; + end else begin + case (r_state) + `R_FREE: begin + if (cpu_ce_i && cpu_we_i == 0) begin + stall_req_r = 1; + cpu_data_o = 0; + end else begin + stall_req_r = 0; + cpu_data_o = 0; + end + end + `R_ADDR: begin + stall_req_r = 1; + cpu_data_o = 0; + end + `R_DATA: begin + if (s_rvalid && s_rlast) begin + stall_req_r = 0; + cpu_data_o = s_rdata; + end else begin + stall_req_r = 1; + cpu_data_o = 0; + end + end + default: begin + end + endcase + end + end + + //read + //state machine + always @(posedge aclk) begin + if (!aresetn) begin + r_state <= `R_FREE; + s_arid <= 0; + s_araddr <= 0; + s_arsize <= 0; + data_buffer <= 0; + s_rready <= 0; + + s_arvalid <= 0; + end else begin + case (r_state) + + `R_FREE: begin + + if (cpu_ce_i && (cpu_we_i == 0)) begin + r_state <= `R_ADDR; + s_arid <= 0; + s_araddr <= cpu_addr_i; + s_arsize <= 0; + data_buffer <= 0; + s_rready <= 0; + + s_arvalid <= 1; + + + end else begin + r_state <= r_state; + s_arid <= 0; + s_araddr <= 0; + s_arsize <= 0; + data_buffer <= 0; + s_rready <= 0; + + s_arvalid <= 0; + end + end + + /** AR **/ + `R_ADDR: begin + + if (s_arready && s_arvalid) begin + r_state <= `R_DATA; + s_arid <= id; + s_araddr <= cpu_addr_i; + s_arsize <= 3'b010; + data_buffer <= 0; + s_rready <= 1; + + s_arvalid <= 0; + end else begin + r_state <= r_state; + s_arid <= s_arid; + s_araddr <= s_araddr; + s_arsize <= s_arsize; + data_buffer <= 0; + s_rready <= s_rready; + + s_arvalid <= s_arvalid; + + end + + + end + + /** R **/ + `R_DATA: begin + // if(!aresetn) + // begin + + // end + if (s_rvalid && s_rlast) begin + r_state <= `R_FREE; + data_buffer <= s_rdata; + s_rready <= 0; + end else begin + r_state <= r_state; + data_buffer <= 0; + s_rready <= s_rready; + end + + // //set s_rready + // if(~s_rready) + // begin + // s_rready<=1; + // end + // else if(s_rready&&s_rvalid) + // begin + // s_rready<=0; + + // end + // else + // begin + // s_rready<=s_rready; + // end + end + + default: begin + + end + + endcase + end + end + + //set default + //ar + assign s_arlen = 0; + assign s_arburst = `INCR; + assign s_arlock = 0; + assign s_arcache = 4'b0000; + assign s_arprot = 3'b000; + + + //write + //state machine + reg [3:0] w_state; + //改变输出 + always @(*) begin + if (!aresetn) stall_req_w = 0; + else begin + case (w_state) + `W_FREE: begin + if (cpu_ce_i && (cpu_we_i)) stall_req_w = 1; + else stall_req_w = 0; + end + `W_ADDR, `W_DATA: stall_req_w = 1; + `W_RESP: begin + if (s_bvalid && s_bready) stall_req_w = 0; + else stall_req_w = 1; + end + default: begin + end + endcase + end + + end + + always @(posedge aclk) begin + if (!aresetn) begin + w_state <= `W_FREE; + s_awaddr <= 0; + s_awsize <= 0; + + s_awvalid <= 0; + s_wdata <= 0; + s_wvalid <= 0; + s_bready <= 0; + end else begin + case (w_state) + + `W_FREE: begin + + if (cpu_ce_i && (cpu_we_i)) begin + w_state <= `W_ADDR; + s_awaddr <= 0; + s_awsize <= 0; + + s_awvalid <= 1; + s_wdata <= 0; + s_wvalid <= 0; + s_bready <= 0; + end else begin + w_state <= w_state; + s_awaddr <= 0; + s_awsize <= 0; + + s_awvalid <= 0; + s_wdata <= 0; + s_wvalid <= 0; + s_bready <= 0; + end + end + /** AW **/ + `W_ADDR: begin + + if (s_awvalid && s_awready) begin + w_state <= `W_DATA; + s_awaddr <= cpu_addr_i; + s_awsize <= 3'b010; + + s_awvalid <= 0; + s_wvalid <= 1; + s_bready <= 1; + end else begin + w_state <= w_state; + s_awaddr <= s_awaddr; + s_awsize <= s_awsize; + + s_awvalid <= s_awvalid; + s_wvalid <= s_wvalid; + s_bready <= s_bready; + end + end + /** W **/ + `W_DATA: begin + + if (s_wvalid && s_wready) begin + w_state <= `W_RESP; + s_wdata <= cpu_data_i; + end else begin + w_state <= w_state; + s_wdata <= s_wdata; + end + + //set wvalid + if (s_wvalid && s_wready) begin + s_wvalid <= 0; + end else if (~s_wvalid) begin + s_wvalid <= 1; + end else begin + s_wvalid <= s_wvalid; + end + + end + /** B **/ + `W_RESP: begin + + if (s_bvalid && s_bready) begin + w_state <= `W_FREE; + s_bready <= 0; + end else begin + w_state <= w_state; + s_bready <= s_bready; + end + end + + default: begin + + end + + endcase + end + end + + //set default + //aw + assign s_awid = 1; + assign s_awlen = 0; + assign s_awburst = `INCR; + assign s_awlock = 0; + assign s_awcache = 0; + assign s_awprot = 0; + assign s_wid = 0; + assign s_wstrb = {4{cpu_we_i}} & cpu_sel_i; + assign s_wlast = 1; + + +endmodule diff --git a/src/vsrc/cpu_top.v b/src/vsrc/cpu_top.v index 2ef084b..286bc20 100644 --- a/src/vsrc/cpu_top.v +++ b/src/vsrc/cpu_top.v @@ -18,971 +18,971 @@ module cpu_top ( input wire clk, input wire rst, - input wire[`RegBus] dram_data_i_1, - input wire[`RegBus] dram_data_i_2, - input wire[`RegBus] ram_rdata_i_1, - input wire[`RegBus] ram_rdata_i_2, - - output wire[`RegBus] ram_raddr_o_1, - output wire[`RegBus] ram_raddr_o_2, - output wire[`RegBus] ram_wdata_o, - output wire[`RegBus] ram_waddr_o, + input wire [`RegBus] dram_data_i_1, + input wire [`RegBus] dram_data_i_2, + input wire [`RegBus] ram_rdata_i_1, + input wire [`RegBus] ram_rdata_i_2, + + output wire [`RegBus] ram_raddr_o_1, + output wire [`RegBus] ram_raddr_o_2, + output wire [`RegBus] ram_wdata_o, + output wire [`RegBus] ram_waddr_o, output wire ram_wen_o, output wire ram_en_o, - output wire[`RegBus] dram_addr_o_1, - output wire[`RegBus] dram_data_o_1, + output wire [`RegBus] dram_addr_o_1, + output wire [`RegBus] dram_data_o_1, output wire dram_we_o_1, - output wire[3:0] dram_sel_o_1, + output wire [3:0] dram_sel_o_1, output wire dram_ce_o_1, - output wire[`InstAddrBus] dram_pc_o_1, + output wire [`InstAddrBus] dram_pc_o_1, - output wire[`RegBus] dram_addr_o_2, - output wire[`RegBus] dram_data_o_2, + output wire [`RegBus] dram_addr_o_2, + output wire [`RegBus] dram_data_o_2, output wire dram_we_o_2, - output wire[3:0] dram_sel_o_2, + output wire [3:0] dram_sel_o_2, output wire dram_ce_o_2, - output wire[`InstAddrBus] dram_pc_o_2, + output wire [`InstAddrBus] dram_pc_o_2, - output wire[`RegBus] debug_commit_pc_1, + output wire [`RegBus] debug_commit_pc_1, output wire debug_commit_valid_1, - output wire[`InstBus] debug_commit_instr_1, + output wire [`InstBus] debug_commit_instr_1, output wire debug_commit_wreg_1, - output wire[`RegAddrBus] debug_commit_reg_waddr_1, - output wire[`RegBus] debug_commit_reg_wdata_1, - output wire[`RegBus] debug_commit_pc_2, + output wire [`RegAddrBus] debug_commit_reg_waddr_1, + output wire [`RegBus] debug_commit_reg_wdata_1, + output wire [`RegBus] debug_commit_pc_2, output wire debug_commit_valid_2, - output wire[`InstBus] debug_commit_instr_2, + output wire [`InstBus] debug_commit_instr_2, output wire debug_commit_wreg_2, - output wire[`RegAddrBus] debug_commit_reg_waddr_2, - output wire[`RegBus] debug_commit_reg_wdata_2, - output wire[1023:0] debug_reg, - output wire[831:0] csr_diff, + output wire [`RegAddrBus] debug_commit_reg_waddr_2, + output wire [`RegBus] debug_commit_reg_wdata_2, + output wire [1023:0] debug_reg, + output wire [831:0] csr_diff, output wire Instram_branch_flag - ); - - wire[`InstAddrBus] pc_1; - wire[`InstAddrBus] pc_2; - wire chip_enable; - - wire [`InstAddrBus]pc_buffer_1; - wire [`InstAddrBus]pc_buffer_2; - - assign ram_en_o = chip_enable; - assign ram_raddr_o_1 = pc_buffer_1; - assign ram_raddr_o_2 = pc_buffer_2; - - wire branch_flag_1; - wire branch_flag_2; - assign Instram_branch_flag=branch_flag_1 | branch_flag_2; - wire[`RegBus] branch_target_address_1; - wire[`RegBus] branch_target_address_2; - wire[`RegBus] link_addr; - wire flush; - wire[`RegBus] new_pc; - wire[6:0] stall1; // [pc_reg,if_buffer_1, if_id, id_ex, ex_mem, mem_wb, ctrl] - wire[6:0] stall2; - - - //tlb - wire inst_addr_trans_en; - wire data_addr_trans_en; - wire fetch_en; - wire [31:0] inst_vaddr; - wire inst_dmw0_en; - wire inst_dmw1_en; - wire [7:0] inst_index; - wire [19:0] inst_tag; - wire [3:0] inst_offset; - wire inst_tlb_found; - wire inst_tlb_v; - wire inst_tlb_d; - wire [1:0] inst_tlb_mat; - wire [1:0] inst_tlb_plv; - wire data_fetch; - wire [31:0] data_vaddr; - wire data_dmw0_en; - wire data_dmw1_en; - wire cacop_op_mode_di; - wire [7:0] data_index; - wire [19:0] data_tag; - wire [3:0] data_offset; - wire data_tlb_found; - wire [4:0] data_tlb_index; - wire data_tlb_v; - wire data_tlb_d; - wire [1:0] data_tlb_mat; - wire [1:0] data_tlb_plv; - wire tlbfill_en; - wire tlbwr_en; - wire [4:0] rand_index; - wire [31:0] tlbw_tlbehi; - wire [31:0] tlbw_tlbelo0; - wire [31:0] tlbw_tlbelo1; - wire [31:0] tlbw_r_tlbidx; - wire [5:0] tlbw_ecode; - wire [31:0] tlbr_tlbehi; - wire [31:0] tlbr_tlbelo0; - wire [31:0] tlbr_tlbelo1; - wire [31:0] tlbr_tlbidx; - wire [9:0] tlbr_asid; - wire invtlb_en; - wire [9:0] invtlb_asid; - wire [18:0] invtlb_vpn; - wire [4:0] invtlb_op; - - //csr - wire has_int; - wire excp_flush; - wire ertn_flush; - wire wb_csr_en; - wire [13:0] wb_csr_addr; - wire [31:0] wb_csr_data; - wire [31:0] wb_csr_era; - wire [8:0] wb_csr_esubcode; - wire [5:0] wb_csr_ecode; - wire wb_va_error; - wire [31:0] wb_bad_va; - wire tlbsrch_en; - wire tlbsrch_found; - wire [4:0] tlbsrch_index; - wire excp_tlbrefill; - wire excp_tlb; - wire [18:0] excp_tlb_vppn; - wire csr_llbit_i; - wire csr_llbit_set_i; - wire csr_llbit_o; - wire csr_llbit_set_o; - wire [`RegBus]csr_eentry; - wire [31:0] csr_tlbrentry; - wire [`RegBus] csr_era; - - wire [9:0] csr_asid; - wire csr_pg; - wire csr_da; - wire [31:0] csr_dmw0; - wire [31:0] csr_dmw1; - wire [1:0] csr_datf; - wire [1:0] csr_datm; - wire [1:0] csr_plv; - - wire [13:0] id_csr_addr_1; - wire [31:0] id_csr_data_1; - wire [13:0] id_csr_addr_2; - wire [31:0] id_csr_data_2; - wire [`RegBus] id_csr_data_o_1; - wire [`RegBus] id_csr_data_o_2; - wire id_csr_we_1; - wire id_csr_we_2; - wire [13:0] id_csr_addr_o_1; - wire [13:0] id_csr_addr_o_2; - wire [13:0] id_csr_read_addr_o_1; - wire [13:0] id_csr_read_addr_o_2; - - wire pc_excp_o; - wire [3:0] pc_excp_num_o; - - wire idle_flush; - wire[`InstAddrBus] idle_pc; - wire excp_flush_1; - wire ertn_flush_1; - wire excp_flush_2; - wire ertn_flush_2; - - assign excp_flush = excp_flush_1 | excp_flush_2; - assign ertn_flush = ertn_flush_1 | ertn_flush_2; - - wire [`RegBus] id_csr_data_i_1; - wire [`RegBus] id_csr_data_i_2; - - wire disable_cache; - - pc_reg u_pc_reg( - .clk(clk), - .rst(rst), - .pc_1(pc_1), - .pc_2(pc_2), - .ce(chip_enable), - .branch_flag_i_1(branch_flag_1), - .branch_target_address_1(branch_target_address_1), - .branch_flag_i_2(branch_flag_2), - .branch_target_address_2(branch_target_address_2), - .flush(flush), - .new_pc(new_pc), - .stall1(stall1[0]), - .stall2(stall2[0]), - .excp_flush(excp_flush), - .ertn_flush(ertn_flush), - .excp_tlbrefill(excp_tlbrefill), - .idle_flush(idle_flush), - .idle_pc(idle_pc), - - .excp_o(pc_excp_o), - .excp_num_o(pc_excp_num_o), - - .csr_pg(csr_pg), - .csr_da(csr_da), - .csr_dmw0(csr_dmw0), - .csr_dmw1(csr_dmw1), - .csr_plv(csr_plv), - .csr_datf(csr_datf), - .disable_cache(disable_cache), - .csr_eentry(csr_eentry), - .csr_era(csr_era), - .csr_tlbrentry(csr_tlbrentry), - - .inst_tlb_found(inst_tlb_found), - .inst_tlb_v(inst_tlb_v), - .inst_tlb_d(inst_tlb_d), - .inst_tlb_mat(inst_tlb_mat), - .inst_tlb_plv(inst_tlb_plv), - - .inst_addr(inst_vaddr), - .inst_addr_trans_en(inst_addr_trans_en), - .dmw0_en(inst_dmw0_en), - .dmw1_en(inst_dmw1_en) - ); - - wire if_inst_valid_1; - wire if_inst_valid_2; - wire if_excp_i_1; - wire [3:0] if_excp_num_i_1; - wire if_excp_i_2; - wire [3:0] if_excp_num_i_2; - - if_buffer if_buffer_1( - .clk(clk), - .rst(rst), - .pc_i(pc_1), - .branch_flag_i(branch_flag_1 | branch_flag_2), - .pc_valid(if_inst_valid_1), - .pc_o(pc_buffer_1), - .flush(flush), - .stall(stall1[1]), - .excp_i(pc_excp_o), - .excp_num_i(pc_excp_num_o), - .excp_o(if_excp_i_1), - .excp_num_o(if_excp_num_i_1), - .excp_flush(excp_flush), - .ertn_flush(ertn_flush) - ); - - if_buffer if_buffer_2( - .clk(clk), - .rst(rst), - .pc_i(pc_2), - .branch_flag_i(branch_flag), - .pc_valid(if_inst_valid_2), - .pc_o(pc_buffer_2), - .flush(flush), - .stall(stall2[1]), - .excp_i(pc_excp_o), - .excp_num_i(pc_excp_num_o), - .excp_o(if_excp_i_2), - .excp_num_o(if_excp_num_i_2), - .excp_flush(excp_flush), - .ertn_flush(ertn_flush) - ); - - - wire[`InstAddrBus] id_pc_1; - wire[`InstBus] id_inst_1; - wire[`InstAddrBus] id_pc_2; - wire[`InstBus] id_inst_2; - - wire if_excp_o_1; - wire [3:0] if_excp_num_o_1; - wire if_excp_o_2; - wire [3:0] if_excp_num_o_2; - - // wire if_id_instr_invalid; - if_id u_if_id_1( - .clk(clk), - .rst(rst), - .if_pc_i(pc_buffer_1), - .if_inst_i(ram_rdata_i_1), - .id_pc_o(id_pc_1), - .id_inst_o(id_inst_1), - .if_inst_valid(if_inst_valid_1), - .branch_flag_i(branch_flag), - .flush(flush), - .stall(stall1[2]), - .excp_i(if_excp_i_1), - .excp_num_i(if_excp_num_i_1), - .excp_o(if_excp_o_1), - .excp_num_o(if_excp_num_o_1) - ); - - if_id u_if_id_2( - .clk(clk), - .rst(rst), - .if_pc_i(pc_buffer_2), - .if_inst_i(ram_rdata_i_2), - .id_pc_o(id_pc_2), - .id_inst_o(id_inst_2), - .if_inst_valid(if_inst_valid_2), - .branch_flag_i(branch_flag), - .flush(flush), - .stall(stall2[2]), - .excp_i(if_excp_i_2), - .excp_num_i(if_excp_num_i_2), - .excp_o(if_excp_o_2), - .excp_num_o(if_excp_num_o_2) - ); - - wire[`AluOpBus] id_aluop_1; - wire[`AluSelBus] id_alusel_1; - wire[`RegBus] id_reg1_1; - wire[`RegBus] id_reg2_1; - wire[`RegAddrBus] id_reg_waddr_1; - wire id_wreg_1; - wire id_inst_valid_1; - wire[`InstAddrBus] id_inst_pc_1; - wire[`RegBus] id_inst_o_1; - - wire reg1_read_1; - wire reg2_read_1; - wire[`RegAddrBus] reg1_addr_1; - wire[`RegAddrBus] reg2_addr_1; - wire[`RegBus] reg1_data_1; - wire[`RegBus] reg2_data_1; - - wire ex_wreg_o_1; - wire[`RegAddrBus] ex_reg_waddr_o_1; - wire[`RegBus] ex_reg_wdata_1; - wire[`AluOpBus] ex_aluop_o_1; - - wire mem_wreg_o_1; - wire[`RegAddrBus] mem_reg_waddr_o_1; - wire[`RegBus] mem_reg_wdata_o_1; - - wire stallreq_from_id_1; - wire stallreq_from_ex_1; - - wire[1:0] id_excepttype_o_1; - wire[`RegBus] id_current_inst_address_o_1; - - wire ex_wreg_o_2; - wire[`RegAddrBus] ex_reg_waddr_o_2; - wire[`RegBus] ex_reg_wdata_2; - wire[`AluOpBus] ex_aluop_o_2; - - wire mem_wreg_o_2; - wire[`RegAddrBus] mem_reg_waddr_o_2; - wire[`RegBus] mem_reg_wdata_o_2; - - wire[`RegAddrBus] reg1_addr_2; - wire[`RegAddrBus] reg2_addr_2; - - wire[`RegBus] link_addr_1; - wire[`RegBus] link_addr_2; - - wire[`RegAddrBus] id_reg_waddr_2; - - wire stallreq_to_next_1; - wire stallreq_to_next_2; - - wire id_excp_o_1; - wire [8:0] id_excp_num_o_1; - wire id_excp_o_2; - wire [8:0] id_excp_num_o_2; - - - id u_id_1( - .rst(rst), - .pc_i(id_pc_1), - .inst_i(id_inst_1), - - .pc_i_other(pc_buffer_2), - - .reg1_data_i (reg1_data_1 ), - .reg2_data_i (reg2_data_1 ), - - .ex_wreg_i_1 (ex_wreg_o_1 ), - .ex_waddr_i_1 (ex_reg_waddr_o_1), - .ex_wdata_i_1 (ex_reg_wdata_1), - .ex_aluop_i_1 (ex_aluop_o_1), - - .ex_wreg_i_2 (ex_wreg_o_2 ), - .ex_waddr_i_2 (ex_reg_waddr_o_2), - .ex_wdata_i_2 (ex_reg_wdata_2), - .ex_aluop_i_2 (ex_aluop_o_2), - - .mem_wreg_i_1 (mem_wreg_o_1), - .mem_waddr_i_1 (mem_reg_waddr_o_1), - .mem_wdata_i_1 (mem_reg_wdata_o_1), - - .mem_wreg_i_2 (mem_wreg_o_2), - .mem_waddr_i_2 (mem_reg_waddr_o_2), - .mem_wdata_i_2 (mem_reg_wdata_o_2), - - .reg1_read_o (reg1_read_1 ), - .reg2_read_o (reg2_read_1 ), - - .reg1_addr_o (reg1_addr_1 ), - .reg2_addr_o (reg2_addr_1 ), - - .aluop_o (id_aluop_1 ), - .alusel_o (id_alusel_1 ), - .reg1_o (id_reg1_1 ), - .reg2_o (id_reg2_1 ), - .reg_waddr_o (id_reg_waddr_1 ), - .wreg_o (id_wreg_1 ), - .inst_valid(id_inst_valid_1), - .inst_pc(id_inst_pc_1), - .inst_o(id_inst_o_1), - .csr_we(id_csr_we_1), - .csr_addr_o(id_csr_addr_o_1), - .csr_data_o(id_csr_data_o_1), - - .csr_read_addr_o(id_csr_read_addr_o_1), - .csr_data_i(id_csr_data_1), - .has_int(has_int), - .csr_plv(csr_plv), - - .excp_i(if_excp_o_1), - .excp_num_i(if_excp_num_o_1), - .excp_o(id_excp_o_1), - .excp_num_o(id_excp_num_o_1), - - .branch_flag_o(branch_flag_1), - .branch_target_address_o(branch_target_address_1), - .link_addr_o(link_addr_1), - - .stallreq(stallreq_to_next_1), - .idle_stallreq(), - - .excepttype_o(id_excepttype_o_1), - .current_inst_address_o(id_current_inst_address_o_1) - ); - - wire[`AluOpBus] id_aluop_2; - wire[`AluSelBus] id_alusel_2; - wire[`RegBus] id_reg1_2; - wire[`RegBus] id_reg2_2; - - wire id_wreg_2; - wire id_inst_valid_2; - wire[`InstAddrBus] id_inst_pc_2; - wire[`RegBus] id_inst_o_2; - - wire reg1_read_2; - wire reg2_read_2; - wire[`RegBus] reg1_data_2; - wire[`RegBus] reg2_data_2; - - - - wire stallreq_from_id_2; - wire stallreq_from_ex_2; - - wire[1:0] id_excepttype_o_2; - wire[`RegBus] id_current_inst_address_o_2; - - - - id u_id_2( - .rst(rst), - .pc_i(id_pc_2), - .inst_i(id_inst_2), - - .pc_i_other(pc_buffer_1), - - .reg1_data_i (reg1_data_2 ), - .reg2_data_i (reg2_data_2 ), - - .ex_wreg_i_1 (ex_wreg_o_2 ), - .ex_waddr_i_1 (ex_reg_waddr_o_2), - .ex_wdata_i_1 (ex_reg_wdata_2), - .ex_aluop_i_1 (ex_aluop_o_2), - - .ex_wreg_i_2 (ex_wreg_o_1 ), - .ex_waddr_i_2 (ex_reg_waddr_o_1), - .ex_wdata_i_2 (ex_reg_wdata_1), - .ex_aluop_i_2 (ex_aluop_o_1), - - .mem_wreg_i_1 (mem_wreg_o_2), - .mem_waddr_i_1 (mem_reg_waddr_o_2), - .mem_wdata_i_1 (mem_reg_wdata_o_2), - - .mem_wreg_i_2 (mem_wreg_o_1), - .mem_waddr_i_2 (mem_reg_waddr_o_1), - .mem_wdata_i_2 (mem_reg_wdata_o_1), - - .reg1_read_o (reg1_read_2 ), - .reg2_read_o (reg2_read_2 ), - - .reg1_addr_o (reg1_addr_2 ), - .reg2_addr_o (reg2_addr_2 ), - - .aluop_o (id_aluop_2 ), - .alusel_o (id_alusel_2 ), - .reg1_o (id_reg1_2 ), - .reg2_o (id_reg2_2 ), - .reg_waddr_o (id_reg_waddr_2 ), - .wreg_o (id_wreg_2 ), - .inst_valid(id_inst_valid_2), - .inst_pc(id_inst_pc_2), - .inst_o(id_inst_o_2), - - .csr_we(id_csr_we_2), - .csr_addr_o(id_csr_addr_o_2), - .csr_data_i(id_csr_data_2), - - .csr_read_addr_o(id_csr_read_addr_o_2), - .csr_data_o(id_csr_data_o_2), - .has_int(has_int), - .csr_plv(csr_plv), - - .excp_i(if_excp_o_2), - .excp_num_i(if_excp_num_o_2), - .excp_o(id_excp_o_2), - .excp_num_o(id_excp_num_o_2), - - .branch_flag_o(branch_flag_2), - .branch_target_address_o(branch_target_address_2), - .link_addr_o(link_addr_2), - - .stallreq(stallreq_to_next_2), - .idle_stallreq(), - - .excepttype_o(id_excepttype_o_2), - .current_inst_address_o(id_current_inst_address_o_2) - - ); - - wire[`AluOpBus] ex_aluop_1; - wire[`AluSelBus] ex_alusel_1; - wire[`RegBus] ex_reg1_1; - wire[`RegBus] ex_reg2_1; - wire[`RegAddrBus] ex_reg_waddr_i_1; - wire ex_wreg_i_1; - wire ex_inst_valid_i_1; - wire[`InstAddrBus] ex_inst_pc_i_1; - wire[`RegBus] ex_link_address_1; - wire[`RegBus] ex_inst_i_1; - wire[1:0] ex_excepttype_i_1; - wire[`RegBus] ex_current_inst_address_i_1; - wire ex_csr_we_i_1; - wire [13:0] ex_csr_addr_i_1; - wire [31:0] ex_csr_data_i_1; - - wire ex_excp_i_1; - wire [8:0] ex_excp_num_i_1; - wire ex_excp_o_1; - wire [8:0] ex_excp_num_i_2; - - id_ex id_ex_1( - .clk(clk), - .rst(rst), - .stall(stall1[3]), - - .id_aluop(id_aluop_1), - .id_alusel(id_alusel_1), - .id_reg1(id_reg1_1), - .id_reg2(id_reg2_1), - .id_wd(id_reg_waddr_1), - .id_wreg(id_wreg_1), - .id_inst_pc(id_inst_pc_1), - .id_inst_valid(id_inst_valid_1), - .id_link_address(link_addr_1), - .id_inst(id_inst_o_1), - .flush(flush), - .id_excepttype(id_excepttype_o_1), - .id_current_inst_address(id_current_inst_address_o_1), - .id_csr_we(id_csr_we_1), - .id_csr_addr(id_csr_addr_o_1), - .id_csr_data(id_csr_data_o_1), - - .ex_aluop(ex_aluop_1), - .ex_alusel(ex_alusel_1), - .ex_reg1(ex_reg1_1), - .ex_reg2(ex_reg2_1), - .ex_wd(ex_reg_waddr_i_1), - .ex_wreg(ex_wreg_i_1), - .ex_inst_pc(ex_inst_pc_i_1), - .ex_inst_valid(ex_inst_valid_i_1), - .ex_link_address(ex_link_address_1), - .ex_inst(ex_inst_i_1), - .ex_excepttype(ex_excepttype_i_1), - .ex_current_inst_address(ex_current_inst_address_i_1), - .ex_csr_we(ex_csr_we_i_1), - .ex_csr_addr(ex_csr_addr_i_1), - .ex_csr_data(ex_csr_data_i_1), - - .reg1_addr_i(reg1_addr_1), - .reg2_addr_i(reg2_addr_1), - .pc_i_other(id_inst_pc_2), - .reg1_addr_i_other(reg1_addr_2), - .reg2_addr_i_other(reg2_addr_2), - .waddr_i_other(id_reg_waddr_2), - - .stallreq_from_id(stallreq_to_next_1), - .stallreq(stallreq_from_id_1), - - .excp_i(id_excp_o_1), - .excp_num_i(id_excp_num_o_1), - .excp_o(ex_excp_i_1), - .excp_num_o(ex_excp_num_i_1), - - .excp_flush(excp_flush), - .ertn_flush(ertn_flush) - ); - - wire[`AluOpBus] ex_aluop_2; - wire[`AluSelBus] ex_alusel_2; - wire[`RegBus] ex_reg1_2; - wire[`RegBus] ex_reg2_2; - wire[`RegAddrBus] ex_reg_waddr_i_2; - wire ex_wreg_i_2; - wire ex_inst_valid_i_2; - wire[`InstAddrBus] ex_inst_pc_i_2; - wire[`RegBus] ex_link_address_2; - wire[`RegBus] ex_inst_i_2; - wire[1:0] ex_excepttype_i_2; - wire[`RegBus] ex_current_inst_address_i_2; - wire ex_csr_we_i_2; - wire [13:0] ex_csr_addr_i_2; - wire [31:0] ex_csr_data_i_2; - - wire ex_excp_i_2; - wire [9:0] ex_excp_num_o_1; - wire ex_excp_o_2; - wire [9:0] ex_excp_num_o_2; - - id_ex id_ex_2( - .clk(clk), - .rst(rst), - .stall(stall2[3]), - - .id_aluop(id_aluop_2), - .id_alusel(id_alusel_2), - .id_reg1(id_reg1_2), - .id_reg2(id_reg2_2), - .id_wd(id_reg_waddr_2), - .id_wreg(id_wreg_2), - .id_inst_pc(id_inst_pc_2), - .id_inst_valid(id_inst_valid_2), - .id_link_address(link_addr_2), - .id_inst(id_inst_o_2), - .flush(flush), - .id_excepttype(id_excepttype_o_2), - .id_current_inst_address(id_current_inst_address_o_2), - .id_csr_we(id_csr_we_2), - .id_csr_addr(id_csr_addr_o_2), - .id_csr_data(id_csr_data_o_2), - - .ex_aluop(ex_aluop_2), - .ex_alusel(ex_alusel_2), - .ex_reg1(ex_reg1_2), - .ex_reg2(ex_reg2_2), - .ex_wd(ex_reg_waddr_i_2), - .ex_wreg(ex_wreg_i_2), - .ex_inst_pc(ex_inst_pc_i_2), - .ex_inst_valid(ex_inst_valid_i_2), - .ex_link_address(ex_link_address_2), - .ex_inst(ex_inst_i_2), - .ex_excepttype(ex_excepttype_i_2), - .ex_current_inst_address(ex_current_inst_address_i_2), - .ex_csr_we(ex_csr_we_i_2), - .ex_csr_addr(ex_csr_addr_i_2), - .ex_csr_data(ex_csr_data_i_2), - - .reg1_addr_i(reg1_addr_2), - .reg2_addr_i(reg2_addr_2), - .pc_i_other(id_inst_pc_1), - .reg1_addr_i_other(reg1_addr_1), - .reg2_addr_i_other(reg2_addr_2), - .waddr_i_other(id_reg_waddr_1), - - .stallreq_from_id(stallreq_to_next_2), - .stallreq(stallreq_from_id_2), - - .excp_i(id_excp_o_2), - .excp_num_i(id_excp_num_o_2), - .excp_o(ex_excp_i_2), - .excp_num_o(ex_excp_num_i_2), - - .excp_flush(excp_flush), - .ertn_flush(ertn_flush) - ); - - - wire ex_inst_valid_o_1; - wire[`InstAddrBus] ex_inst_pc_o_1; - wire[`RegBus] ex_addr_o_1; - wire[`RegBus] ex_reg2_o_1; - wire[1:0] ex_excepttype_o_1; - wire[`RegBus] ex_current_inst_address_o_1; - wire ex_csr_we_o_1; - wire [13:0] ex_csr_addr_o_1; - wire [31:0] ex_csr_data_o_1; - - - - ex u_ex_1( - .rst(rst), - - .aluop_i(ex_aluop_1), - .alusel_i(ex_alusel_1), - .reg1_i(ex_reg1_1), - .reg2_i(ex_reg2_1), - .wd_i(ex_reg_waddr_i_1), - .wreg_i(ex_wreg_i_1), - .inst_valid_i(ex_inst_valid_i_1), - .inst_pc_i(ex_inst_pc_i_1), - .inst_i(ex_inst_i_1), - .link_addr_i(ex_link_address_1), - .excepttype_i(ex_excepttype_i_1), - .current_inst_address_i(ex_current_inst_address_i_1), - .ex_csr_we_i(ex_csr_we_i_1), - .ex_csr_addr_i(ex_csr_addr_i_1), - .ex_csr_data_i(ex_csr_data_i_1), - - .wd_o(ex_reg_waddr_o_1), - .wreg_o(ex_wreg_o_1), - .wdata_o(ex_reg_wdata_1), - .inst_valid_o(ex_inst_valid_o_1), - .inst_pc_o(ex_inst_pc_o_1), - .aluop_o(ex_aluop_o_1), - .mem_addr_o(ex_addr_o_1), - .reg2_o(ex_reg2_o_1), - .excepttype_o(ex_excepttype_o_1), - .current_inst_address_o(ex_current_inst_address_o_1), - .ex_csr_we_o(ex_csr_we_o_1), - .ex_csr_addr_o(ex_csr_addr_o_1), - .ex_csr_data_o(ex_csr_data_o_1), - - .stallreq(stallreq_from_ex_1), - - .excp_i(ex_excp_i_1), - .excp_num_i(ex_excp_num_i_1), - .excp_o(ex_excp_o_1), - .excp_num_o(ex_excp_num_o_1) - ); - - wire ex_inst_valid_o_2; - wire[`InstAddrBus] ex_inst_pc_o_2; - wire[`RegBus] ex_addr_o_2; - wire[`RegBus] ex_reg2_o_2; - wire[1:0] ex_excepttype_o_2; - wire[`RegBus] ex_current_inst_address_o_2; - wire ex_csr_we_o_2; - wire [13:0] ex_csr_addr_o_2; - wire [31:0] ex_csr_data_o_2; - - - ex u_ex_2( - .rst(rst), - - .aluop_i(ex_aluop_2), - .alusel_i(ex_alusel_2), - .reg1_i(ex_reg1_2), - .reg2_i(ex_reg2_2), - .wd_i(ex_reg_waddr_i_2), - .wreg_i(ex_wreg_i_2), - .inst_valid_i(ex_inst_valid_i_2), - .inst_pc_i(ex_inst_pc_i_2), - .inst_i(ex_inst_i_2), - .link_addr_i(ex_link_address_2), - .excepttype_i(ex_excepttype_i_2), - .current_inst_address_i(ex_current_inst_address_i_2), - .ex_csr_we_i(ex_csr_we_i_2), - .ex_csr_addr_i(ex_csr_addr_i_2), - .ex_csr_data_i(ex_csr_data_i_2), - - .wd_o(ex_reg_waddr_o_2), - .wreg_o(ex_wreg_o_2), - .wdata_o(ex_reg_wdata_2), - .inst_valid_o(ex_inst_valid_o_2), - .inst_pc_o(ex_inst_pc_o_2), - .aluop_o(ex_aluop_o_2), - .mem_addr_o(ex_addr_o_2), - .reg2_o(ex_reg2_o_2), - .excepttype_o(ex_excepttype_o_2), - .current_inst_address_o(ex_current_inst_address_o_2), - .ex_csr_we_o(ex_csr_we_o_2), - .ex_csr_addr_o(ex_csr_addr_o_2), - .ex_csr_data_o(ex_csr_data_o_2), - - .stallreq(stallreq_from_ex_2), - - .excp_i(ex_excp_i_2), - .excp_num_i(ex_excp_num_i_2), - .excp_o(ex_excp_o_2), - .excp_num_o(ex_excp_num_o_2) - ); - - - wire mem_wreg_i_1; - wire[`RegAddrBus] mem_reg_waddr_i_1; - wire[`RegBus] mem_reg_wdata_i_1; - - wire mem_inst_valid_1; - wire[`InstAddrBus] mem_inst_pc_1; - - wire[`AluOpBus] mem_aluop_i_1; - wire[`RegBus] mem_addr_i_1; - wire[`RegBus] mem_reg2_i_1; - wire[1:0] mem_excepttype_i_1; - wire[`RegBus] mem_current_inst_address_i_1; - - wire mem_csr_we_i_1; - wire [13:0] mem_csr_addr_i_1; - wire [31:0] mem_csr_data_i_1; - - wire mem_excp_i_1; - wire [9:0] mem_excp_num_i_1; - wire mem_excp_i_2; - wire [9:0] mem_excp_num_i_2; - - ex_mem u_ex_mem_1( - .clk(clk ), - .rst(rst ), - .stall(stall1[4]), - - .ex_wd (ex_reg_waddr_o_1 ), - .ex_wreg (ex_wreg_o_1 ), - .ex_wdata (ex_reg_wdata_1 ), - .ex_inst_pc(ex_inst_pc_o_1), - .ex_inst_valid(ex_inst_valid_o_1), - .ex_aluop(ex_aluop_o_1), - .ex_mem_addr(ex_addr_o_1), - .ex_reg2(ex_reg2_o_1), - .flush(flush), - .ex_excepttype(ex_excepttype_o_1), - .ex_current_inst_address(ex_current_inst_address_o_1), - .ex_csr_we(ex_csr_we_o_1), - .ex_csr_addr(ex_csr_addr_o_1), - .ex_csr_data(ex_csr_data_o_1), - - .mem_wd(mem_reg_waddr_i_1 ), - .mem_wreg(mem_wreg_i_1 ), - .mem_wdata(mem_reg_wdata_i_1 ), - .mem_inst_valid(mem_inst_valid_1), - .mem_inst_pc(mem_inst_pc_1), - .mem_aluop(mem_aluop_i_1), - .mem_mem_addr(mem_addr_i_1), - .mem_reg2(mem_reg2_i_1), - .mem_excepttype(mem_excepttype_i_1), - .mem_current_inst_address(mem_current_inst_address_i_1), - .mem_csr_we(mem_csr_we_i_1), - .mem_csr_addr(mem_csr_addr_i_1), - .mem_csr_data(mem_csr_data_i_1), - - .excp_i(ex_excp_o_1), - .excp_num_i(ex_excp_num_o_1), - .excp_o(mem_excp_i_1), - .excp_num_o(mem_excp_num_i_1), - - .excp_flush(excp_flush), - .ertn_flush(ertn_flush) - - ); - - - wire mem_wreg_i_2; - wire[`RegAddrBus] mem_reg_waddr_i_2; - wire[`RegBus] mem_reg_wdata_i_2; - - wire mem_inst_valid_2; - wire[`InstAddrBus] mem_inst_pc_2; - - wire[`AluOpBus] mem_aluop_i_2; - wire[`RegBus] mem_addr_i_2; - wire[`RegBus] mem_reg2_i_2; - wire[1:0] mem_excepttype_i_2; - wire[`RegBus] mem_current_inst_address_i_2; - wire mem_csr_we_i_2; - wire [13:0] mem_csr_addr_i_2; - wire [31:0] mem_csr_data_i_2; - - - ex_mem u_ex_mem_2( - .clk(clk ), - .rst(rst ), - .stall(stall2[4]), - - .ex_wd (ex_reg_waddr_o_2 ), - .ex_wreg (ex_wreg_o_2 ), - .ex_wdata (ex_reg_wdata_2 ), - .ex_inst_pc(ex_inst_pc_o_2), - .ex_inst_valid(ex_inst_valid_o_2), - .ex_aluop(ex_aluop_o_2), - .ex_mem_addr(ex_addr_o_2), - .ex_reg2(ex_reg2_o_2), - .flush(flush), - .ex_excepttype(ex_excepttype_o_2), - .ex_current_inst_address(ex_current_inst_address_o_2), - .ex_csr_we(ex_csr_we_o_1), - .ex_csr_addr(ex_csr_addr_o_1), - .ex_csr_data(ex_csr_data_o_1), - - .mem_wd(mem_reg_waddr_i_2 ), - .mem_wreg(mem_wreg_i_2 ), - .mem_wdata(mem_reg_wdata_i_2 ), - .mem_inst_valid(mem_inst_valid_2), - .mem_inst_pc(mem_inst_pc_2), - .mem_aluop(mem_aluop_i_2), - .mem_mem_addr(mem_addr_i_2), - .mem_reg2(mem_reg2_i_2), - .mem_excepttype(mem_excepttype_i_2), - .mem_current_inst_address(mem_current_inst_address_i_2), - .mem_csr_we(mem_csr_we_i_2), - .mem_csr_addr(mem_csr_addr_i_2), - .mem_csr_data(mem_csr_data_i_2), - - .excp_i(ex_excp_o_2), - .excp_num_i(ex_excp_num_o_2), - .excp_o(mem_excp_i_2), - .excp_num_o(mem_excp_num_i_2), - - .excp_flush(excp_flush), - .ertn_flush(ertn_flush) - - ); - - wire LLbit_o_1; - wire wb_LLbit_we_i_1; - wire wb_LLbit_value_i_1; - wire mem_LLbit_we_o_1; - wire mem_LLbit_value_o_1; - wire[1:0] mem_excepttype_o_1; - wire[1:0] mem_excepttype_o_2; - wire[`RegBus] mem_current_inst_address_o_1; - wire[`InstAddrBus] wb_inst_pc_1; - wire mem_csr_we_o_1; - wire [13:0] mem_csr_addr_o_1; - wire [31:0] mem_csr_data_o_1; - - wire mem_excp_o_1; - wire [15:0] mem_excp_num_o_1; - wire mem_excp_o_2; - wire [15:0] mem_excp_num_o_2; - - wire[`AluOpBus] mem_aluop_o_1; - wire[`AluOpBus] mem_aluop_o_2; - - wire data_addr_trans_en_1; - wire data_dmw0_en_1; - wire data_dmw1_en_1; - - wire data_addr_trans_en_2; - wire data_dmw0_en_2; - wire data_dmw1_en_2; - - - - mem u_mem_1( - .rst (rst ), - - .inst_pc_i(mem_inst_pc_1), - .wd_i (mem_reg_waddr_i_1 ), - .wreg_i (mem_wreg_i_1 ), - .wdata_i (mem_reg_wdata_i_1), - .aluop_i(mem_aluop_i_1), +); + + wire [`InstAddrBus] pc_1; + wire [`InstAddrBus] pc_2; + wire chip_enable; + + wire [`InstAddrBus] pc_buffer_1; + wire [`InstAddrBus] pc_buffer_2; + + assign ram_en_o = chip_enable; + assign ram_raddr_o_1 = pc_buffer_1; + assign ram_raddr_o_2 = pc_buffer_2; + + wire branch_flag_1; + wire branch_flag_2; + assign Instram_branch_flag = branch_flag_1 | branch_flag_2; + wire [`RegBus] branch_target_address_1; + wire [`RegBus] branch_target_address_2; + wire [`RegBus] link_addr; + wire flush; + wire [`RegBus] new_pc; + wire [6:0] stall1; // [pc_reg,if_buffer_1, if_id, id_ex, ex_mem, mem_wb, ctrl] + wire [6:0] stall2; + + + //tlb + wire inst_addr_trans_en; + wire data_addr_trans_en; + wire fetch_en; + wire [31:0] inst_vaddr; + wire inst_dmw0_en; + wire inst_dmw1_en; + wire [7:0] inst_index; + wire [19:0] inst_tag; + wire [3:0] inst_offset; + wire inst_tlb_found; + wire inst_tlb_v; + wire inst_tlb_d; + wire [1:0] inst_tlb_mat; + wire [1:0] inst_tlb_plv; + wire data_fetch; + wire [31:0] data_vaddr; + wire data_dmw0_en; + wire data_dmw1_en; + wire cacop_op_mode_di; + wire [7:0] data_index; + wire [19:0] data_tag; + wire [3:0] data_offset; + wire data_tlb_found; + wire [4:0] data_tlb_index; + wire data_tlb_v; + wire data_tlb_d; + wire [1:0] data_tlb_mat; + wire [1:0] data_tlb_plv; + wire tlbfill_en; + wire tlbwr_en; + wire [4:0] rand_index; + wire [31:0] tlbw_tlbehi; + wire [31:0] tlbw_tlbelo0; + wire [31:0] tlbw_tlbelo1; + wire [31:0] tlbw_r_tlbidx; + wire [5:0] tlbw_ecode; + wire [31:0] tlbr_tlbehi; + wire [31:0] tlbr_tlbelo0; + wire [31:0] tlbr_tlbelo1; + wire [31:0] tlbr_tlbidx; + wire [9:0] tlbr_asid; + wire invtlb_en; + wire [9:0] invtlb_asid; + wire [18:0] invtlb_vpn; + wire [4:0] invtlb_op; + + //csr + wire has_int; + wire excp_flush; + wire ertn_flush; + wire wb_csr_en; + wire [13:0] wb_csr_addr; + wire [31:0] wb_csr_data; + wire [31:0] wb_csr_era; + wire [8:0] wb_csr_esubcode; + wire [5:0] wb_csr_ecode; + wire wb_va_error; + wire [31:0] wb_bad_va; + wire tlbsrch_en; + wire tlbsrch_found; + wire [4:0] tlbsrch_index; + wire excp_tlbrefill; + wire excp_tlb; + wire [18:0] excp_tlb_vppn; + wire csr_llbit_i; + wire csr_llbit_set_i; + wire csr_llbit_o; + wire csr_llbit_set_o; + wire [`RegBus] csr_eentry; + wire [31:0] csr_tlbrentry; + wire [`RegBus] csr_era; + + wire [9:0] csr_asid; + wire csr_pg; + wire csr_da; + wire [31:0] csr_dmw0; + wire [31:0] csr_dmw1; + wire [1:0] csr_datf; + wire [1:0] csr_datm; + wire [1:0] csr_plv; + + wire [13:0] id_csr_addr_1; + wire [31:0] id_csr_data_1; + wire [13:0] id_csr_addr_2; + wire [31:0] id_csr_data_2; + wire [`RegBus] id_csr_data_o_1; + wire [`RegBus] id_csr_data_o_2; + wire id_csr_we_1; + wire id_csr_we_2; + wire [13:0] id_csr_addr_o_1; + wire [13:0] id_csr_addr_o_2; + wire [13:0] id_csr_read_addr_o_1; + wire [13:0] id_csr_read_addr_o_2; + + wire pc_excp_o; + wire [3:0] pc_excp_num_o; + + wire idle_flush; + wire [`InstAddrBus] idle_pc; + wire excp_flush_1; + wire ertn_flush_1; + wire excp_flush_2; + wire ertn_flush_2; + + assign excp_flush = excp_flush_1 | excp_flush_2; + assign ertn_flush = ertn_flush_1 | ertn_flush_2; + + wire [`RegBus] id_csr_data_i_1; + wire [`RegBus] id_csr_data_i_2; + + wire disable_cache; + + pc_reg u_pc_reg ( + .clk(clk), + .rst(rst), + .pc_1(pc_1), + .pc_2(pc_2), + .ce(chip_enable), + .branch_flag_i_1(branch_flag_1), + .branch_target_address_1(branch_target_address_1), + .branch_flag_i_2(branch_flag_2), + .branch_target_address_2(branch_target_address_2), + .flush(flush), + .new_pc(new_pc), + .stall1(stall1[0]), + .stall2(stall2[0]), + .excp_flush(excp_flush), + .ertn_flush(ertn_flush), + .excp_tlbrefill(excp_tlbrefill), + .idle_flush(idle_flush), + .idle_pc(idle_pc), + + .excp_o(pc_excp_o), + .excp_num_o(pc_excp_num_o), + + .csr_pg(csr_pg), + .csr_da(csr_da), + .csr_dmw0(csr_dmw0), + .csr_dmw1(csr_dmw1), + .csr_plv(csr_plv), + .csr_datf(csr_datf), + .disable_cache(disable_cache), + .csr_eentry(csr_eentry), + .csr_era(csr_era), + .csr_tlbrentry(csr_tlbrentry), + + .inst_tlb_found(inst_tlb_found), + .inst_tlb_v(inst_tlb_v), + .inst_tlb_d(inst_tlb_d), + .inst_tlb_mat(inst_tlb_mat), + .inst_tlb_plv(inst_tlb_plv), + + .inst_addr(inst_vaddr), + .inst_addr_trans_en(inst_addr_trans_en), + .dmw0_en(inst_dmw0_en), + .dmw1_en(inst_dmw1_en) + ); + + wire if_inst_valid_1; + wire if_inst_valid_2; + wire if_excp_i_1; + wire [3:0] if_excp_num_i_1; + wire if_excp_i_2; + wire [3:0] if_excp_num_i_2; + + if_buffer if_buffer_1 ( + .clk(clk), + .rst(rst), + .pc_i(pc_1), + .branch_flag_i(branch_flag_1 | branch_flag_2), + .pc_valid(if_inst_valid_1), + .pc_o(pc_buffer_1), + .flush(flush), + .stall(stall1[1]), + .excp_i(pc_excp_o), + .excp_num_i(pc_excp_num_o), + .excp_o(if_excp_i_1), + .excp_num_o(if_excp_num_i_1), + .excp_flush(excp_flush), + .ertn_flush(ertn_flush) + ); + + if_buffer if_buffer_2 ( + .clk(clk), + .rst(rst), + .pc_i(pc_2), + .branch_flag_i(branch_flag), + .pc_valid(if_inst_valid_2), + .pc_o(pc_buffer_2), + .flush(flush), + .stall(stall2[1]), + .excp_i(pc_excp_o), + .excp_num_i(pc_excp_num_o), + .excp_o(if_excp_i_2), + .excp_num_o(if_excp_num_i_2), + .excp_flush(excp_flush), + .ertn_flush(ertn_flush) + ); + + + wire [`InstAddrBus] id_pc_1; + wire [`InstBus] id_inst_1; + wire [`InstAddrBus] id_pc_2; + wire [`InstBus] id_inst_2; + + wire if_excp_o_1; + wire [3:0] if_excp_num_o_1; + wire if_excp_o_2; + wire [3:0] if_excp_num_o_2; + + // wire if_id_instr_invalid; + if_id u_if_id_1 ( + .clk(clk), + .rst(rst), + .if_pc_i(pc_buffer_1), + .if_inst_i(ram_rdata_i_1), + .id_pc_o(id_pc_1), + .id_inst_o(id_inst_1), + .if_inst_valid(if_inst_valid_1), + .branch_flag_i(branch_flag), + .flush(flush), + .stall(stall1[2]), + .excp_i(if_excp_i_1), + .excp_num_i(if_excp_num_i_1), + .excp_o(if_excp_o_1), + .excp_num_o(if_excp_num_o_1) + ); + + if_id u_if_id_2 ( + .clk(clk), + .rst(rst), + .if_pc_i(pc_buffer_2), + .if_inst_i(ram_rdata_i_2), + .id_pc_o(id_pc_2), + .id_inst_o(id_inst_2), + .if_inst_valid(if_inst_valid_2), + .branch_flag_i(branch_flag), + .flush(flush), + .stall(stall2[2]), + .excp_i(if_excp_i_2), + .excp_num_i(if_excp_num_i_2), + .excp_o(if_excp_o_2), + .excp_num_o(if_excp_num_o_2) + ); + + wire [`AluOpBus] id_aluop_1; + wire [`AluSelBus] id_alusel_1; + wire [`RegBus] id_reg1_1; + wire [`RegBus] id_reg2_1; + wire [`RegAddrBus] id_reg_waddr_1; + wire id_wreg_1; + wire id_inst_valid_1; + wire [`InstAddrBus] id_inst_pc_1; + wire [`RegBus] id_inst_o_1; + + wire reg1_read_1; + wire reg2_read_1; + wire [`RegAddrBus] reg1_addr_1; + wire [`RegAddrBus] reg2_addr_1; + wire [`RegBus] reg1_data_1; + wire [`RegBus] reg2_data_1; + + wire ex_wreg_o_1; + wire [`RegAddrBus] ex_reg_waddr_o_1; + wire [`RegBus] ex_reg_wdata_1; + wire [`AluOpBus] ex_aluop_o_1; + + wire mem_wreg_o_1; + wire [`RegAddrBus] mem_reg_waddr_o_1; + wire [`RegBus] mem_reg_wdata_o_1; + + wire stallreq_from_id_1; + wire stallreq_from_ex_1; + + wire [1:0] id_excepttype_o_1; + wire [`RegBus] id_current_inst_address_o_1; + + wire ex_wreg_o_2; + wire [`RegAddrBus] ex_reg_waddr_o_2; + wire [`RegBus] ex_reg_wdata_2; + wire [`AluOpBus] ex_aluop_o_2; + + wire mem_wreg_o_2; + wire [`RegAddrBus] mem_reg_waddr_o_2; + wire [`RegBus] mem_reg_wdata_o_2; + + wire [`RegAddrBus] reg1_addr_2; + wire [`RegAddrBus] reg2_addr_2; + + wire [`RegBus] link_addr_1; + wire [`RegBus] link_addr_2; + + wire [`RegAddrBus] id_reg_waddr_2; + + wire stallreq_to_next_1; + wire stallreq_to_next_2; + + wire id_excp_o_1; + wire [8:0] id_excp_num_o_1; + wire id_excp_o_2; + wire [8:0] id_excp_num_o_2; + + + id u_id_1 ( + .rst(rst), + .pc_i(id_pc_1), + .inst_i(id_inst_1), + + .pc_i_other(pc_buffer_2), + + .reg1_data_i(reg1_data_1), + .reg2_data_i(reg2_data_1), + + .ex_wreg_i_1 (ex_wreg_o_1), + .ex_waddr_i_1(ex_reg_waddr_o_1), + .ex_wdata_i_1(ex_reg_wdata_1), + .ex_aluop_i_1(ex_aluop_o_1), + + .ex_wreg_i_2 (ex_wreg_o_2), + .ex_waddr_i_2(ex_reg_waddr_o_2), + .ex_wdata_i_2(ex_reg_wdata_2), + .ex_aluop_i_2(ex_aluop_o_2), + + .mem_wreg_i_1 (mem_wreg_o_1), + .mem_waddr_i_1(mem_reg_waddr_o_1), + .mem_wdata_i_1(mem_reg_wdata_o_1), + + .mem_wreg_i_2 (mem_wreg_o_2), + .mem_waddr_i_2(mem_reg_waddr_o_2), + .mem_wdata_i_2(mem_reg_wdata_o_2), + + .reg1_read_o(reg1_read_1), + .reg2_read_o(reg2_read_1), + + .reg1_addr_o(reg1_addr_1), + .reg2_addr_o(reg2_addr_1), + + .aluop_o (id_aluop_1), + .alusel_o (id_alusel_1), + .reg1_o (id_reg1_1), + .reg2_o (id_reg2_1), + .reg_waddr_o(id_reg_waddr_1), + .wreg_o (id_wreg_1), + .inst_valid (id_inst_valid_1), + .inst_pc (id_inst_pc_1), + .inst_o (id_inst_o_1), + .csr_we (id_csr_we_1), + .csr_addr_o (id_csr_addr_o_1), + .csr_data_o (id_csr_data_o_1), + + .csr_read_addr_o(id_csr_read_addr_o_1), + .csr_data_i(id_csr_data_1), + .has_int(has_int), + .csr_plv(csr_plv), + + .excp_i(if_excp_o_1), + .excp_num_i(if_excp_num_o_1), + .excp_o(id_excp_o_1), + .excp_num_o(id_excp_num_o_1), + + .branch_flag_o(branch_flag_1), + .branch_target_address_o(branch_target_address_1), + .link_addr_o(link_addr_1), + + .stallreq(stallreq_to_next_1), + .idle_stallreq(), + + .excepttype_o(id_excepttype_o_1), + .current_inst_address_o(id_current_inst_address_o_1) + ); + + wire [`AluOpBus] id_aluop_2; + wire [`AluSelBus] id_alusel_2; + wire [`RegBus] id_reg1_2; + wire [`RegBus] id_reg2_2; + + wire id_wreg_2; + wire id_inst_valid_2; + wire [`InstAddrBus] id_inst_pc_2; + wire [`RegBus] id_inst_o_2; + + wire reg1_read_2; + wire reg2_read_2; + wire [`RegBus] reg1_data_2; + wire [`RegBus] reg2_data_2; + + + + wire stallreq_from_id_2; + wire stallreq_from_ex_2; + + wire [1:0] id_excepttype_o_2; + wire [`RegBus] id_current_inst_address_o_2; + + + + id u_id_2 ( + .rst(rst), + .pc_i(id_pc_2), + .inst_i(id_inst_2), + + .pc_i_other(pc_buffer_1), + + .reg1_data_i(reg1_data_2), + .reg2_data_i(reg2_data_2), + + .ex_wreg_i_1 (ex_wreg_o_2), + .ex_waddr_i_1(ex_reg_waddr_o_2), + .ex_wdata_i_1(ex_reg_wdata_2), + .ex_aluop_i_1(ex_aluop_o_2), + + .ex_wreg_i_2 (ex_wreg_o_1), + .ex_waddr_i_2(ex_reg_waddr_o_1), + .ex_wdata_i_2(ex_reg_wdata_1), + .ex_aluop_i_2(ex_aluop_o_1), + + .mem_wreg_i_1 (mem_wreg_o_2), + .mem_waddr_i_1(mem_reg_waddr_o_2), + .mem_wdata_i_1(mem_reg_wdata_o_2), + + .mem_wreg_i_2 (mem_wreg_o_1), + .mem_waddr_i_2(mem_reg_waddr_o_1), + .mem_wdata_i_2(mem_reg_wdata_o_1), + + .reg1_read_o(reg1_read_2), + .reg2_read_o(reg2_read_2), + + .reg1_addr_o(reg1_addr_2), + .reg2_addr_o(reg2_addr_2), + + .aluop_o (id_aluop_2), + .alusel_o (id_alusel_2), + .reg1_o (id_reg1_2), + .reg2_o (id_reg2_2), + .reg_waddr_o(id_reg_waddr_2), + .wreg_o (id_wreg_2), + .inst_valid (id_inst_valid_2), + .inst_pc (id_inst_pc_2), + .inst_o (id_inst_o_2), + + .csr_we(id_csr_we_2), + .csr_addr_o(id_csr_addr_o_2), + .csr_data_i(id_csr_data_2), + + .csr_read_addr_o(id_csr_read_addr_o_2), + .csr_data_o(id_csr_data_o_2), + .has_int(has_int), + .csr_plv(csr_plv), + + .excp_i(if_excp_o_2), + .excp_num_i(if_excp_num_o_2), + .excp_o(id_excp_o_2), + .excp_num_o(id_excp_num_o_2), + + .branch_flag_o(branch_flag_2), + .branch_target_address_o(branch_target_address_2), + .link_addr_o(link_addr_2), + + .stallreq(stallreq_to_next_2), + .idle_stallreq(), + + .excepttype_o(id_excepttype_o_2), + .current_inst_address_o(id_current_inst_address_o_2) + + ); + + wire [`AluOpBus] ex_aluop_1; + wire [`AluSelBus] ex_alusel_1; + wire [`RegBus] ex_reg1_1; + wire [`RegBus] ex_reg2_1; + wire [`RegAddrBus] ex_reg_waddr_i_1; + wire ex_wreg_i_1; + wire ex_inst_valid_i_1; + wire [`InstAddrBus] ex_inst_pc_i_1; + wire [`RegBus] ex_link_address_1; + wire [`RegBus] ex_inst_i_1; + wire [1:0] ex_excepttype_i_1; + wire [`RegBus] ex_current_inst_address_i_1; + wire ex_csr_we_i_1; + wire [13:0] ex_csr_addr_i_1; + wire [31:0] ex_csr_data_i_1; + + wire ex_excp_i_1; + wire [8:0] ex_excp_num_i_1; + wire ex_excp_o_1; + wire [8:0] ex_excp_num_i_2; + + id_ex id_ex_1 ( + .clk (clk), + .rst (rst), + .stall(stall1[3]), + + .id_aluop(id_aluop_1), + .id_alusel(id_alusel_1), + .id_reg1(id_reg1_1), + .id_reg2(id_reg2_1), + .id_wd(id_reg_waddr_1), + .id_wreg(id_wreg_1), + .id_inst_pc(id_inst_pc_1), + .id_inst_valid(id_inst_valid_1), + .id_link_address(link_addr_1), + .id_inst(id_inst_o_1), + .flush(flush), + .id_excepttype(id_excepttype_o_1), + .id_current_inst_address(id_current_inst_address_o_1), + .id_csr_we(id_csr_we_1), + .id_csr_addr(id_csr_addr_o_1), + .id_csr_data(id_csr_data_o_1), + + .ex_aluop(ex_aluop_1), + .ex_alusel(ex_alusel_1), + .ex_reg1(ex_reg1_1), + .ex_reg2(ex_reg2_1), + .ex_wd(ex_reg_waddr_i_1), + .ex_wreg(ex_wreg_i_1), + .ex_inst_pc(ex_inst_pc_i_1), + .ex_inst_valid(ex_inst_valid_i_1), + .ex_link_address(ex_link_address_1), + .ex_inst(ex_inst_i_1), + .ex_excepttype(ex_excepttype_i_1), + .ex_current_inst_address(ex_current_inst_address_i_1), + .ex_csr_we(ex_csr_we_i_1), + .ex_csr_addr(ex_csr_addr_i_1), + .ex_csr_data(ex_csr_data_i_1), + + .reg1_addr_i(reg1_addr_1), + .reg2_addr_i(reg2_addr_1), + .pc_i_other(id_inst_pc_2), + .reg1_addr_i_other(reg1_addr_2), + .reg2_addr_i_other(reg2_addr_2), + .waddr_i_other(id_reg_waddr_2), + + .stallreq_from_id(stallreq_to_next_1), + .stallreq(stallreq_from_id_1), + + .excp_i(id_excp_o_1), + .excp_num_i(id_excp_num_o_1), + .excp_o(ex_excp_i_1), + .excp_num_o(ex_excp_num_i_1), + + .excp_flush(excp_flush), + .ertn_flush(ertn_flush) + ); + + wire [`AluOpBus] ex_aluop_2; + wire [`AluSelBus] ex_alusel_2; + wire [`RegBus] ex_reg1_2; + wire [`RegBus] ex_reg2_2; + wire [`RegAddrBus] ex_reg_waddr_i_2; + wire ex_wreg_i_2; + wire ex_inst_valid_i_2; + wire [`InstAddrBus] ex_inst_pc_i_2; + wire [`RegBus] ex_link_address_2; + wire [`RegBus] ex_inst_i_2; + wire [1:0] ex_excepttype_i_2; + wire [`RegBus] ex_current_inst_address_i_2; + wire ex_csr_we_i_2; + wire [13:0] ex_csr_addr_i_2; + wire [31:0] ex_csr_data_i_2; + + wire ex_excp_i_2; + wire [9:0] ex_excp_num_o_1; + wire ex_excp_o_2; + wire [9:0] ex_excp_num_o_2; + + id_ex id_ex_2 ( + .clk (clk), + .rst (rst), + .stall(stall2[3]), + + .id_aluop(id_aluop_2), + .id_alusel(id_alusel_2), + .id_reg1(id_reg1_2), + .id_reg2(id_reg2_2), + .id_wd(id_reg_waddr_2), + .id_wreg(id_wreg_2), + .id_inst_pc(id_inst_pc_2), + .id_inst_valid(id_inst_valid_2), + .id_link_address(link_addr_2), + .id_inst(id_inst_o_2), + .flush(flush), + .id_excepttype(id_excepttype_o_2), + .id_current_inst_address(id_current_inst_address_o_2), + .id_csr_we(id_csr_we_2), + .id_csr_addr(id_csr_addr_o_2), + .id_csr_data(id_csr_data_o_2), + + .ex_aluop(ex_aluop_2), + .ex_alusel(ex_alusel_2), + .ex_reg1(ex_reg1_2), + .ex_reg2(ex_reg2_2), + .ex_wd(ex_reg_waddr_i_2), + .ex_wreg(ex_wreg_i_2), + .ex_inst_pc(ex_inst_pc_i_2), + .ex_inst_valid(ex_inst_valid_i_2), + .ex_link_address(ex_link_address_2), + .ex_inst(ex_inst_i_2), + .ex_excepttype(ex_excepttype_i_2), + .ex_current_inst_address(ex_current_inst_address_i_2), + .ex_csr_we(ex_csr_we_i_2), + .ex_csr_addr(ex_csr_addr_i_2), + .ex_csr_data(ex_csr_data_i_2), + + .reg1_addr_i(reg1_addr_2), + .reg2_addr_i(reg2_addr_2), + .pc_i_other(id_inst_pc_1), + .reg1_addr_i_other(reg1_addr_1), + .reg2_addr_i_other(reg2_addr_2), + .waddr_i_other(id_reg_waddr_1), + + .stallreq_from_id(stallreq_to_next_2), + .stallreq(stallreq_from_id_2), + + .excp_i(id_excp_o_2), + .excp_num_i(id_excp_num_o_2), + .excp_o(ex_excp_i_2), + .excp_num_o(ex_excp_num_i_2), + + .excp_flush(excp_flush), + .ertn_flush(ertn_flush) + ); + + + wire ex_inst_valid_o_1; + wire [`InstAddrBus] ex_inst_pc_o_1; + wire [`RegBus] ex_addr_o_1; + wire [`RegBus] ex_reg2_o_1; + wire [1:0] ex_excepttype_o_1; + wire [`RegBus] ex_current_inst_address_o_1; + wire ex_csr_we_o_1; + wire [13:0] ex_csr_addr_o_1; + wire [31:0] ex_csr_data_o_1; + + + + ex u_ex_1 ( + .rst(rst), + + .aluop_i(ex_aluop_1), + .alusel_i(ex_alusel_1), + .reg1_i(ex_reg1_1), + .reg2_i(ex_reg2_1), + .wd_i(ex_reg_waddr_i_1), + .wreg_i(ex_wreg_i_1), + .inst_valid_i(ex_inst_valid_i_1), + .inst_pc_i(ex_inst_pc_i_1), + .inst_i(ex_inst_i_1), + .link_addr_i(ex_link_address_1), + .excepttype_i(ex_excepttype_i_1), + .current_inst_address_i(ex_current_inst_address_i_1), + .ex_csr_we_i(ex_csr_we_i_1), + .ex_csr_addr_i(ex_csr_addr_i_1), + .ex_csr_data_i(ex_csr_data_i_1), + + .wd_o(ex_reg_waddr_o_1), + .wreg_o(ex_wreg_o_1), + .wdata_o(ex_reg_wdata_1), + .inst_valid_o(ex_inst_valid_o_1), + .inst_pc_o(ex_inst_pc_o_1), + .aluop_o(ex_aluop_o_1), + .mem_addr_o(ex_addr_o_1), + .reg2_o(ex_reg2_o_1), + .excepttype_o(ex_excepttype_o_1), + .current_inst_address_o(ex_current_inst_address_o_1), + .ex_csr_we_o(ex_csr_we_o_1), + .ex_csr_addr_o(ex_csr_addr_o_1), + .ex_csr_data_o(ex_csr_data_o_1), + + .stallreq(stallreq_from_ex_1), + + .excp_i(ex_excp_i_1), + .excp_num_i(ex_excp_num_i_1), + .excp_o(ex_excp_o_1), + .excp_num_o(ex_excp_num_o_1) + ); + + wire ex_inst_valid_o_2; + wire [`InstAddrBus] ex_inst_pc_o_2; + wire [`RegBus] ex_addr_o_2; + wire [`RegBus] ex_reg2_o_2; + wire [1:0] ex_excepttype_o_2; + wire [`RegBus] ex_current_inst_address_o_2; + wire ex_csr_we_o_2; + wire [13:0] ex_csr_addr_o_2; + wire [31:0] ex_csr_data_o_2; + + + ex u_ex_2 ( + .rst(rst), + + .aluop_i(ex_aluop_2), + .alusel_i(ex_alusel_2), + .reg1_i(ex_reg1_2), + .reg2_i(ex_reg2_2), + .wd_i(ex_reg_waddr_i_2), + .wreg_i(ex_wreg_i_2), + .inst_valid_i(ex_inst_valid_i_2), + .inst_pc_i(ex_inst_pc_i_2), + .inst_i(ex_inst_i_2), + .link_addr_i(ex_link_address_2), + .excepttype_i(ex_excepttype_i_2), + .current_inst_address_i(ex_current_inst_address_i_2), + .ex_csr_we_i(ex_csr_we_i_2), + .ex_csr_addr_i(ex_csr_addr_i_2), + .ex_csr_data_i(ex_csr_data_i_2), + + .wd_o(ex_reg_waddr_o_2), + .wreg_o(ex_wreg_o_2), + .wdata_o(ex_reg_wdata_2), + .inst_valid_o(ex_inst_valid_o_2), + .inst_pc_o(ex_inst_pc_o_2), + .aluop_o(ex_aluop_o_2), + .mem_addr_o(ex_addr_o_2), + .reg2_o(ex_reg2_o_2), + .excepttype_o(ex_excepttype_o_2), + .current_inst_address_o(ex_current_inst_address_o_2), + .ex_csr_we_o(ex_csr_we_o_2), + .ex_csr_addr_o(ex_csr_addr_o_2), + .ex_csr_data_o(ex_csr_data_o_2), + + .stallreq(stallreq_from_ex_2), + + .excp_i(ex_excp_i_2), + .excp_num_i(ex_excp_num_i_2), + .excp_o(ex_excp_o_2), + .excp_num_o(ex_excp_num_o_2) + ); + + + wire mem_wreg_i_1; + wire [`RegAddrBus] mem_reg_waddr_i_1; + wire [`RegBus] mem_reg_wdata_i_1; + + wire mem_inst_valid_1; + wire [`InstAddrBus] mem_inst_pc_1; + + wire [`AluOpBus] mem_aluop_i_1; + wire [`RegBus] mem_addr_i_1; + wire [`RegBus] mem_reg2_i_1; + wire [1:0] mem_excepttype_i_1; + wire [`RegBus] mem_current_inst_address_i_1; + + wire mem_csr_we_i_1; + wire [13:0] mem_csr_addr_i_1; + wire [31:0] mem_csr_data_i_1; + + wire mem_excp_i_1; + wire [9:0] mem_excp_num_i_1; + wire mem_excp_i_2; + wire [9:0] mem_excp_num_i_2; + + ex_mem u_ex_mem_1 ( + .clk (clk), + .rst (rst), + .stall(stall1[4]), + + .ex_wd (ex_reg_waddr_o_1), + .ex_wreg (ex_wreg_o_1), + .ex_wdata (ex_reg_wdata_1), + .ex_inst_pc (ex_inst_pc_o_1), + .ex_inst_valid (ex_inst_valid_o_1), + .ex_aluop (ex_aluop_o_1), + .ex_mem_addr (ex_addr_o_1), + .ex_reg2 (ex_reg2_o_1), + .flush (flush), + .ex_excepttype (ex_excepttype_o_1), + .ex_current_inst_address(ex_current_inst_address_o_1), + .ex_csr_we (ex_csr_we_o_1), + .ex_csr_addr (ex_csr_addr_o_1), + .ex_csr_data (ex_csr_data_o_1), + + .mem_wd (mem_reg_waddr_i_1), + .mem_wreg (mem_wreg_i_1), + .mem_wdata (mem_reg_wdata_i_1), + .mem_inst_valid (mem_inst_valid_1), + .mem_inst_pc (mem_inst_pc_1), + .mem_aluop (mem_aluop_i_1), + .mem_mem_addr (mem_addr_i_1), + .mem_reg2 (mem_reg2_i_1), + .mem_excepttype (mem_excepttype_i_1), + .mem_current_inst_address(mem_current_inst_address_i_1), + .mem_csr_we (mem_csr_we_i_1), + .mem_csr_addr (mem_csr_addr_i_1), + .mem_csr_data (mem_csr_data_i_1), + + .excp_i(ex_excp_o_1), + .excp_num_i(ex_excp_num_o_1), + .excp_o(mem_excp_i_1), + .excp_num_o(mem_excp_num_i_1), + + .excp_flush(excp_flush), + .ertn_flush(ertn_flush) + + ); + + + wire mem_wreg_i_2; + wire [`RegAddrBus] mem_reg_waddr_i_2; + wire [`RegBus] mem_reg_wdata_i_2; + + wire mem_inst_valid_2; + wire [`InstAddrBus] mem_inst_pc_2; + + wire [`AluOpBus] mem_aluop_i_2; + wire [`RegBus] mem_addr_i_2; + wire [`RegBus] mem_reg2_i_2; + wire [1:0] mem_excepttype_i_2; + wire [`RegBus] mem_current_inst_address_i_2; + wire mem_csr_we_i_2; + wire [13:0] mem_csr_addr_i_2; + wire [31:0] mem_csr_data_i_2; + + + ex_mem u_ex_mem_2 ( + .clk (clk), + .rst (rst), + .stall(stall2[4]), + + .ex_wd (ex_reg_waddr_o_2), + .ex_wreg (ex_wreg_o_2), + .ex_wdata (ex_reg_wdata_2), + .ex_inst_pc (ex_inst_pc_o_2), + .ex_inst_valid (ex_inst_valid_o_2), + .ex_aluop (ex_aluop_o_2), + .ex_mem_addr (ex_addr_o_2), + .ex_reg2 (ex_reg2_o_2), + .flush (flush), + .ex_excepttype (ex_excepttype_o_2), + .ex_current_inst_address(ex_current_inst_address_o_2), + .ex_csr_we (ex_csr_we_o_1), + .ex_csr_addr (ex_csr_addr_o_1), + .ex_csr_data (ex_csr_data_o_1), + + .mem_wd (mem_reg_waddr_i_2), + .mem_wreg (mem_wreg_i_2), + .mem_wdata (mem_reg_wdata_i_2), + .mem_inst_valid (mem_inst_valid_2), + .mem_inst_pc (mem_inst_pc_2), + .mem_aluop (mem_aluop_i_2), + .mem_mem_addr (mem_addr_i_2), + .mem_reg2 (mem_reg2_i_2), + .mem_excepttype (mem_excepttype_i_2), + .mem_current_inst_address(mem_current_inst_address_i_2), + .mem_csr_we (mem_csr_we_i_2), + .mem_csr_addr (mem_csr_addr_i_2), + .mem_csr_data (mem_csr_data_i_2), + + .excp_i(ex_excp_o_2), + .excp_num_i(ex_excp_num_o_2), + .excp_o(mem_excp_i_2), + .excp_num_o(mem_excp_num_i_2), + + .excp_flush(excp_flush), + .ertn_flush(ertn_flush) + + ); + + wire LLbit_o_1; + wire wb_LLbit_we_i_1; + wire wb_LLbit_value_i_1; + wire mem_LLbit_we_o_1; + wire mem_LLbit_value_o_1; + wire [1:0] mem_excepttype_o_1; + wire [1:0] mem_excepttype_o_2; + wire [`RegBus] mem_current_inst_address_o_1; + wire [`InstAddrBus] wb_inst_pc_1; + wire mem_csr_we_o_1; + wire [13:0] mem_csr_addr_o_1; + wire [31:0] mem_csr_data_o_1; + + wire mem_excp_o_1; + wire [15:0] mem_excp_num_o_1; + wire mem_excp_o_2; + wire [15:0] mem_excp_num_o_2; + + wire [`AluOpBus] mem_aluop_o_1; + wire [`AluOpBus] mem_aluop_o_2; + + wire data_addr_trans_en_1; + wire data_dmw0_en_1; + wire data_dmw1_en_1; + + wire data_addr_trans_en_2; + wire data_dmw0_en_2; + wire data_dmw1_en_2; + + + + mem u_mem_1 ( + .rst(rst), + + .inst_pc_i (mem_inst_pc_1), + .wd_i (mem_reg_waddr_i_1), + .wreg_i (mem_wreg_i_1), + .wdata_i (mem_reg_wdata_i_1), + .aluop_i (mem_aluop_i_1), .mem_addr_i(mem_addr_i_1), - .reg2_i(mem_reg2_i_1), + .reg2_i (mem_reg2_i_1), .mem_data_i(dram_data_i_1), @@ -993,21 +993,21 @@ module cpu_top ( .excepttype_i(mem_excepttype_i_1), .current_inst_address_i(mem_current_inst_address_i_1), - .mem_csr_we_i(mem_csr_we_i_1), + .mem_csr_we_i (mem_csr_we_i_1), .mem_csr_addr_i(mem_csr_addr_i_1), .mem_csr_data_i(mem_csr_data_i_1), .inst_pc_o(wb_inst_pc_1), - .wd_o (mem_reg_waddr_o_1), - .wreg_o (mem_wreg_o_1 ), - .wdata_o (mem_reg_wdata_o_1 ), - .aluop_o(mem_aluop_i_1), + .wd_o (mem_reg_waddr_o_1), + .wreg_o (mem_wreg_o_1), + .wdata_o (mem_reg_wdata_o_1), + .aluop_o (mem_aluop_i_1), .mem_addr_o(dram_addr_o_1), - .mem_we_o(dram_we_o_1), - .mem_sel_o(dram_sel_o_1), + .mem_we_o (dram_we_o_1), + .mem_sel_o (dram_sel_o_1), .mem_data_o(dram_data_o_1), - .mem_ce_o(dram_ce_o_1), + .mem_ce_o (dram_ce_o_1), .LLbit_we_o(mem_LLbit_we_o_1), .LLbit_value_o(mem_LLbit_value_o_1), @@ -1015,10 +1015,10 @@ module cpu_top ( .excepttype_o(mem_excepttype_o_1), .current_inst_address_o(mem_current_inst_address_o_1), - .mem_csr_we_o(mem_csr_we_o_1), + .mem_csr_we_o (mem_csr_we_o_1), .mem_csr_addr_o(mem_csr_addr_o_1), .mem_csr_data_o(mem_csr_data_o_1), - + .excp_i(mem_excp_i_1), .excp_num_i(mem_excp_num_i_1), .excp_o(mem_excp_o_1), @@ -1044,31 +1044,31 @@ module cpu_top ( .data_tlb_mat(data_tlb_mat), .data_tlb_plv(data_tlb_plv) - ); - - wire LLbit_o_2; - wire wb_LLbit_we_i_2; - wire wb_LLbit_value_i_2; - wire mem_LLbit_we_o_2; - wire mem_LLbit_value_o_2; - wire[`RegBus] mem_current_inst_address_o_2 ; - wire[`InstAddrBus] wb_inst_pc_2; - wire mem_csr_we_o_2; - wire [13:0] mem_csr_addr_o_2; - wire [31:0] mem_csr_data_o_2; - - - - mem u_mem_2( - .rst (rst ), - - .inst_pc_i(mem_inst_pc_2), - .wd_i (mem_reg_waddr_i_2 ), - .wreg_i (mem_wreg_i_2 ), - .wdata_i (mem_reg_wdata_i_2), - .aluop_i(mem_aluop_i_2), + ); + + wire LLbit_o_2; + wire wb_LLbit_we_i_2; + wire wb_LLbit_value_i_2; + wire mem_LLbit_we_o_2; + wire mem_LLbit_value_o_2; + wire [`RegBus] mem_current_inst_address_o_2; + wire [`InstAddrBus] wb_inst_pc_2; + wire mem_csr_we_o_2; + wire [13:0] mem_csr_addr_o_2; + wire [31:0] mem_csr_data_o_2; + + + + mem u_mem_2 ( + .rst(rst), + + .inst_pc_i (mem_inst_pc_2), + .wd_i (mem_reg_waddr_i_2), + .wreg_i (mem_wreg_i_2), + .wdata_i (mem_reg_wdata_i_2), + .aluop_i (mem_aluop_i_2), .mem_addr_i(mem_addr_i_2), - .reg2_i(mem_reg2_i_2), + .reg2_i (mem_reg2_i_2), .mem_data_i(dram_data_i_2), @@ -1079,21 +1079,21 @@ module cpu_top ( .excepttype_i(mem_excepttype_i_2), .current_inst_address_i(mem_current_inst_address_i_2), - .mem_csr_we_i(mem_csr_we_i_2), + .mem_csr_we_i (mem_csr_we_i_2), .mem_csr_addr_i(mem_csr_addr_i_2), .mem_csr_data_i(mem_csr_data_i_2), .inst_pc_o(wb_inst_pc_2), - .wd_o (mem_reg_waddr_o_2), - .wreg_o (mem_wreg_o_2 ), - .wdata_o (mem_reg_wdata_o_2 ), - .aluop_o(mem_aluop_o_2), + .wd_o (mem_reg_waddr_o_2), + .wreg_o (mem_wreg_o_2), + .wdata_o (mem_reg_wdata_o_2), + .aluop_o (mem_aluop_o_2), .mem_addr_o(dram_addr_o_2), - .mem_we_o(dram_we_o_2), - .mem_sel_o(dram_sel_o_2), + .mem_we_o (dram_we_o_2), + .mem_sel_o (dram_sel_o_2), .mem_data_o(dram_data_o_2), - .mem_ce_o(dram_ce_o_2), + .mem_ce_o (dram_ce_o_2), .LLbit_we_o(mem_LLbit_we_o_2), .LLbit_value_o(mem_LLbit_value_o_2), @@ -1101,7 +1101,7 @@ module cpu_top ( .excepttype_o(mem_excepttype_o_2), .current_inst_address_o(mem_current_inst_address_o_2), - .mem_csr_we_o(mem_csr_we_o_2), + .mem_csr_we_o (mem_csr_we_o_2), .mem_csr_addr_o(mem_csr_addr_o_2), .mem_csr_data_o(mem_csr_data_o_2), @@ -1130,347 +1130,347 @@ module cpu_top ( .data_tlb_mat(data_tlb_mat), .data_tlb_plv(data_tlb_plv) - ); - - assign dram_pc_o_1 = wb_inst_pc_1; - assign dram_pc_o_2 = wb_inst_pc_2; - - wire wb_wreg_1; - wire[`RegAddrBus] wb_reg_waddr_1; - wire[`RegBus] wb_reg_wdata_1; - - wire wb_csr_we_1; - wire[13:0] wb_csr_addr_1; - wire[`RegBus] wb_csr_data_1; - - assign debug_commit_wreg_1 = wb_wreg_1; - assign debug_commit_reg_waddr_1 = wb_reg_waddr_1; - assign debug_commit_reg_wdata_1 = wb_reg_wdata_1; - - - wire wb_excp_o_1; - wire [15:0] wb_excp_num_o_1; - wire wb_excp_o_2; - wire [15:0] wb_excp_num_o_2; - - wire [`RegBus] wb_csr_era_1; - wire [8:0] wb_csr_esubcode_1; - wire [5:0] wb_csr_ecode_1; - - wire wb_va_error_1; - wire [`RegBus]wb_bad_va_1; - wire excp_tlbrefill_1; - wire [18:0] excp_tlb_vppn_1; - - mem_wb mem_wb_1( - .clk(clk), - .rst(rst), - .stall(stall1[5]), - - .mem_wd(mem_reg_waddr_o_1), - .mem_wreg(mem_wreg_o_1), - .mem_wdata(mem_reg_wdata_o_1), - .mem_inst_pc (mem_inst_pc_1 ), - .mem_instr ( ), - .mem_aluop(mem_aluop_o_1), - .mem_inst_valid (mem_inst_valid_1 ), - - .mem_LLbit_we(mem_LLbit_we_o_1), - .mem_LLbit_value(mem_LLbit_value_o_1), - - .flush(flush), - - .mem_csr_we(mem_csr_we_o_1), - .mem_csr_addr(mem_csr_addr_o_1), - .mem_csr_data(mem_csr_data_o_1), - - .wb_wd(wb_reg_waddr_1), - .wb_wreg(wb_wreg_1), - .wb_wdata(wb_reg_wdata_1), - - .wb_LLbit_we(wb_LLbit_we_i_1), - .wb_LLbit_value(wb_LLbit_value_i_1), - - .wb_csr_we(wb_csr_we_1), - .wb_csr_addr(wb_csr_addr_1), - .wb_csr_data(wb_csr_data_1), - - .debug_commit_pc (debug_commit_pc_1 ), - .debug_commit_valid (debug_commit_valid_1 ), - .debug_commit_instr (debug_commit_instr_1 ), - - .excp_i(mem_excp_o_1), - .excp_num_i(mem_excp_num_o_1), - .excp_o(wb_excp_o_1), - .excp_num_o(wb_excp_num_o_1), - - .csr_era(wb_csr_era_1), - .csr_esubcode(wb_csr_esubcode_1), - .csr_ecode(wb_csr_ecode_1), - .excp_flush(excp_flush_1), - .ertn_flush(ertn_flush_1), - .va_error(wb_va_error_1), - .bad_va(wb_bad_va_1), - .excp_tlbrefill(excp_tlbrefill_1), - .excp_tlb_vppn(excp_tlb_vppn_1) - ); - - wire wb_wreg_2; - wire[`RegAddrBus] wb_reg_waddr_2; - wire[`RegBus] wb_reg_wdata_2; - - wire wb_csr_we_2; - wire[13:0] wb_csr_addr_2; - wire[`RegBus] wb_csr_data_2; - - assign debug_commit_wreg_2 = wb_wreg_2; - assign debug_commit_reg_waddr_2 = wb_reg_waddr_2; - assign debug_commit_reg_wdata_2 = wb_reg_wdata_2; - - wire [`RegBus] wb_csr_era_2; - wire [8:0] wb_csr_esubcode_2; - wire [5:0] wb_csr_ecode_2; - - wire wb_va_error_2; - wire [`RegBus]wb_bad_va_2; - wire excp_tlbrefill_2; - wire [18:0] excp_tlb_vppn_2; - - mem_wb mem_wb_2( - .clk(clk), - .rst(rst), - .stall(stall2[5]), - - .mem_wd(mem_reg_waddr_o_2), - .mem_wreg(mem_wreg_o_2), - .mem_wdata(mem_reg_wdata_o_2), - .mem_inst_pc (mem_inst_pc_2 ), - .mem_instr ( ), - .mem_aluop(mem_aluop_o_2), - .mem_inst_valid (mem_inst_valid_2 ), - - .mem_LLbit_we(mem_LLbit_we_o_2), - .mem_LLbit_value(mem_LLbit_value_o_2), - - .flush(flush), - - .mem_csr_we(mem_csr_we_o_2), - .mem_csr_addr(mem_csr_addr_o_2), - .mem_csr_data(mem_csr_data_o_2), - - .wb_wd(wb_reg_waddr_2), - .wb_wreg(wb_wreg_2), - .wb_wdata(wb_reg_wdata_2), - - .wb_LLbit_we(wb_LLbit_we_i), - .wb_LLbit_value(wb_LLbit_value_2), - - .wb_csr_we(wb_csr_we_2), - .wb_csr_addr(wb_csr_addr_2), - .wb_csr_data(wb_csr_data_2), - - .debug_commit_pc (debug_commit_pc_2 ), - .debug_commit_valid (debug_commit_valid_2 ), - .debug_commit_instr (debug_commit_instr_2 ), - - .excp_i(mem_excp_o_2), - .excp_num_i(mem_excp_num_o_2), - .excp_o(wb_excp_o_2), - .excp_num_o(wb_excp_num_o_2), - - .csr_era(wb_csr_era_2), - .csr_esubcode(wb_csr_esubcode_2), - .csr_ecode(wb_csr_ecode_2), - .excp_flush(excp_flush_2), - .ertn_flush(ertn_flush_2), - .va_error(wb_va_error_2), - .bad_va(wb_bad_va_2), - .excp_tlbrefill(excp_tlbrefill_2), - .excp_tlb_vppn(excp_tlb_vppn_2) - ); - - regfile u_regfile( - .clk(clk), - .rst(rst), - - .we_1 (wb_wreg_1), - .pc_i_1 (), - .waddr_1 (wb_reg_waddr_1), - .wdata_1 (wb_reg_wdata_1), - .we_2 (wb_wreg_2), - .pc_i_2 (), - .waddr_2 (wb_reg_waddr_2), - .wdata_2 (wb_reg_wdata_2), - - .re1_1 (reg1_read_1), - .raddr1_1 (reg1_addr_1), - .rdata1_1 (reg1_data_1), - .re2_1 (reg2_read_1), - .raddr2_1 (reg2_addr_1), - .rdata2_1 (reg2_data_1), - .re1_2 (reg1_read_2), - .raddr1_2 (reg1_addr_2), - .rdata1_2 (reg1_data_2), - .re2_2 (reg2_read_2), - .raddr2_2 (reg2_addr_2), - .rdata2_2 (reg2_data_2), - .debug_reg(debug_reg) - ); - - ctrl u_ctrl( - .clk(clk), - .rst(rst), - .stall1(stall1), - .stallreq_from_id_1(stallreq_from_id_1), - .stallreq_from_ex_1(stallreq_from_ex_1), - .stall2(stall2), - .stallreq_from_id_2(stallreq_from_id_2), - .stallreq_from_ex_2(stallreq_from_ex_2), - .idle_stallreq(), - .excepttype_i_1(mem_excepttype_o_1), - .excepttype_i_2(mem_excepttype_o_2), - .new_pc(new_pc), - .flush(flush) - ); - - LLbit_reg u_LLbit_reg( - .clk(clk), - .rst(rst), - .flush(1'b0), - .LLbit_i_1(wb_LLbit_value_i_1), - .LLbit_i_2(wb_LLbit_value_i_2), - .we(wb_LLbit_we_i), - .LLbit_o(LLbit_o) - ); - - - //目前没有进行冲突处理,是假设不会同时出现两条异常同时发生 - assign wb_csr_era = wb_csr_era_1 | wb_csr_era_2; - assign wb_csr_ecode = wb_csr_ecode_1 | wb_csr_ecode_2; - assign wb_csr_esubcode = wb_csr_esubcode_1 | wb_csr_esubcode_2; - assign excp_flush = excp_flush_1 | excp_flush_2; - assign ertn_flush = ertn_flush_1 | ertn_flush_2; - assign wb_va_error = wb_va_error_1 | wb_va_error_2; - assign wb_bad_va = wb_bad_va_1 | wb_bad_va_2; - assign excp_tlbrefill = excp_tlbrefill_1 | excp_tlbrefill_2; - assign excp_tlb_vppn = excp_tlb_vppn_1 | excp_tlb_vppn_2; - - cs_reg u_cs_reg( - .clk(clk), - .rst(rst), - .waddr_1(wb_csr_addr_1), - .waddr_2(wb_csr_addr_2), - .excp_flush(excp_flush), - .ertn_flush(ertn_flush), - .we_1(wb_csr_we_1), - .we_2(wb_csr_we_2), - .wdata_1(wb_csr_data_1), - .wdata_2(wb_csr_data_2), - .raddr_1(id_csr_read_addr_o_1), - .raddr_2(id_csr_read_addr_o_2), - .rdata_1(id_csr_data_1), - .rdata_2(id_csr_data_2), - .era_i(wb_csr_era), - .esubcode_i(wb_csr_esubcode), - .va_error_i(wb_va_error), - .bad_va_i(wb_bad_va), - .tlbsrch_en(tlbsrch_en), - .tlbsrch_found(tlbsrch_found), - .tlbsrch_index(tlbsrch_index), - .excp_tlbrefill(excp_tlbrefill), - .excp_tlb(excp_tlb), - .excp_tlb_vppn(excp_tlb_vppn), - .has_int(has_int), - .eentry_out(csr_eentry), - .era_out(csr_era), - .tlbrentry_out(csr_tlbrentry), - .asid_out(csr_asid), - .rand_index(rand_index), - .tlbehi_out(tlbw_tlbehi), - .tlbelo0_out(tlbw_tlbelo0), - .tlbelo1_out(tlbw_tlbelo1), - .tlbidx_out(tlbw_r_tlbidx), - .pg_out(csr_pg), - .da_out(csr_da), - .dmw0_out(csr_dmw0), - .dmw1_out(csr_dmw1), - .datf_out(csr_datf), - .datm_out(csr_datm), - .ecode_out(tlbw_ecode), - .tlbrd_en(tlbrd_en), - .tlbehi_in(tlbr_tlbehi), - .tlbelo0_in(tlbr_tlbelo0), - .tlbelo1_in(tlbr_tlbelo1), - .tlbidx_in(tlbr_tlbidx), - .asid_in(tlbr_asid), - .csr_diff(csr_diff) - ); - - - assign data_addr_trans_en = data_addr_trans_en_1 | data_addr_trans_en_2; - assign data_dmw0_en = data_dmw0_en_1 | data_dmw0_en_2; - assign data_dmw1_en = data_dmw1_en_1 | data_dmw1_en_2; - - tlb u_tlb( - .clk(clk), - .asid(csr_asid), - //trans mode - .inst_addr_trans_en(inst_addr_trans_en), - .data_addr_trans_en(data_addr_trans_en), - //inst addr trans - .inst_fetch(fetch_en), - .inst_vaddr(inst_vaddr), - .inst_dmw0_en(inst_dmw0_en), - .inst_dmw1_en(inst_dmw1_en), - .inst_index(inst_index), - .inst_tag (inst_tag), - .inst_offset(inst_offset), - .inst_tlb_found(inst_tlb_found), - .inst_tlb_v(inst_tlb_v), - .inst_tlb_d(inst_tlb_d), - .inst_tlb_mat(inst_tlb_mat), - .inst_tlb_plv(inst_tlb_plv), - //data addr trans - .data_fetch(data_fetch), - .data_vaddr(data_vaddr), - .data_dmw0_en(data_dmw0_en), - .data_dmw1_en(data_dmw1_en), - .cacop_op_mode_di (cacop_op_mode_di), - .data_index (data_index ), - .data_tag (data_tag ), - .data_offset (data_offset ), - .data_tlb_found (data_tlb_found ), - .data_tlb_index (data_tlb_index ), - .data_tlb_v (data_tlb_v ), - .data_tlb_d (data_tlb_d ), - .data_tlb_mat (data_tlb_mat ), - .data_tlb_plv (data_tlb_plv ), - //tlbwr tlbfill tlb write - .tlbfill_en (tlbfill_en ), - .tlbwr_en (tlbwr_en ), - .rand_index (rand_index ), - .tlbehi_in (tlbw_tlbehi ), - .tlbelo0_in (tlbw_tlbelo0 ), - .tlbelo1_in (tlbw_tlbelo1 ), - .tlbidx_in (tlbw_r_tlbidx ), - .ecode_in (tlbw_ecode ), - //tlbp tlb read - .tlbehi_out (tlbr_tlbehi ), - .tlbelo0_out (tlbr_tlbelo0 ), - .tlbelo1_out (tlbr_tlbelo1 ), - .tlbidx_out (tlbr_tlbidx ), - .asid_out (tlbr_asid ), - //invtlb - .invtlb_en (invtlb_en ), - .invtlb_asid (invtlb_asid ), - .invtlb_vpn (invtlb_vpn ), - .invtlb_op (invtlb_op ), - //from csr - .csr_dmw0 (csr_dmw0 ), - .csr_dmw1 (csr_dmw1 ), - .csr_da (csr_da ), - .csr_pg (csr_pg ) - ); + ); + + assign dram_pc_o_1 = wb_inst_pc_1; + assign dram_pc_o_2 = wb_inst_pc_2; + + wire wb_wreg_1; + wire [`RegAddrBus] wb_reg_waddr_1; + wire [`RegBus] wb_reg_wdata_1; + + wire wb_csr_we_1; + wire [13:0] wb_csr_addr_1; + wire [`RegBus] wb_csr_data_1; + + assign debug_commit_wreg_1 = wb_wreg_1; + assign debug_commit_reg_waddr_1 = wb_reg_waddr_1; + assign debug_commit_reg_wdata_1 = wb_reg_wdata_1; + + + wire wb_excp_o_1; + wire [15:0] wb_excp_num_o_1; + wire wb_excp_o_2; + wire [15:0] wb_excp_num_o_2; + + wire [`RegBus] wb_csr_era_1; + wire [8:0] wb_csr_esubcode_1; + wire [5:0] wb_csr_ecode_1; + + wire wb_va_error_1; + wire [`RegBus] wb_bad_va_1; + wire excp_tlbrefill_1; + wire [18:0] excp_tlb_vppn_1; + + mem_wb mem_wb_1 ( + .clk (clk), + .rst (rst), + .stall(stall1[5]), + + .mem_wd (mem_reg_waddr_o_1), + .mem_wreg (mem_wreg_o_1), + .mem_wdata (mem_reg_wdata_o_1), + .mem_inst_pc (mem_inst_pc_1), + .mem_instr (), + .mem_aluop (mem_aluop_o_1), + .mem_inst_valid(mem_inst_valid_1), + + .mem_LLbit_we(mem_LLbit_we_o_1), + .mem_LLbit_value(mem_LLbit_value_o_1), + + .flush(flush), + + .mem_csr_we (mem_csr_we_o_1), + .mem_csr_addr(mem_csr_addr_o_1), + .mem_csr_data(mem_csr_data_o_1), + + .wb_wd(wb_reg_waddr_1), + .wb_wreg(wb_wreg_1), + .wb_wdata(wb_reg_wdata_1), + + .wb_LLbit_we(wb_LLbit_we_i_1), + .wb_LLbit_value(wb_LLbit_value_i_1), + + .wb_csr_we (wb_csr_we_1), + .wb_csr_addr(wb_csr_addr_1), + .wb_csr_data(wb_csr_data_1), + + .debug_commit_pc (debug_commit_pc_1), + .debug_commit_valid(debug_commit_valid_1), + .debug_commit_instr(debug_commit_instr_1), + + .excp_i(mem_excp_o_1), + .excp_num_i(mem_excp_num_o_1), + .excp_o(wb_excp_o_1), + .excp_num_o(wb_excp_num_o_1), + + .csr_era(wb_csr_era_1), + .csr_esubcode(wb_csr_esubcode_1), + .csr_ecode(wb_csr_ecode_1), + .excp_flush(excp_flush_1), + .ertn_flush(ertn_flush_1), + .va_error(wb_va_error_1), + .bad_va(wb_bad_va_1), + .excp_tlbrefill(excp_tlbrefill_1), + .excp_tlb_vppn(excp_tlb_vppn_1) + ); + + wire wb_wreg_2; + wire [`RegAddrBus] wb_reg_waddr_2; + wire [`RegBus] wb_reg_wdata_2; + + wire wb_csr_we_2; + wire [13:0] wb_csr_addr_2; + wire [`RegBus] wb_csr_data_2; + + assign debug_commit_wreg_2 = wb_wreg_2; + assign debug_commit_reg_waddr_2 = wb_reg_waddr_2; + assign debug_commit_reg_wdata_2 = wb_reg_wdata_2; + + wire [`RegBus] wb_csr_era_2; + wire [8:0] wb_csr_esubcode_2; + wire [5:0] wb_csr_ecode_2; + + wire wb_va_error_2; + wire [`RegBus] wb_bad_va_2; + wire excp_tlbrefill_2; + wire [18:0] excp_tlb_vppn_2; + + mem_wb mem_wb_2 ( + .clk (clk), + .rst (rst), + .stall(stall2[5]), + + .mem_wd (mem_reg_waddr_o_2), + .mem_wreg (mem_wreg_o_2), + .mem_wdata (mem_reg_wdata_o_2), + .mem_inst_pc (mem_inst_pc_2), + .mem_instr (), + .mem_aluop (mem_aluop_o_2), + .mem_inst_valid(mem_inst_valid_2), + + .mem_LLbit_we(mem_LLbit_we_o_2), + .mem_LLbit_value(mem_LLbit_value_o_2), + + .flush(flush), + + .mem_csr_we (mem_csr_we_o_2), + .mem_csr_addr(mem_csr_addr_o_2), + .mem_csr_data(mem_csr_data_o_2), + + .wb_wd(wb_reg_waddr_2), + .wb_wreg(wb_wreg_2), + .wb_wdata(wb_reg_wdata_2), + + .wb_LLbit_we(wb_LLbit_we_i), + .wb_LLbit_value(wb_LLbit_value_2), + + .wb_csr_we (wb_csr_we_2), + .wb_csr_addr(wb_csr_addr_2), + .wb_csr_data(wb_csr_data_2), + + .debug_commit_pc (debug_commit_pc_2), + .debug_commit_valid(debug_commit_valid_2), + .debug_commit_instr(debug_commit_instr_2), + + .excp_i(mem_excp_o_2), + .excp_num_i(mem_excp_num_o_2), + .excp_o(wb_excp_o_2), + .excp_num_o(wb_excp_num_o_2), + + .csr_era(wb_csr_era_2), + .csr_esubcode(wb_csr_esubcode_2), + .csr_ecode(wb_csr_ecode_2), + .excp_flush(excp_flush_2), + .ertn_flush(ertn_flush_2), + .va_error(wb_va_error_2), + .bad_va(wb_bad_va_2), + .excp_tlbrefill(excp_tlbrefill_2), + .excp_tlb_vppn(excp_tlb_vppn_2) + ); + + regfile u_regfile ( + .clk(clk), + .rst(rst), + + .we_1 (wb_wreg_1), + .pc_i_1 (), + .waddr_1(wb_reg_waddr_1), + .wdata_1(wb_reg_wdata_1), + .we_2 (wb_wreg_2), + .pc_i_2 (), + .waddr_2(wb_reg_waddr_2), + .wdata_2(wb_reg_wdata_2), + + .re1_1 (reg1_read_1), + .raddr1_1 (reg1_addr_1), + .rdata1_1 (reg1_data_1), + .re2_1 (reg2_read_1), + .raddr2_1 (reg2_addr_1), + .rdata2_1 (reg2_data_1), + .re1_2 (reg1_read_2), + .raddr1_2 (reg1_addr_2), + .rdata1_2 (reg1_data_2), + .re2_2 (reg2_read_2), + .raddr2_2 (reg2_addr_2), + .rdata2_2 (reg2_data_2), + .debug_reg(debug_reg) + ); + + ctrl u_ctrl ( + .clk(clk), + .rst(rst), + .stall1(stall1), + .stallreq_from_id_1(stallreq_from_id_1), + .stallreq_from_ex_1(stallreq_from_ex_1), + .stall2(stall2), + .stallreq_from_id_2(stallreq_from_id_2), + .stallreq_from_ex_2(stallreq_from_ex_2), + .idle_stallreq(), + .excepttype_i_1(mem_excepttype_o_1), + .excepttype_i_2(mem_excepttype_o_2), + .new_pc(new_pc), + .flush(flush) + ); + + LLbit_reg u_LLbit_reg ( + .clk(clk), + .rst(rst), + .flush(1'b0), + .LLbit_i_1(wb_LLbit_value_i_1), + .LLbit_i_2(wb_LLbit_value_i_2), + .we(wb_LLbit_we_i), + .LLbit_o(LLbit_o) + ); + + + //目前没有进行冲突处理,是假设不会同时出现两条异常同时发生 + assign wb_csr_era = wb_csr_era_1 | wb_csr_era_2; + assign wb_csr_ecode = wb_csr_ecode_1 | wb_csr_ecode_2; + assign wb_csr_esubcode = wb_csr_esubcode_1 | wb_csr_esubcode_2; + assign excp_flush = excp_flush_1 | excp_flush_2; + assign ertn_flush = ertn_flush_1 | ertn_flush_2; + assign wb_va_error = wb_va_error_1 | wb_va_error_2; + assign wb_bad_va = wb_bad_va_1 | wb_bad_va_2; + assign excp_tlbrefill = excp_tlbrefill_1 | excp_tlbrefill_2; + assign excp_tlb_vppn = excp_tlb_vppn_1 | excp_tlb_vppn_2; + + cs_reg u_cs_reg ( + .clk(clk), + .rst(rst), + .waddr_1(wb_csr_addr_1), + .waddr_2(wb_csr_addr_2), + .excp_flush(excp_flush), + .ertn_flush(ertn_flush), + .we_1(wb_csr_we_1), + .we_2(wb_csr_we_2), + .wdata_1(wb_csr_data_1), + .wdata_2(wb_csr_data_2), + .raddr_1(id_csr_read_addr_o_1), + .raddr_2(id_csr_read_addr_o_2), + .rdata_1(id_csr_data_1), + .rdata_2(id_csr_data_2), + .era_i(wb_csr_era), + .esubcode_i(wb_csr_esubcode), + .va_error_i(wb_va_error), + .bad_va_i(wb_bad_va), + .tlbsrch_en(tlbsrch_en), + .tlbsrch_found(tlbsrch_found), + .tlbsrch_index(tlbsrch_index), + .excp_tlbrefill(excp_tlbrefill), + .excp_tlb(excp_tlb), + .excp_tlb_vppn(excp_tlb_vppn), + .has_int(has_int), + .eentry_out(csr_eentry), + .era_out(csr_era), + .tlbrentry_out(csr_tlbrentry), + .asid_out(csr_asid), + .rand_index(rand_index), + .tlbehi_out(tlbw_tlbehi), + .tlbelo0_out(tlbw_tlbelo0), + .tlbelo1_out(tlbw_tlbelo1), + .tlbidx_out(tlbw_r_tlbidx), + .pg_out(csr_pg), + .da_out(csr_da), + .dmw0_out(csr_dmw0), + .dmw1_out(csr_dmw1), + .datf_out(csr_datf), + .datm_out(csr_datm), + .ecode_out(tlbw_ecode), + .tlbrd_en(tlbrd_en), + .tlbehi_in(tlbr_tlbehi), + .tlbelo0_in(tlbr_tlbelo0), + .tlbelo1_in(tlbr_tlbelo1), + .tlbidx_in(tlbr_tlbidx), + .asid_in(tlbr_asid), + .csr_diff(csr_diff) + ); + + + assign data_addr_trans_en = data_addr_trans_en_1 | data_addr_trans_en_2; + assign data_dmw0_en = data_dmw0_en_1 | data_dmw0_en_2; + assign data_dmw1_en = data_dmw1_en_1 | data_dmw1_en_2; + + tlb u_tlb ( + .clk (clk), + .asid (csr_asid), + //trans mode + .inst_addr_trans_en(inst_addr_trans_en), + .data_addr_trans_en(data_addr_trans_en), + //inst addr trans + .inst_fetch (fetch_en), + .inst_vaddr (inst_vaddr), + .inst_dmw0_en (inst_dmw0_en), + .inst_dmw1_en (inst_dmw1_en), + .inst_index (inst_index), + .inst_tag (inst_tag), + .inst_offset (inst_offset), + .inst_tlb_found (inst_tlb_found), + .inst_tlb_v (inst_tlb_v), + .inst_tlb_d (inst_tlb_d), + .inst_tlb_mat (inst_tlb_mat), + .inst_tlb_plv (inst_tlb_plv), + //data addr trans + .data_fetch (data_fetch), + .data_vaddr (data_vaddr), + .data_dmw0_en (data_dmw0_en), + .data_dmw1_en (data_dmw1_en), + .cacop_op_mode_di (cacop_op_mode_di), + .data_index (data_index), + .data_tag (data_tag), + .data_offset (data_offset), + .data_tlb_found (data_tlb_found), + .data_tlb_index (data_tlb_index), + .data_tlb_v (data_tlb_v), + .data_tlb_d (data_tlb_d), + .data_tlb_mat (data_tlb_mat), + .data_tlb_plv (data_tlb_plv), + //tlbwr tlbfill tlb write + .tlbfill_en (tlbfill_en), + .tlbwr_en (tlbwr_en), + .rand_index (rand_index), + .tlbehi_in (tlbw_tlbehi), + .tlbelo0_in (tlbw_tlbelo0), + .tlbelo1_in (tlbw_tlbelo1), + .tlbidx_in (tlbw_r_tlbidx), + .ecode_in (tlbw_ecode), + //tlbp tlb read + .tlbehi_out (tlbr_tlbehi), + .tlbelo0_out (tlbr_tlbelo0), + .tlbelo1_out (tlbr_tlbelo1), + .tlbidx_out (tlbr_tlbidx), + .asid_out (tlbr_asid), + //invtlb + .invtlb_en (invtlb_en), + .invtlb_asid (invtlb_asid), + .invtlb_vpn (invtlb_vpn), + .invtlb_op (invtlb_op), + //from csr + .csr_dmw0 (csr_dmw0), + .csr_dmw1 (csr_dmw1), + .csr_da (csr_da), + .csr_pg (csr_pg) + ); endmodule From 123187c3a74382baef2a4a111156a221218bffe5 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Mon, 2 May 2022 15:25:31 +0800 Subject: [PATCH 040/114] fix: fix latch for axi.stall_req_w --- src/vsrc/AXI/axi_master.v | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vsrc/AXI/axi_master.v b/src/vsrc/AXI/axi_master.v index df9fe47..1b04242 100644 --- a/src/vsrc/AXI/axi_master.v +++ b/src/vsrc/AXI/axi_master.v @@ -255,6 +255,7 @@ module axi_master ( else stall_req_w = 1; end default: begin + stall_req_w = 0; end endcase end From 02d895efc7f92b5e5effc21a905be63207c87e87 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Mon, 2 May 2022 15:36:59 +0800 Subject: [PATCH 041/114] docs: update path --- src/vsrc/AXI/README.md | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/vsrc/AXI/README.md b/src/vsrc/AXI/README.md index 0ccaa10..2871a79 100644 --- a/src/vsrc/AXI/README.md +++ b/src/vsrc/AXI/README.md @@ -2,14 +2,9 @@ ## 目录结构 ``` - AXI - AXI_Master/ 主机接口文件夹 - axi_Master axi主机接口,接入cpu_top - axi_MasterThree 失败版本,不用管 - - AXI_Slave/ 空文件夹 - - axi_defines.v 定义了宏的文件 + AXI/ # 本目录 + axi_Master # axi主机接口,接入cpu_top + axi_defines.v # 定义了宏的文件 ``` ## 接口说明 From 8a81e196d9c95eb0ca79909e0d907fba7ed26837 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Mon, 2 May 2022 15:38:00 +0800 Subject: [PATCH 042/114] docs: rename Master to master --- src/vsrc/AXI/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vsrc/AXI/README.md b/src/vsrc/AXI/README.md index 2871a79..3700bdf 100644 --- a/src/vsrc/AXI/README.md +++ b/src/vsrc/AXI/README.md @@ -3,7 +3,7 @@ ## 目录结构 ``` AXI/ # 本目录 - axi_Master # axi主机接口,接入cpu_top + axi_master # axi主机接口,接入cpu_top axi_defines.v # 定义了宏的文件 ``` From 69951f9ba6af6fd0304b70d8923a6d7ed9952288 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Mon, 2 May 2022 15:40:31 +0800 Subject: [PATCH 043/114] refactor: rename to BPU --- README.md | 4 ++++ src/vsrc/{branch_predictor => BPU}/Makefile | 0 src/vsrc/{branch_predictor => BPU}/README.md | 0 src/vsrc/{branch_predictor => BPU}/base_predictor.sv | 0 src/vsrc/{branch_predictor => BPU}/benchmark.sh | 0 src/vsrc/{branch_predictor => BPU}/btb.sv | 0 src/vsrc/{branch_predictor => BPU}/cbp3.cpp | 0 src/vsrc/{branch_predictor => BPU}/defines.sv | 0 src/vsrc/{branch_predictor => BPU}/folder_func.sv | 0 src/vsrc/{branch_predictor => BPU}/tage_predictor.sv | 0 src/vsrc/{branch_predictor => BPU}/tagged_predictor.sv | 0 src/vsrc/{branch_predictor => BPU}/testbench.cpp | 0 src/vsrc/{branch_predictor => BPU}/utils/csr_hash.sv | 0 src/vsrc/{branch_predictor => BPU}/utils/fpa.sv | 0 src/vsrc/{branch_predictor => BPU}/utils/xor_func.sv | 0 15 files changed, 4 insertions(+) rename src/vsrc/{branch_predictor => BPU}/Makefile (100%) rename src/vsrc/{branch_predictor => BPU}/README.md (100%) rename src/vsrc/{branch_predictor => BPU}/base_predictor.sv (100%) rename src/vsrc/{branch_predictor => BPU}/benchmark.sh (100%) rename src/vsrc/{branch_predictor => BPU}/btb.sv (100%) rename src/vsrc/{branch_predictor => BPU}/cbp3.cpp (100%) rename src/vsrc/{branch_predictor => BPU}/defines.sv (100%) rename src/vsrc/{branch_predictor => BPU}/folder_func.sv (100%) rename src/vsrc/{branch_predictor => BPU}/tage_predictor.sv (100%) rename src/vsrc/{branch_predictor => BPU}/tagged_predictor.sv (100%) rename src/vsrc/{branch_predictor => BPU}/testbench.cpp (100%) rename src/vsrc/{branch_predictor => BPU}/utils/csr_hash.sv (100%) rename src/vsrc/{branch_predictor => BPU}/utils/fpa.sv (100%) rename src/vsrc/{branch_predictor => BPU}/utils/xor_func.sv (100%) diff --git a/README.md b/README.md index 9e61a8d..e7e22ef 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,8 @@ src/ CPU Verilog 源代码 vsrc/ CPU 核心部分源码 pipeline/ 流水线部分 + AXI/ AXI 控制器 + BPU/ 分支预测部件 ... 其他模块 Makefile 用于自动化测试和Verilator仿真,无需关心 @@ -25,6 +27,8 @@ testbench.cpp 用于Verilator仿真,如果使用Vivado仿真,无需关 - [译码器设计](doc/instr_decode.md) - [差分测试](doc/difftest.md) +- [AXI控制器](src/vsrc/AXI/README.md) +- [分支预测器](src/vsrc/BPU/README.md) ## 开发流程 diff --git a/src/vsrc/branch_predictor/Makefile b/src/vsrc/BPU/Makefile similarity index 100% rename from src/vsrc/branch_predictor/Makefile rename to src/vsrc/BPU/Makefile diff --git a/src/vsrc/branch_predictor/README.md b/src/vsrc/BPU/README.md similarity index 100% rename from src/vsrc/branch_predictor/README.md rename to src/vsrc/BPU/README.md diff --git a/src/vsrc/branch_predictor/base_predictor.sv b/src/vsrc/BPU/base_predictor.sv similarity index 100% rename from src/vsrc/branch_predictor/base_predictor.sv rename to src/vsrc/BPU/base_predictor.sv diff --git a/src/vsrc/branch_predictor/benchmark.sh b/src/vsrc/BPU/benchmark.sh similarity index 100% rename from src/vsrc/branch_predictor/benchmark.sh rename to src/vsrc/BPU/benchmark.sh diff --git a/src/vsrc/branch_predictor/btb.sv b/src/vsrc/BPU/btb.sv similarity index 100% rename from src/vsrc/branch_predictor/btb.sv rename to src/vsrc/BPU/btb.sv diff --git a/src/vsrc/branch_predictor/cbp3.cpp b/src/vsrc/BPU/cbp3.cpp similarity index 100% rename from src/vsrc/branch_predictor/cbp3.cpp rename to src/vsrc/BPU/cbp3.cpp diff --git a/src/vsrc/branch_predictor/defines.sv b/src/vsrc/BPU/defines.sv similarity index 100% rename from src/vsrc/branch_predictor/defines.sv rename to src/vsrc/BPU/defines.sv diff --git a/src/vsrc/branch_predictor/folder_func.sv b/src/vsrc/BPU/folder_func.sv similarity index 100% rename from src/vsrc/branch_predictor/folder_func.sv rename to src/vsrc/BPU/folder_func.sv diff --git a/src/vsrc/branch_predictor/tage_predictor.sv b/src/vsrc/BPU/tage_predictor.sv similarity index 100% rename from src/vsrc/branch_predictor/tage_predictor.sv rename to src/vsrc/BPU/tage_predictor.sv diff --git a/src/vsrc/branch_predictor/tagged_predictor.sv b/src/vsrc/BPU/tagged_predictor.sv similarity index 100% rename from src/vsrc/branch_predictor/tagged_predictor.sv rename to src/vsrc/BPU/tagged_predictor.sv diff --git a/src/vsrc/branch_predictor/testbench.cpp b/src/vsrc/BPU/testbench.cpp similarity index 100% rename from src/vsrc/branch_predictor/testbench.cpp rename to src/vsrc/BPU/testbench.cpp diff --git a/src/vsrc/branch_predictor/utils/csr_hash.sv b/src/vsrc/BPU/utils/csr_hash.sv similarity index 100% rename from src/vsrc/branch_predictor/utils/csr_hash.sv rename to src/vsrc/BPU/utils/csr_hash.sv diff --git a/src/vsrc/branch_predictor/utils/fpa.sv b/src/vsrc/BPU/utils/fpa.sv similarity index 100% rename from src/vsrc/branch_predictor/utils/fpa.sv rename to src/vsrc/BPU/utils/fpa.sv diff --git a/src/vsrc/branch_predictor/utils/xor_func.sv b/src/vsrc/BPU/utils/xor_func.sv similarity index 100% rename from src/vsrc/branch_predictor/utils/xor_func.sv rename to src/vsrc/BPU/utils/xor_func.sv From 3de89c2f43829cd800595aadb5d5059eddac1df4 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Mon, 2 May 2022 15:46:35 +0800 Subject: [PATCH 044/114] docs: add chiplab --- README.md | 1 + doc/chiplab.md | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 doc/chiplab.md diff --git a/README.md b/README.md index e7e22ef..ffc27e6 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ testbench.cpp 用于Verilator仿真,如果使用Vivado仿真,无需关 - [差分测试](doc/difftest.md) - [AXI控制器](src/vsrc/AXI/README.md) - [分支预测器](src/vsrc/BPU/README.md) +- [Chiplab对接](doc/chiplab.md) ## 开发流程 diff --git a/doc/chiplab.md b/doc/chiplab.md new file mode 100644 index 0000000..2b828b0 --- /dev/null +++ b/doc/chiplab.md @@ -0,0 +1,79 @@ +# 对接Chiplab文档 + +## CPU核模块 +此处是指CPU内核部分的模块 + +一般来说包含: +- 流水线,ALU等核心部件 +- AXI控制器 +- 差分测试相关DPI + +一般来说不包含: +- 仿真/综合/调试/chiplab等可能用到的各种RAM +- 各种AXI桥和AXI Slave + +Chiplab要求的模块端口,接口均写死在Chiplab,如果要更改需要修改Chiplab的配置或源码 + +例外:双发射Chiplab有提供支持,参考最下面 + +```verilog +module cpu_top( + input aclk, + input aresetn, + input [ 7:0] intrpt, + //AXI interface + //read reqest + output [ 3:0] arid, + output [31:0] araddr, + output [ 7:0] arlen, + output [ 2:0] arsize, + output [ 1:0] arburst, + output [ 1:0] arlock, + output [ 3:0] arcache, + output [ 2:0] arprot, + output arvalid, + input arready, + //read back + input [ 3:0] rid, + input [31:0] rdata, + input [ 1:0] rresp, + input rlast, + input rvalid, + output rready, + //write request + output [ 3:0] awid, + output [31:0] awaddr, + output [ 7:0] awlen, + output [ 2:0] awsize, + output [ 1:0] awburst, + output [ 1:0] awlock, + output [ 3:0] awcache, + output [ 2:0] awprot, + output awvalid, + input awready, + //write data + output [ 3:0] wid, + output [31:0] wdata, + output [ 3:0] wstrb, + output wlast, + output wvalid, + input wready, + //write back + input [ 3:0] bid, + input [ 1:0] bresp, + input bvalid, + output bready, + //debug info + output [31:0] debug0_wb_pc, + output [ 3:0] debug0_wb_rf_wen, + output [ 4:0] debug0_wb_rf_wnum, + output [31:0] debug0_wb_rf_wdata + #ifdef CPU_2CMT + , + output [31:0] debug1_wb_pc, + output [ 3:0] debug1_wb_rf_wen, + output [ 4:0] debug1_wb_rf_wnum, + output [31:0] debug1_wb_rf_wdata + #endif +); +``` \ No newline at end of file From f8fe5c509fdf34bf34615403b59105b958921ad7 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Mon, 2 May 2022 17:28:11 +0800 Subject: [PATCH 045/114] feat: BUGGY! adapt pins for chiplab --- src/vsrc/AXI/axi_master.v | 2 +- src/vsrc/cpu_top.v | 174 ++- src/vsrc/pc_reg.v | 213 ++-- src/vsrc/pipeline/1_fetch/if_buffer.v | 64 +- src/vsrc/pipeline/1_fetch/if_id.v | 76 +- src/vsrc/pipeline/2_decode/id.v | 1600 +++++++++++------------- src/vsrc/pipeline/2_decode/id_ex.v | 205 ++- src/vsrc/pipeline/3_execution/ex.v | 380 +++--- src/vsrc/pipeline/3_execution/ex_mem.v | 153 ++- src/vsrc/pipeline/4_mem/mem.v | 603 ++++----- src/vsrc/pipeline/4_mem/mem_wb.v | 182 ++- 11 files changed, 1734 insertions(+), 1918 deletions(-) diff --git a/src/vsrc/AXI/axi_master.v b/src/vsrc/AXI/axi_master.v index 1b04242..5f8b1c8 100644 --- a/src/vsrc/AXI/axi_master.v +++ b/src/vsrc/AXI/axi_master.v @@ -1,4 +1,4 @@ -`include "axi_defines.v" +`include "AXI/axi_defines.v" module axi_master ( input wire aclk, input wire aresetn, //low is valid diff --git a/src/vsrc/cpu_top.v b/src/vsrc/cpu_top.v index 286bc20..bc9d8b4 100644 --- a/src/vsrc/cpu_top.v +++ b/src/vsrc/cpu_top.v @@ -5,6 +5,7 @@ `include "cs_reg.v" `include "tlb.v" `include "tlb_entry.v" +`include "AXI/axi_master.v" `include "pipeline/1_fetch/if_buffer.v" `include "pipeline/1_fetch/if_id.v" `include "pipeline/2_decode/id.v" @@ -15,66 +16,137 @@ `include "pipeline/4_mem/mem_wb.v" module cpu_top ( - input wire clk, - input wire rst, - - input wire [`RegBus] dram_data_i_1, - input wire [`RegBus] dram_data_i_2, - input wire [`RegBus] ram_rdata_i_1, - input wire [`RegBus] ram_rdata_i_2, - - output wire [`RegBus] ram_raddr_o_1, - output wire [`RegBus] ram_raddr_o_2, - output wire [`RegBus] ram_wdata_o, - output wire [`RegBus] ram_waddr_o, - output wire ram_wen_o, - output wire ram_en_o, - - output wire [`RegBus] dram_addr_o_1, - output wire [`RegBus] dram_data_o_1, - output wire dram_we_o_1, - output wire [3:0] dram_sel_o_1, - output wire dram_ce_o_1, - output wire [`InstAddrBus] dram_pc_o_1, - - output wire [`RegBus] dram_addr_o_2, - output wire [`RegBus] dram_data_o_2, - output wire dram_we_o_2, - output wire [3:0] dram_sel_o_2, - output wire dram_ce_o_2, - output wire [`InstAddrBus] dram_pc_o_2, - - output wire [`RegBus] debug_commit_pc_1, - output wire debug_commit_valid_1, - output wire [`InstBus] debug_commit_instr_1, - output wire debug_commit_wreg_1, - output wire [`RegAddrBus] debug_commit_reg_waddr_1, - output wire [`RegBus] debug_commit_reg_wdata_1, - output wire [`RegBus] debug_commit_pc_2, - output wire debug_commit_valid_2, - output wire [`InstBus] debug_commit_instr_2, - output wire debug_commit_wreg_2, - output wire [`RegAddrBus] debug_commit_reg_waddr_2, - output wire [`RegBus] debug_commit_reg_wdata_2, - output wire [1023:0] debug_reg, - output wire [831:0] csr_diff, - output wire Instram_branch_flag + input wire aclk, + input wire aresetn, + + input wire [7:0] intrpt, // External interrupt + + // AXI interface + // read reqest + output [ 3:0] arid, + output [31:0] araddr, + output [ 7:0] arlen, + output [ 2:0] arsize, + output [ 1:0] arburst, + output [ 1:0] arlock, + output [ 3:0] arcache, + output [ 2:0] arprot, + output arvalid, + input arready, + // read back + input [ 3:0] rid, + input [31:0] rdata, + input [ 1:0] rresp, + input rlast, + input rvalid, + output rready, + // write request + output [ 3:0] awid, + output [31:0] awaddr, + output [ 7:0] awlen, + output [ 2:0] awsize, + output [ 1:0] awburst, + output [ 1:0] awlock, + output [ 3:0] awcache, + output [ 2:0] awprot, + output awvalid, + input awready, + // write data + output [ 3:0] wid, + output [31:0] wdata, + output [ 3:0] wstrb, + output wlast, + output wvalid, + input wready, + //write back + input [ 3:0] bid, + input [ 1:0] bresp, + input bvalid, + output bready, + //debug info + output [31:0] debug0_wb_pc, + output [ 3:0] debug0_wb_rf_wen, + output [ 4:0] debug0_wb_rf_wnum, + output [31:0] debug0_wb_rf_wdata ); + // Clock signal + wire clk; + assign clk = aclk; + // Reset signal + wire rst_n; + wire rst; + assign rst_n = aresetn; + assign rst = ~rst_n; + + // Global enable signal + wire chip_enable; + + wire branch_flag_1; + wire branch_flag_2; + wire Instram_branch_flag; + assign Instram_branch_flag = branch_flag_1 | branch_flag_2; + + axi_master u_axi_master ( + .aclk (aclk), + .aresetn(aresetn), + + .cpu_addr_i(pc_buffer_1), + .cpu_ce_i(chip_enable), + .cpu_data_i(0), + .cpu_we_i(1'b0), + .cpu_sel_i(4'b1111), + .stall_i(Instram_branch_flag), + .flush_i(Instram_branch_flag), + .cpu_data_o(), + .stallreq(stallreq_from_id_1), + .id(4'b0000), // Read Instruction only, TODO: move this from AXI to cache + .s_arid(arid), + .s_araddr(araddr), + .s_arlen(arlen), + .s_arsize(arsize), + .s_arburst(arburst), + .s_arlock(arlock), + .s_arcache(arcache), + .s_arprot(arprot), + .s_arvalid(arvalid), + .s_arready(arready), + .s_rid(rid), + .s_rdata(rdata), + .s_rresp(rresp), + .s_rlast(rlast), + .s_rvalid(rvalid), + .s_rready(rready), + .s_awid(awid), + .s_awaddr(awaddr), + .s_awlen(awlen), + .s_awsize(awsize), + .s_awburst(awburst), + .s_awlock(awlock), + .s_awcache(awcache), + .s_awprot(awprot), + .s_awvalid(awvalid), + .s_awready(awready), + .s_wid(wid), + .s_wdata(wdata), + .s_wstrb(wstrb), + .s_wlast(wlast), + .s_wvalid(wvalid), + .s_wready(wready), + .s_bid(bid), + .s_bresp(bresp), + .s_bvalid(bvalid), + .s_bready(bready) + ); + + wire [`InstAddrBus] pc_1; wire [`InstAddrBus] pc_2; - wire chip_enable; wire [`InstAddrBus] pc_buffer_1; wire [`InstAddrBus] pc_buffer_2; - assign ram_en_o = chip_enable; - assign ram_raddr_o_1 = pc_buffer_1; - assign ram_raddr_o_2 = pc_buffer_2; - wire branch_flag_1; - wire branch_flag_2; - assign Instram_branch_flag = branch_flag_1 | branch_flag_2; wire [`RegBus] branch_target_address_1; wire [`RegBus] branch_target_address_2; wire [`RegBus] link_addr; diff --git a/src/vsrc/pc_reg.v b/src/vsrc/pc_reg.v index 708cb10..f1d5563 100644 --- a/src/vsrc/pc_reg.v +++ b/src/vsrc/pc_reg.v @@ -7,25 +7,25 @@ module pc_reg ( input wire stall2, input wire branch_flag_i_1, - input wire[`RegBus] branch_target_address_1, + input wire [`RegBus] branch_target_address_1, input wire branch_flag_i_2, - input wire[`RegBus] branch_target_address_2, + input wire [`RegBus] branch_target_address_2, input wire flush, input wire excp_flush, input wire ertn_flush, input wire excp_tlbrefill, - input wire[`InstAddrBus] new_pc, + input wire [`InstAddrBus] new_pc, input wire idle_flush, - input wire[`InstAddrBus] idle_pc, + input wire [`InstAddrBus] idle_pc, - output reg[`InstAddrBus] pc_1, - output reg[`InstAddrBus] pc_2, + output reg [`InstAddrBus] pc_1, + output reg [`InstAddrBus] pc_2, output reg ce, output wire excp_o, - output wire[3:0]excp_num_o, + output wire [3:0] excp_num_o, //from csr input wire csr_pg, @@ -38,137 +38,110 @@ module pc_reg ( input wire [`RegBus] csr_eentry, input wire [`RegBus] csr_era, input wire [`RegBus] csr_tlbrentry, - + //from tlb input wire inst_tlb_found, input wire inst_tlb_v, input wire inst_tlb_d, - input wire [1:0]inst_tlb_mat, - input wire [1:0]inst_tlb_plv, + input wire [1:0] inst_tlb_mat, + input wire [1:0] inst_tlb_plv, //to tlb - output wire[31:0]inst_addr, + output wire [31:0] inst_addr, output wire inst_addr_trans_en, output wire dmw0_en, output wire dmw1_en - ); - -reg if_valid; -wire if_ready_go; -wire if_allowin; -wire to_if_valid; -wire pif_ready_go; -wire [31:0] seq_pc; -wire [31:0] nextpc; -wire [31:0] real_nextpc; -wire pif_excp_adef; -wire if_excp_tlbr; -wire if_excp_pif; -wire if_excp_ppi; -reg if_excp; -reg if_excp_num; -wire excp; -wire [3:0] excp_num; -wire pif_excp; -wire pif_excp_num; -wire flush_sign; -reg [31:0] inst_rd_buff; -reg inst_buff_enable; -wire da_mode; -wire flush_inst_delay; -wire flush_inst_go_dirt; -wire fetch_btb_target; -reg idle_lock; -wire tlb_excp_lock_pc; -wire if_excp_adef; - - assign inst_addr_trans_en = csr_pg && !csr_da && !dmw0_en && !dmw1_en; - - assign dmw0_en = ((csr_dmw0[`PLV0] && csr_plv == 2'd0) || (csr_dmw0[`PLV3] && csr_plv == 2'd3)) && (pc_1[31:29] == csr_dmw0[`VSEG]); - assign dmw1_en = ((csr_dmw1[`PLV0] && csr_plv == 2'd0) || (csr_dmw1[`PLV3] && csr_plv == 2'd3)) && (pc_2[31:29] == csr_dmw1[`VSEG]); - - - //异常处理 - - //未找到tlb - assign if_excp_tlbr = !inst_tlb_found && inst_addr_trans_en; - //load操作页无效 - assign if_excp_pif = !inst_tlb_v && inst_addr_trans_en; - //页特权不合法 - assign if_excp_ppi = (csr_plv > inst_tlb_plv) && inst_addr_trans_en; - //取指地址错误 - assign if_excp_adef = (pc_1[31] || pc_2[31]) && (csr_plv == 2'd3) && inst_addr_trans_en; - - - assign excp_o = if_excp || if_excp_tlbr || if_excp_pif || if_excp_ppi || if_excp_adef; - assign excp_num_o = {if_excp_ppi, if_excp_pif, if_excp_tlbr, if_excp_num || if_excp_adef}; - - - always @(posedge clk) - begin - if(ce == `ChipDisable) - pc_1 <= 32'h1c000000; - else if(idle_flush) - pc_1 = idle_pc; - else if(flush == 1'b1) - pc_1 <= new_pc; - else if(stall1 == `Stop) // Hold output - begin - pc_1 <= pc_1; - end - else +); + + reg if_valid; + wire if_ready_go; + wire if_allowin; + wire to_if_valid; + wire pif_ready_go; + wire [31:0] seq_pc; + wire [31:0] nextpc; + wire [31:0] real_nextpc; + wire pif_excp_adef; + wire if_excp_tlbr; + wire if_excp_pif; + wire if_excp_ppi; + reg if_excp; + reg if_excp_num; + wire excp; + wire [3:0] excp_num; + wire pif_excp; + wire pif_excp_num; + wire flush_sign; + reg [31:0] inst_rd_buff; + reg inst_buff_enable; + wire da_mode; + wire flush_inst_delay; + wire flush_inst_go_dirt; + wire fetch_btb_target; + reg idle_lock; + wire tlb_excp_lock_pc; + wire if_excp_adef; + + assign inst_addr_trans_en = csr_pg && !csr_da && !dmw0_en && !dmw1_en; + + assign dmw0_en = ((csr_dmw0[`PLV0] && csr_plv == 2'd0) || (csr_dmw0[`PLV3] && csr_plv == 2'd3)) && (pc_1[31:29] == csr_dmw0[`VSEG]); + assign dmw1_en = ((csr_dmw1[`PLV0] && csr_plv == 2'd0) || (csr_dmw1[`PLV3] && csr_plv == 2'd3)) && (pc_2[31:29] == csr_dmw1[`VSEG]); + + + //异常处理 + + //未找到tlb + assign if_excp_tlbr = !inst_tlb_found && inst_addr_trans_en; + //load操作页无效 + assign if_excp_pif = !inst_tlb_v && inst_addr_trans_en; + //页特权不合法 + assign if_excp_ppi = (csr_plv > inst_tlb_plv) && inst_addr_trans_en; + //取指地址错误 + assign if_excp_adef = (pc_1[31] || pc_2[31]) && (csr_plv == 2'd3) && inst_addr_trans_en; + + + assign excp_o = if_excp || if_excp_tlbr || if_excp_pif || if_excp_ppi || if_excp_adef; + assign excp_num_o = {if_excp_ppi, if_excp_pif, if_excp_tlbr, if_excp_num || if_excp_adef}; + + + always @(posedge clk) begin + if (ce == `ChipDisable) pc_1 <= 32'h1c000000; + else if (idle_flush) pc_1 <= idle_pc; + else if (flush == 1'b1) pc_1 <= new_pc; + else if(stall1 == `Stop) // Hold output begin - if(branch_flag_i_1 == `Branch) - pc_1 <= branch_target_address_1; - else if(branch_flag_i_2 == `Branch) - pc_1 <= branch_target_address_2; - else if(excp_flush && !excp_tlbrefill) - pc_1 <= csr_eentry; - else if(excp_flush && excp_tlbrefill) - pc_1 <= csr_tlbrentry; - else if(ertn_flush) - pc_1 <= csr_era; - else - pc_1 <= pc_1 + 32'h8; + pc_1 <= pc_1; + end else begin + if (branch_flag_i_1 == `Branch) pc_1 <= branch_target_address_1; + else if (branch_flag_i_2 == `Branch) pc_1 <= branch_target_address_2; + else if (excp_flush && !excp_tlbrefill) pc_1 <= csr_eentry; + else if (excp_flush && excp_tlbrefill) pc_1 <= csr_tlbrentry; + else if (ertn_flush) pc_1 <= csr_era; + else pc_1 <= pc_1 + 32'h8; end end - always @(posedge clk) - begin - if(ce == `ChipDisable) - pc_2 <= 32'h1c000004; - else if(idle_flush) - pc_2 = idle_pc + 4'h4; - else if(flush == 1'b1) - pc_2 <= new_pc + 4'h4; - else if(stall2 == `Stop) // Hold output - begin - pc_2 <= pc_2; - end - else + always @(posedge clk) begin + if (ce == `ChipDisable) pc_2 <= 32'h1c000004; + else if (idle_flush) pc_2 <= idle_pc + 4'h4; + else if (flush == 1'b1) pc_2 <= new_pc + 4'h4; + else if(stall2 == `Stop) // Hold output begin - if(branch_flag_i_1 == `Branch) - pc_2 <= branch_target_address_1 + 4'h4; - else if(branch_flag_i_2 == `Branch) - pc_2 <= branch_target_address_2 + 4'h4; - else if(excp_flush && !excp_tlbrefill) - pc_2 <= csr_eentry + 4'h4; - else if(excp_flush && excp_tlbrefill) - pc_2 <= csr_tlbrentry + 4'h4; - else if(ertn_flush) - pc_2 <= csr_era +4'h4; - else - pc_2 <= pc_2 + 32'h8; + pc_2 <= pc_2; + end else begin + if (branch_flag_i_1 == `Branch) pc_2 <= branch_target_address_1 + 4'h4; + else if (branch_flag_i_2 == `Branch) pc_2 <= branch_target_address_2 + 4'h4; + else if (excp_flush && !excp_tlbrefill) pc_2 <= csr_eentry + 4'h4; + else if (excp_flush && excp_tlbrefill) pc_2 <= csr_tlbrentry + 4'h4; + else if (ertn_flush) pc_2 <= csr_era + 4'h4; + else pc_2 <= pc_2 + 32'h8; end end - always @(posedge clk) - begin - if(rst == `RstEnable) - ce <= `ChipDisable; - else - ce <= `ChipEnable; + always @(posedge clk) begin + if (rst == `RstEnable) ce <= `ChipDisable; + else ce <= `ChipEnable; end endmodule diff --git a/src/vsrc/pipeline/1_fetch/if_buffer.v b/src/vsrc/pipeline/1_fetch/if_buffer.v index 76d65a5..da11203 100644 --- a/src/vsrc/pipeline/1_fetch/if_buffer.v +++ b/src/vsrc/pipeline/1_fetch/if_buffer.v @@ -1,5 +1,5 @@ //to keep PC and inst_o corresponding -`include "../../defines.v" +`include "defines.v" module if_buffer ( input wire clk, input wire rst, @@ -12,49 +12,41 @@ module if_buffer ( input wire branch_flag_i, output reg [`InstAddrBus] pc_o, output reg pc_valid, - + input wire excp_i, input wire [3:0] excp_num_i, output reg excp_o, output reg [3:0] excp_num_o - ); +); - always @(posedge clk) - begin - if(rst) - begin - pc_o <= `ZeroWord; - pc_valid <= `InstInvalid; - excp_o <= 1'b0; - excp_num_o <= 4'b0; - end - else if(branch_flag_i == `Branch) - begin - pc_o <= `ZeroWord; - pc_valid <= `InstInvalid; - excp_o <= 1'b0; - excp_num_o <= 4'b0; - end - else if(flush == 1'b1 || excp_flush == 1'b1 || ertn_flush == 1'b1) - begin - pc_o <= `ZeroWord; - pc_valid <= `InstInvalid; - excp_o <= 1'b0; - excp_num_o <= 4'b0; + always @(posedge clk) begin + if (rst) begin + pc_o <= `ZeroWord; + pc_valid <= `InstInvalid; + excp_o <= 1'b0; + excp_num_o <= 4'b0; + end else if (branch_flag_i == `Branch) begin + pc_o <= `ZeroWord; + pc_valid <= `InstInvalid; + excp_o <= 1'b0; + excp_num_o <= 4'b0; + end else if (flush == 1'b1 || excp_flush == 1'b1 || ertn_flush == 1'b1) begin + pc_o <= `ZeroWord; + pc_valid <= `InstInvalid; + excp_o <= 1'b0; + excp_num_o <= 4'b0; end else if(stall == `Stop) // Stall, hold output begin - pc_o <= pc_o; - pc_valid <= pc_valid; - excp_o <= excp_i; - excp_num_o <= excp_num_i; - end - else - begin - pc_o <= pc_i; - pc_valid <= `InstValid; - excp_o <= excp_i; - excp_num_o <= excp_num_i; + pc_o <= pc_o; + pc_valid <= pc_valid; + excp_o <= excp_i; + excp_num_o <= excp_num_i; + end else begin + pc_o <= pc_i; + pc_valid <= `InstValid; + excp_o <= excp_i; + excp_num_o <= excp_num_i; end end diff --git a/src/vsrc/pipeline/1_fetch/if_id.v b/src/vsrc/pipeline/1_fetch/if_id.v index a61aa9e..64cf9ca 100644 --- a/src/vsrc/pipeline/1_fetch/if_id.v +++ b/src/vsrc/pipeline/1_fetch/if_id.v @@ -1,60 +1,50 @@ -`include "../../defines.v" +`include "defines.v" module if_id ( input wire clk, input wire rst, input wire branch_flag_i, - input wire[`InstAddrBus] if_pc_i, - input wire[`InstAddrBus] if_inst_i, + input wire [`InstAddrBus] if_pc_i, + input wire [`InstAddrBus] if_inst_i, input wire if_inst_valid, input wire flush, - input wire stall, // current stage stall, hold output - output reg[`InstAddrBus] id_pc_o, - output reg[`InstBus] id_inst_o, + input wire stall, // current stage stall, hold output + output reg [`InstAddrBus] id_pc_o, + output reg [`InstBus] id_inst_o, input wire excp_i, input wire [3:0] excp_num_i, output reg excp_o, output reg [3:0] excp_num_o - ); +); - always @(posedge clk) - begin - if(rst == `RstEnable) - begin - id_pc_o <= `ZeroWord; - id_inst_o <= `ZeroWord; - excp_o <= 1'b0; - excp_num_o <= 4'b0; - end - else if(flush == 1'b1) - begin - id_pc_o <= `ZeroWord; - id_inst_o <= `ZeroWord; - excp_o <= 1'b0; - excp_num_o <= 4'b0; - end - else if(branch_flag_i || if_inst_valid == `InstInvalid) - begin - id_pc_o <= `ZeroWord; - id_inst_o <= `ZeroWord; - excp_o <= 1'b0; - excp_num_o <= 4'b0; - end - else if(stall == `Stop) - begin - id_inst_o <= id_inst_o; - id_pc_o <= id_pc_o; - excp_o <= excp_i; - excp_num_o <= excp_num_i; - end - else - begin - id_inst_o <= if_inst_i; - id_pc_o <= if_pc_i; - excp_o <= excp_i; - excp_num_o <= excp_num_i; + always @(posedge clk) begin + if (rst == `RstEnable) begin + id_pc_o <= `ZeroWord; + id_inst_o <= `ZeroWord; + excp_o <= 1'b0; + excp_num_o <= 4'b0; + end else if (flush == 1'b1) begin + id_pc_o <= `ZeroWord; + id_inst_o <= `ZeroWord; + excp_o <= 1'b0; + excp_num_o <= 4'b0; + end else if (branch_flag_i || if_inst_valid == `InstInvalid) begin + id_pc_o <= `ZeroWord; + id_inst_o <= `ZeroWord; + excp_o <= 1'b0; + excp_num_o <= 4'b0; + end else if (stall == `Stop) begin + id_inst_o <= id_inst_o; + id_pc_o <= id_pc_o; + excp_o <= excp_i; + excp_num_o <= excp_num_i; + end else begin + id_inst_o <= if_inst_i; + id_pc_o <= if_pc_i; + excp_o <= excp_i; + excp_num_o <= excp_num_i; end end diff --git a/src/vsrc/pipeline/2_decode/id.v b/src/vsrc/pipeline/2_decode/id.v index a91d4ab..668448e 100644 --- a/src/vsrc/pipeline/2_decode/id.v +++ b/src/vsrc/pipeline/2_decode/id.v @@ -1,68 +1,68 @@ -`timescale 1ns/1ns +`timescale 1ns / 1ns -`include "../../defines.v" -module id( +`include "defines.v" +module id ( input wire rst, // <- IF - input wire[`InstAddrBus] pc_i, - input wire[`InstBus] inst_i, + input wire [`InstAddrBus] pc_i, + input wire [`InstBus] inst_i, input wire excp_i, - input wire [3:0]excp_num_i, + input wire [3:0] excp_num_i, // <- Regfile - input wire[`RegBus] reg1_data_i, - input wire[`RegBus] reg2_data_i, + input wire [`RegBus] reg1_data_i, + input wire [`RegBus] reg2_data_i, - input wire[`InstAddrBus] pc_i_other, + input wire [`InstAddrBus] pc_i_other, // <- EXE input wire ex_wreg_i_1, - input wire[`RegAddrBus] ex_waddr_i_1, - input wire[`RegBus] ex_wdata_i_1, - input wire[`AluOpBus] ex_aluop_i_1, + input wire [`RegAddrBus] ex_waddr_i_1, + input wire [`RegBus] ex_wdata_i_1, + input wire [`AluOpBus] ex_aluop_i_1, // <- ANOTHER_EXE input wire ex_wreg_i_2, - input wire[`RegAddrBus] ex_waddr_i_2, - input wire[`RegBus] ex_wdata_i_2, - input wire[`AluOpBus] ex_aluop_i_2, + input wire [`RegAddrBus] ex_waddr_i_2, + input wire [`RegBus] ex_wdata_i_2, + input wire [`AluOpBus] ex_aluop_i_2, // <- Mem input wire mem_wreg_i_1, - input wire[`RegAddrBus] mem_waddr_i_1, - input wire[`RegBus] mem_wdata_i_1, + input wire [`RegAddrBus] mem_waddr_i_1, + input wire [`RegBus] mem_wdata_i_1, // <- ANOTHER_Mem input wire mem_wreg_i_2, - input wire[`RegAddrBus] mem_waddr_i_2, - input wire[`RegBus] mem_wdata_i_2, + input wire [`RegAddrBus] mem_waddr_i_2, + input wire [`RegBus] mem_wdata_i_2, // -> Regfile output reg reg1_read_o, output reg reg2_read_o, // -> EXE - output reg[`RegAddrBus] reg1_addr_o, - output reg[`RegAddrBus] reg2_addr_o, - output reg[`AluOpBus] aluop_o, - output reg[`AluSelBus] alusel_o, - output reg[`RegBus] reg1_o, - output reg[`RegBus] reg2_o, - output reg[`RegAddrBus] reg_waddr_o, + output reg [`RegAddrBus] reg1_addr_o, + output reg [`RegAddrBus] reg2_addr_o, + output reg [`AluOpBus] aluop_o, + output reg [`AluSelBus] alusel_o, + output reg [`RegBus] reg1_o, + output reg [`RegBus] reg2_o, + output reg [`RegAddrBus] reg_waddr_o, output reg wreg_o, output reg inst_valid, - output reg[`InstAddrBus] inst_pc, - output wire[`RegBus] inst_o, - output wire[`RegBus] current_inst_address_o, + output reg [`InstAddrBus] inst_pc, + output wire [`RegBus] inst_o, + output wire [`RegBus] current_inst_address_o, output reg csr_we, output reg [13:0] csr_addr_o, - output reg [`RegBus]csr_data_o, + output reg [`RegBus] csr_data_o, output wire [1:0] excepttype_o, output wire excp_o, - output wire[8:0] excp_num_o, + output wire [8:0] excp_num_o, // <- CSR input wire has_int, @@ -70,58 +70,58 @@ module id( input wire [1:0] csr_plv, // -> CSR - output reg [13:0]csr_read_addr_o, + output reg [13:0] csr_read_addr_o, // -> PC output reg branch_flag_o, - output reg[`RegBus] branch_target_address_o, - output reg[`RegBus] link_addr_o, - output reg[`InstAddrBus] idle_pc, + output reg [`RegBus] branch_target_address_o, + output reg [`RegBus] link_addr_o, + output reg [`InstAddrBus] idle_pc, // ->Ctrl output wire stallreq, - output reg idle_stallreq - ); - - wire[5:0] opcode_6 = inst_i[31:26]; - wire[6:0] opcode_7 = inst_i[31:25]; - wire[7:0] opcode_8 = inst_i[31:24]; - wire[9:0] opcode_10 = inst_i[31:22]; - wire[13:0] opcode_14 = inst_i[31:18]; - wire[16:0] opcode_17 = inst_i[31:15]; - wire[21:0] opcode_22 = inst_i[31:10]; - wire[4:0] imm_5 = inst_i[14:10]; - wire[9:0] imm_10 = inst_i[9:0]; - wire[13:0] imm_14 = inst_i[23:10]; - wire[15:0] imm_16 = inst_i[25:10]; - wire[11:0] imm_12 = inst_i[21:10]; - wire[19:0] imm_20 = inst_i[24:5]; - wire[4:0] op1; - assign op1 = inst_i[4:0]; - wire[4:0] op2 = inst_i[9:5]; - wire[4:0] op3 = inst_i[14:10]; - wire[4:0] op4 = inst_i[19:15]; - - wire[5:0] opcode_1 = inst_i[31:26]; - wire[5:0] opcode_2 = inst_i[25:20]; - wire[4:0] opcode_3 = inst_i[19:15]; - wire[4:0] opcode_4 = inst_i[14:10]; - - wire[`RegBus] pc_plus_4; - - assign pc_plus_4 = pc_i + 4; - assign inst_o = inst_i; - - reg[`RegBus] imm; - - reg stallreq_for_reg1_loadrelate; - reg stallreq_for_reg2_loadrelate; - wire pre_inst_is_load; - - - reg res_from_csr; - - assign pre_inst_is_load = (((ex_aluop_i_1 == `EXE_LD_B_OP) || + output reg idle_stallreq +); + + wire [5:0] opcode_6 = inst_i[31:26]; + wire [6:0] opcode_7 = inst_i[31:25]; + wire [7:0] opcode_8 = inst_i[31:24]; + wire [9:0] opcode_10 = inst_i[31:22]; + wire [13:0] opcode_14 = inst_i[31:18]; + wire [16:0] opcode_17 = inst_i[31:15]; + wire [21:0] opcode_22 = inst_i[31:10]; + wire [4:0] imm_5 = inst_i[14:10]; + wire [9:0] imm_10 = inst_i[9:0]; + wire [13:0] imm_14 = inst_i[23:10]; + wire [15:0] imm_16 = inst_i[25:10]; + wire [11:0] imm_12 = inst_i[21:10]; + wire [19:0] imm_20 = inst_i[24:5]; + wire [4:0] op1; + assign op1 = inst_i[4:0]; + wire [4:0] op2 = inst_i[9:5]; + wire [4:0] op3 = inst_i[14:10]; + wire [4:0] op4 = inst_i[19:15]; + + wire [5:0] opcode_1 = inst_i[31:26]; + wire [5:0] opcode_2 = inst_i[25:20]; + wire [4:0] opcode_3 = inst_i[19:15]; + wire [4:0] opcode_4 = inst_i[14:10]; + + wire [`RegBus] pc_plus_4; + + assign pc_plus_4 = pc_i + 4; + assign inst_o = inst_i; + + reg [`RegBus] imm; + + reg stallreq_for_reg1_loadrelate; + reg stallreq_for_reg2_loadrelate; + wire pre_inst_is_load; + + + reg res_from_csr; + + assign pre_inst_is_load = (((ex_aluop_i_1 == `EXE_LD_B_OP) || (ex_aluop_i_1 == `EXE_LD_H_OP) || (ex_aluop_i_1 == `EXE_LD_W_OP) || (ex_aluop_i_1 == `EXE_LD_BU_OP) || @@ -138,867 +138,775 @@ module id( (ex_aluop_i_2 == `EXE_ST_H_OP) || (ex_aluop_i_2 == `EXE_ST_W_OP)) && (pc_i == pc_i_other + 4)) ? 1'b1 : 1'b0; - reg inst_syscall; - reg inst_break; - reg kernel_inst; + reg inst_syscall; + reg inst_break; + reg kernel_inst; - assign excepttype_o = {inst_syscall,inst_break}; - assign current_inst_address_o = pc_i; + assign excepttype_o = {inst_syscall, inst_break}; + assign current_inst_address_o = pc_i; - assign excp_ine = ~inst_valid; - assign excp_ipe = kernel_inst && (csr_plv == 2'b11); + assign excp_ine = ~inst_valid; + assign excp_ipe = kernel_inst && (csr_plv == 2'b11); - assign excp_o = excp_ipe | inst_syscall | inst_break | excp_i | excp_ine | has_int; - assign excp_num_o = {excp_ipe, excp_ine, inst_break, inst_syscall, excp_num_i, has_int}; + assign excp_o = excp_ipe | inst_syscall | inst_break | excp_i | excp_ine | has_int; + assign excp_num_o = {excp_ipe, excp_ine, inst_break, inst_syscall, excp_num_i, has_int}; - always @(*) - begin - if(rst == `RstEnable) - stallreq_for_reg1_loadrelate = `NoStop; - else if(pre_inst_is_load == 1'b1 && ex_waddr_i_1 == reg1_addr_o && reg1_read_o == 1'b1) - stallreq_for_reg1_loadrelate = `Stop; + always @(*) begin + if (rst == `RstEnable) stallreq_for_reg1_loadrelate = `NoStop; + else if (pre_inst_is_load == 1'b1 && ex_waddr_i_1 == reg1_addr_o && reg1_read_o == 1'b1) + stallreq_for_reg1_loadrelate = `Stop; end - always @(*) - begin - - if(rst == `RstEnable) - stallreq_for_reg2_loadrelate = `NoStop; - else if(pre_inst_is_load == 1'b1 && ex_waddr_i_1 == reg2_addr_o && reg2_read_o == 1'b1) - stallreq_for_reg2_loadrelate = `Stop; + always @(*) begin + + if (rst == `RstEnable) stallreq_for_reg2_loadrelate = `NoStop; + else if (pre_inst_is_load == 1'b1 && ex_waddr_i_1 == reg2_addr_o && reg2_read_o == 1'b1) + stallreq_for_reg2_loadrelate = `Stop; end - //如果这条指令与另一条相邻且存在依赖就直接暂停 - assign stallreq = stallreq_for_reg1_loadrelate | stallreq_for_reg2_loadrelate; + //如果这条指令与另一条相邻且存在依赖就直接暂停 + assign stallreq = stallreq_for_reg1_loadrelate | stallreq_for_reg2_loadrelate; - always @(*) - begin - inst_pc = pc_i; + always @(*) begin + inst_pc = pc_i; end - always @ (*) - begin - if (rst == `RstEnable) - begin - aluop_o = `EXE_NOP_OP; - alusel_o = `EXE_RES_NOP; - reg_waddr_o = `NOPRegAddr; - wreg_o = `WriteDisable; - inst_valid = `InstInvalid; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - reg1_addr_o = `NOPRegAddr; - reg2_addr_o = `NOPRegAddr; - imm = 32'h0; - branch_flag_o = `NotBranch; - branch_target_address_o = `ZeroWord; - link_addr_o = `ZeroWord; - inst_break = `False_v; - inst_syscall = `False_v; - idle_stallreq = 1'b0; - end - else - begin - aluop_o = `EXE_NOP_OP; - alusel_o = `EXE_RES_NOP; - reg_waddr_o = op1; - wreg_o = `WriteDisable; - inst_valid = `InstInvalid; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - reg1_addr_o = op2; - reg2_addr_o = op3; - imm = `ZeroWord; - branch_flag_o = `NotBranch; - branch_target_address_o = `ZeroWord; - link_addr_o = `ZeroWord; - idle_stallreq = 1'b0; - case (opcode_1) - `EXE_JIRL: - begin - wreg_o = `WriteEnable; - aluop_o = `EXE_JIRL_OP; - alusel_o = `EXE_RES_JUMP; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - link_addr_o = pc_plus_4; - branch_flag_o = `Branch; - branch_target_address_o = reg1_o + {{14{imm_16[15]}},imm_16,2'b0}; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_B: - begin - wreg_o = `WriteDisable; - aluop_o = `EXE_B_OP; - alusel_o = `EXE_RES_JUMP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - branch_flag_o = `Branch; - branch_target_address_o = pc_i + {{4{imm_10[9]}},imm_10,imm_16,2'b0}; - inst_valid = `InstValid; - end - `EXE_BL: - begin - wreg_o = `WriteEnable; - aluop_o = `EXE_BL_OP; - alusel_o = `EXE_RES_JUMP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - branch_flag_o = `Branch; - link_addr_o = pc_plus_4; - branch_target_address_o = pc_i +{{4{imm_10[9]}},imm_10,imm_16,2'b0}; - reg_waddr_o = 5'b1; - inst_valid = `InstValid; - end - `EXE_BEQ: - begin - wreg_o = `WriteDisable; - aluop_o = `EXE_BEQ_OP; - alusel_o = `EXE_RES_JUMP; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg1_addr_o = op2; - reg2_addr_o = op1; - if(reg1_o == reg2_o) - begin - branch_flag_o = `Branch; - branch_target_address_o = pc_i +{{14{imm_16[15]}},imm_16,2'b0}; - end - inst_valid = `InstValid; - end - `EXE_BNE: - begin - wreg_o = `WriteDisable; - aluop_o = `EXE_BNE_OP; - alusel_o = `EXE_RES_JUMP; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg1_addr_o = op2; - reg2_addr_o = op1; - if(reg1_o != reg2_o) - begin - branch_flag_o = `Branch; - branch_target_address_o = pc_i +{{14{imm_16[15]}},imm_16,2'b0}; - end - inst_valid = `InstValid; - end - `EXE_BLT: - begin - wreg_o = `WriteDisable; - aluop_o = `EXE_BLT_OP; - alusel_o = `EXE_RES_JUMP; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg1_addr_o = op2; - reg2_addr_o = op1; - if({~reg1_o[31],reg1_o[30:0]} < {~reg2_o[31],reg2_o[30:0]}) - begin - branch_flag_o = `Branch; - branch_target_address_o = pc_i +{{14{imm_16[15]}},imm_16,2'b0}; - end - inst_valid = `InstValid; - end - `EXE_BGE: - begin - wreg_o = `WriteDisable; - aluop_o = `EXE_BGE_OP; - alusel_o = `EXE_RES_JUMP; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg1_addr_o = op2; - reg2_addr_o = op1; - if({~reg1_o[31],reg1_o[30:0]} >= {~reg2_o[31],reg2_o[30:0]}) - begin - branch_flag_o = `Branch; - branch_target_address_o = pc_i +{{14{imm_16[15]}},imm_16,2'b0}; - end - inst_valid = `InstValid; - end - `EXE_BLTU: - begin - wreg_o = `WriteDisable; - aluop_o = `EXE_BLTU_OP; - alusel_o = `EXE_RES_JUMP; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg1_addr_o = op2; - reg2_addr_o = op1; - if(reg1_o < reg2_o) - begin - branch_flag_o = `Branch; - branch_target_address_o = pc_i +{{14{imm_16[15]}},imm_16,2'b0}; - end - inst_valid = `InstValid; - end - `EXE_BGEU: - begin - wreg_o = `WriteDisable; - aluop_o = `EXE_BGEU_OP; - alusel_o = `EXE_RES_JUMP; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg1_addr_o = op2; - reg2_addr_o = op1; - if(reg1_o >= reg2_o) - begin - branch_flag_o = `Branch; - branch_target_address_o = pc_i +{{14{imm_16[15]}},imm_16,2'b0}; - end - inst_valid = `InstValid; - end - `EXE_LU12I_W: - begin - wreg_o = `WriteEnable; - aluop_o = `EXE_LUI_OP; - alusel_o = `EXE_RES_MOVE; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - imm = {imm_20, 12'b0}; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_PCADDU12I: - begin - wreg_o = `WriteEnable; - aluop_o = `EXE_PCADD_OP; - alusel_o = `EXE_RES_MOVE; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - imm = {imm_20, 12'b0}; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_ATOMIC_MEM: - begin - casez (opcode_2) - `EXE_LL_W: - begin - wreg_o = `WriteEnable; - aluop_o = `EXE_LL_OP; - alusel_o = `EXE_RES_LOAD_STORE; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_SC_W: - begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SC_OP; - alusel_o = `EXE_RES_LOAD_STORE; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg2_addr_o = op1; - inst_valid = `InstValid; - end - default: - begin - end - endcase - end - `EXE_MEM_RELATED: - begin - casez (opcode_2) - `EXE_LD_B: - begin - wreg_o = `WriteEnable; - aluop_o = `EXE_LD_B_OP; - alusel_o = `EXE_RES_LOAD_STORE; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_LD_H: - begin - wreg_o = `WriteEnable; - aluop_o = `EXE_LD_H_OP; - alusel_o = `EXE_RES_LOAD_STORE; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_LD_W: - begin - wreg_o = `WriteEnable; - aluop_o = `EXE_LD_W_OP; - alusel_o = `EXE_RES_LOAD_STORE; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_ST_B: - begin - wreg_o = `WriteDisable; - aluop_o = `EXE_ST_B_OP; - alusel_o = `EXE_RES_LOAD_STORE; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg2_addr_o = op1; - inst_valid = `InstValid; - end - `EXE_ST_H: - begin - wreg_o = `WriteDisable; - aluop_o = `EXE_ST_H_OP; - alusel_o = `EXE_RES_LOAD_STORE; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg2_addr_o = op1; - inst_valid = `InstValid; - end - `EXE_ST_W: - begin - wreg_o = `WriteDisable; - aluop_o = `EXE_ST_W_OP; - alusel_o = `EXE_RES_LOAD_STORE; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg2_addr_o = op1; - inst_valid = `InstValid; - end - `EXE_LD_BU: - begin - wreg_o = `WriteEnable; - aluop_o = `EXE_LD_BU_OP; - alusel_o = `EXE_RES_LOAD_STORE; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_LD_HU: - begin - wreg_o = `WriteEnable; - aluop_o = `EXE_LD_HU_OP; - alusel_o = `EXE_RES_LOAD_STORE; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - default: - begin - end - endcase - end - - `EXE_SPECIAL: - begin - case (opcode_2) - `EXE_CSR_RELATED:begin - case (op2) - `EXE_CSRRD:begin - wreg_o = `WriteEnable; - aluop_o = `EXE_CSRRD_OP; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - imm = {18'b0,imm_14}; - csr_addr_o = imm_14; - reg_waddr_o = op1; - inst_valid = `InstValid; - res_from_csr = 1'b1; - kernel_inst = 1'b1; - end - `EXE_CSRWR:begin - wreg_o = `WriteEnable; - aluop_o = `EXE_CSRWR_OP; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - imm = {18'b0,imm_14}; - csr_addr_o = imm_14; - csr_data_o = reg1_data_i; - reg1_addr_o = op1; - reg_waddr_o = op1; - inst_valid = `InstValid; - res_from_csr = 1'b1; - kernel_inst = 1'b1; - end - default:begin - wreg_o = `WriteEnable; - aluop_o = `EXE_CSRXCHG_OP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - imm = {18'b0,imm_14}; - csr_addr_o = imm_14; - csr_data_o = reg1_data_i; - reg_waddr_o = op1; - inst_valid = `InstValid; - res_from_csr = 1'b1; - kernel_inst = 1'b1; - end - endcase - end - `EXE_OTHER:begin - case (opcode_3) - `EXE_TLB_RELATED:begin - case (opcode_22) - `EXE_TLBFILL:begin - wreg_o = `WriteDisable; - aluop_o = `EXE_TLBFILL_OP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - inst_valid = `InstValid; - kernel_inst = 1'b1; - end - `EXE_TLBRD:begin - wreg_o = `WriteDisable; - aluop_o = `EXE_TLBRD_OP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - inst_valid = `InstValid; - kernel_inst = 1'b1; - end - `EXE_TLBSRCH:begin - wreg_o = `WriteDisable; - aluop_o = `EXE_TLBSRCH_OP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - inst_valid = `InstValid; - kernel_inst = 1'b1; - end - `EXE_TLBWR:begin - wreg_o = `WriteDisable; - aluop_o = `EXE_TLBWR_OP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - inst_valid = `InstValid; - kernel_inst = 1'b1; - end - `EXE_ERTN:begin - wreg_o = `WriteDisable; - aluop_o = `EXE_ERTN_OP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - inst_valid = `InstValid; - kernel_inst = 1'b1; - end - default:begin - end - endcase - end - default:begin - case (opcode_17) - `EXE_IDLE:begin - wreg_o = `WriteDisable; - aluop_o = `EXE_IDLE_OP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - idle_stallreq = 1; - idle_pc = pc_i + 4'h4; - inst_valid = `InstValid; - kernel_inst = 1'b1; - end - `EXE_INVTLB:begin - wreg_o = `WriteDisable; - aluop_o = `EXE_INVTLB_OP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - inst_valid = `InstValid; - kernel_inst = 1'b1; - end - default: begin - end - endcase - end - endcase - end - default:begin - end - endcase - end - - `EXE_ARITHMETIC: - begin - casez (opcode_2) - `EXE_SLTI: - begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SLT_OP; - alusel_o = `EXE_RES_ARITH; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - imm = {{20{imm_12[11]}}, imm_12}; // Signed Extension - reg_waddr_o = op1; - inst_valid = `InstValid; + always @(*) begin + if (rst == `RstEnable) begin + aluop_o = `EXE_NOP_OP; + alusel_o = `EXE_RES_NOP; + reg_waddr_o = `NOPRegAddr; + wreg_o = `WriteDisable; + inst_valid = `InstInvalid; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + reg1_addr_o = `NOPRegAddr; + reg2_addr_o = `NOPRegAddr; + imm = 32'h0; + branch_flag_o = `NotBranch; + branch_target_address_o = `ZeroWord; + link_addr_o = `ZeroWord; + inst_break = `False_v; + inst_syscall = `False_v; + idle_stallreq = 1'b0; + end else begin + aluop_o = `EXE_NOP_OP; + alusel_o = `EXE_RES_NOP; + reg_waddr_o = op1; + wreg_o = `WriteDisable; + inst_valid = `InstInvalid; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + reg1_addr_o = op2; + reg2_addr_o = op3; + imm = `ZeroWord; + branch_flag_o = `NotBranch; + branch_target_address_o = `ZeroWord; + link_addr_o = `ZeroWord; + idle_stallreq = 1'b0; + case (opcode_1) + `EXE_JIRL: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_JIRL_OP; + alusel_o = `EXE_RES_JUMP; + reg1_read_o = 1'b1; + reg2_read_o = 1'b0; + link_addr_o = pc_plus_4; + branch_flag_o = `Branch; + branch_target_address_o = reg1_o + {{14{imm_16[15]}}, imm_16, 2'b0}; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_B: begin + wreg_o = `WriteDisable; + aluop_o = `EXE_B_OP; + alusel_o = `EXE_RES_JUMP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + branch_flag_o = `Branch; + branch_target_address_o = pc_i + {{4{imm_10[9]}}, imm_10, imm_16, 2'b0}; + inst_valid = `InstValid; + end + `EXE_BL: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_BL_OP; + alusel_o = `EXE_RES_JUMP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + branch_flag_o = `Branch; + link_addr_o = pc_plus_4; + branch_target_address_o = pc_i + {{4{imm_10[9]}}, imm_10, imm_16, 2'b0}; + reg_waddr_o = 5'b1; + inst_valid = `InstValid; + end + `EXE_BEQ: begin + wreg_o = `WriteDisable; + aluop_o = `EXE_BEQ_OP; + alusel_o = `EXE_RES_JUMP; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg1_addr_o = op2; + reg2_addr_o = op1; + if (reg1_o == reg2_o) begin + branch_flag_o = `Branch; + branch_target_address_o = pc_i + {{14{imm_16[15]}}, imm_16, 2'b0}; end - `EXE_SLTUI: - begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SLTU_OP; - alusel_o = `EXE_RES_ARITH; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - imm = {{20{imm_12[11]}}, imm_12}; // Signed Extension - reg_waddr_o = op1; - inst_valid = `InstValid; + inst_valid = `InstValid; + end + `EXE_BNE: begin + wreg_o = `WriteDisable; + aluop_o = `EXE_BNE_OP; + alusel_o = `EXE_RES_JUMP; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg1_addr_o = op2; + reg2_addr_o = op1; + if (reg1_o != reg2_o) begin + branch_flag_o = `Branch; + branch_target_address_o = pc_i + {{14{imm_16[15]}}, imm_16, 2'b0}; end - `EXE_ADDI_W: - begin - wreg_o = `WriteEnable; - aluop_o = `EXE_ADD_OP; - alusel_o = `EXE_RES_ARITH; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - imm = {{20{imm_12[11]}}, imm_12}; // Signed Extension - reg_waddr_o = op1; - inst_valid = `InstValid; + inst_valid = `InstValid; + end + `EXE_BLT: begin + wreg_o = `WriteDisable; + aluop_o = `EXE_BLT_OP; + alusel_o = `EXE_RES_JUMP; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg1_addr_o = op2; + reg2_addr_o = op1; + if ({~reg1_o[31], reg1_o[30:0]} < {~reg2_o[31], reg2_o[30:0]}) begin + branch_flag_o = `Branch; + branch_target_address_o = pc_i + {{14{imm_16[15]}}, imm_16, 2'b0}; end - `EXE_ANDI: - begin - wreg_o = `WriteEnable; - aluop_o = `EXE_AND_OP; - alusel_o = `EXE_RES_LOGIC; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - imm = {20'h0, imm_12}; - reg_waddr_o = op1; - inst_valid = `InstValid; + inst_valid = `InstValid; + end + `EXE_BGE: begin + wreg_o = `WriteDisable; + aluop_o = `EXE_BGE_OP; + alusel_o = `EXE_RES_JUMP; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg1_addr_o = op2; + reg2_addr_o = op1; + if ({~reg1_o[31], reg1_o[30:0]} >= {~reg2_o[31], reg2_o[30:0]}) begin + branch_flag_o = `Branch; + branch_target_address_o = pc_i + {{14{imm_16[15]}}, imm_16, 2'b0}; end - `EXE_ORI: - begin - wreg_o = `WriteEnable; - aluop_o = `EXE_OR_OP; - alusel_o = `EXE_RES_LOGIC; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - imm = {20'h0, imm_12}; - reg_waddr_o = op1; - inst_valid = `InstValid; + inst_valid = `InstValid; + end + `EXE_BLTU: begin + wreg_o = `WriteDisable; + aluop_o = `EXE_BLTU_OP; + alusel_o = `EXE_RES_JUMP; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg1_addr_o = op2; + reg2_addr_o = op1; + if (reg1_o < reg2_o) begin + branch_flag_o = `Branch; + branch_target_address_o = pc_i + {{14{imm_16[15]}}, imm_16, 2'b0}; end - `EXE_XORI: - begin - wreg_o = `WriteEnable; - aluop_o = `EXE_XOR_OP; - alusel_o = `EXE_RES_LOGIC; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - imm = {20'h0, imm_12}; - reg_waddr_o = op1; - inst_valid = `InstValid; + inst_valid = `InstValid; + end + `EXE_BGEU: begin + wreg_o = `WriteDisable; + aluop_o = `EXE_BGEU_OP; + alusel_o = `EXE_RES_JUMP; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg1_addr_o = op2; + reg2_addr_o = op1; + if (reg1_o >= reg2_o) begin + branch_flag_o = `Branch; + branch_target_address_o = pc_i + {{14{imm_16[15]}}, imm_16, 2'b0}; end - `EXE_LONG_ARITH: - begin - case (opcode_3) - `EXE_ADD_W: - begin + inst_valid = `InstValid; + end + `EXE_LU12I_W: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_LUI_OP; + alusel_o = `EXE_RES_MOVE; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + imm = {imm_20, 12'b0}; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_PCADDU12I: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_PCADD_OP; + alusel_o = `EXE_RES_MOVE; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + imm = {imm_20, 12'b0}; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_ATOMIC_MEM: begin + casez (opcode_2) + `EXE_LL_W: begin wreg_o = `WriteEnable; - aluop_o = `EXE_ADD_OP; - alusel_o = `EXE_RES_ARITH; + aluop_o = `EXE_LL_OP; + alusel_o = `EXE_RES_LOAD_STORE; reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_SUB_W: - begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SUB_OP; - alusel_o = `EXE_RES_ARITH; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_SLT: - begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SLT_OP; - alusel_o = `EXE_RES_ARITH; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_SLTU: - begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SLTU_OP; - alusel_o = `EXE_RES_ARITH; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_NOR: - begin - wreg_o = `WriteEnable; - aluop_o = `EXE_NOR_OP; - alusel_o = `EXE_RES_LOGIC; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; + reg2_read_o = 1'b0; reg_waddr_o = op1; inst_valid = `InstValid; - end - `EXE_AND: - begin + end + `EXE_SC_W: begin wreg_o = `WriteEnable; - aluop_o = `EXE_AND_OP; - alusel_o = `EXE_RES_LOGIC; + aluop_o = `EXE_SC_OP; + alusel_o = `EXE_RES_LOAD_STORE; reg1_read_o = 1'b1; reg2_read_o = 1'b1; - reg_waddr_o = op1; + reg2_addr_o = op1; inst_valid = `InstValid; - end - `EXE_OR: - begin + end + default: begin + end + endcase + end + `EXE_MEM_RELATED: begin + casez (opcode_2) + `EXE_LD_B: begin wreg_o = `WriteEnable; - aluop_o = `EXE_OR_OP; - alusel_o = `EXE_RES_LOGIC; + aluop_o = `EXE_LD_B_OP; + alusel_o = `EXE_RES_LOAD_STORE; reg1_read_o = 1'b1; - reg2_read_o = 1'b1; + reg2_read_o = 1'b0; reg_waddr_o = op1; inst_valid = `InstValid; - end - `EXE_XOR: - begin + end + `EXE_LD_H: begin wreg_o = `WriteEnable; - aluop_o = `EXE_XOR_OP; - alusel_o = `EXE_RES_LOGIC; + aluop_o = `EXE_LD_H_OP; + alusel_o = `EXE_RES_LOAD_STORE; reg1_read_o = 1'b1; - reg2_read_o = 1'b1; + reg2_read_o = 1'b0; reg_waddr_o = op1; inst_valid = `InstValid; - end - `EXE_SLL_W: - begin + end + `EXE_LD_W: begin wreg_o = `WriteEnable; - aluop_o = `EXE_SLL_OP; - alusel_o = `EXE_RES_SHIFT; + aluop_o = `EXE_LD_W_OP; + alusel_o = `EXE_RES_LOAD_STORE; reg1_read_o = 1'b1; - reg2_read_o = 1'b1; + reg2_read_o = 1'b0; reg_waddr_o = op1; inst_valid = `InstValid; - end - `EXE_SRL_W: - begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SRL_OP; - alusel_o = `EXE_RES_SHIFT; + end + `EXE_ST_B: begin + wreg_o = `WriteDisable; + aluop_o = `EXE_ST_B_OP; + alusel_o = `EXE_RES_LOAD_STORE; reg1_read_o = 1'b1; reg2_read_o = 1'b1; - reg_waddr_o = op1; + reg2_addr_o = op1; inst_valid = `InstValid; - end - `EXE_SRA_W: - begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SRA_OP; - alusel_o = `EXE_RES_SHIFT; + end + `EXE_ST_H: begin + wreg_o = `WriteDisable; + aluop_o = `EXE_ST_H_OP; + alusel_o = `EXE_RES_LOAD_STORE; reg1_read_o = 1'b1; reg2_read_o = 1'b1; - reg_waddr_o = op1; + reg2_addr_o = op1; inst_valid = `InstValid; - end - `EXE_MUL_W: - begin - wreg_o = `WriteEnable; - aluop_o = `EXE_MUL_OP; - alusel_o = `EXE_RES_ARITH; + end + `EXE_ST_W: begin + wreg_o = `WriteDisable; + aluop_o = `EXE_ST_W_OP; + alusel_o = `EXE_RES_LOAD_STORE; reg1_read_o = 1'b1; reg2_read_o = 1'b1; - reg_waddr_o = op1; + reg2_addr_o = op1; inst_valid = `InstValid; - end - `EXE_MULH_W: - begin + end + `EXE_LD_BU: begin wreg_o = `WriteEnable; - aluop_o = `EXE_MULH_OP; - alusel_o = `EXE_RES_ARITH; + aluop_o = `EXE_LD_BU_OP; + alusel_o = `EXE_RES_LOAD_STORE; reg1_read_o = 1'b1; - reg2_read_o = 1'b1; + reg2_read_o = 1'b0; reg_waddr_o = op1; inst_valid = `InstValid; - end - `EXE_MULH_WU: - begin + end + `EXE_LD_HU: begin wreg_o = `WriteEnable; - aluop_o = `EXE_MULHU_OP; - alusel_o = `EXE_RES_ARITH; + aluop_o = `EXE_LD_HU_OP; + alusel_o = `EXE_RES_LOAD_STORE; reg1_read_o = 1'b1; - reg2_read_o = 1'b1; + reg2_read_o = 1'b0; reg_waddr_o = op1; inst_valid = `InstValid; - end - default: - begin - end + end + default: begin + end + endcase + end + + `EXE_SPECIAL: begin + case (opcode_2) + `EXE_CSR_RELATED: begin + case (op2) + `EXE_CSRRD: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_CSRRD_OP; + reg1_read_o = 1'b1; + reg2_read_o = 1'b0; + imm = {18'b0, imm_14}; + csr_addr_o = imm_14; + reg_waddr_o = op1; + inst_valid = `InstValid; + res_from_csr = 1'b1; + kernel_inst = 1'b1; + end + `EXE_CSRWR: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_CSRWR_OP; + reg1_read_o = 1'b1; + reg2_read_o = 1'b0; + imm = {18'b0, imm_14}; + csr_addr_o = imm_14; + csr_data_o = reg1_data_i; + reg1_addr_o = op1; + reg_waddr_o = op1; + inst_valid = `InstValid; + res_from_csr = 1'b1; + kernel_inst = 1'b1; + end + default: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_CSRXCHG_OP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + imm = {18'b0, imm_14}; + csr_addr_o = imm_14; + csr_data_o = reg1_data_i; + reg_waddr_o = op1; + inst_valid = `InstValid; + res_from_csr = 1'b1; + kernel_inst = 1'b1; + end + endcase + end + `EXE_OTHER: begin + case (opcode_3) + `EXE_TLB_RELATED: begin + case (opcode_22) + `EXE_TLBFILL: begin + wreg_o = `WriteDisable; + aluop_o = `EXE_TLBFILL_OP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + inst_valid = `InstValid; + kernel_inst = 1'b1; + end + `EXE_TLBRD: begin + wreg_o = `WriteDisable; + aluop_o = `EXE_TLBRD_OP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + inst_valid = `InstValid; + kernel_inst = 1'b1; + end + `EXE_TLBSRCH: begin + wreg_o = `WriteDisable; + aluop_o = `EXE_TLBSRCH_OP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + inst_valid = `InstValid; + kernel_inst = 1'b1; + end + `EXE_TLBWR: begin + wreg_o = `WriteDisable; + aluop_o = `EXE_TLBWR_OP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + inst_valid = `InstValid; + kernel_inst = 1'b1; + end + `EXE_ERTN: begin + wreg_o = `WriteDisable; + aluop_o = `EXE_ERTN_OP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + inst_valid = `InstValid; + kernel_inst = 1'b1; + end + default: begin + end + endcase + end + default: begin + case (opcode_17) + `EXE_IDLE: begin + wreg_o = `WriteDisable; + aluop_o = `EXE_IDLE_OP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + idle_stallreq = 1; + idle_pc = pc_i + 4'h4; + inst_valid = `InstValid; + kernel_inst = 1'b1; + end + `EXE_INVTLB: begin + wreg_o = `WriteDisable; + aluop_o = `EXE_INVTLB_OP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + inst_valid = `InstValid; + kernel_inst = 1'b1; + end + default: begin + end + endcase + end + endcase + end + default: begin + end + endcase + end - endcase - end - `EXE_DIV_ARITH: - begin - casez (opcode_3) - `EXE_DIV_W: - begin + `EXE_ARITHMETIC: begin + casez (opcode_2) + `EXE_SLTI: begin wreg_o = `WriteEnable; - aluop_o = `EXE_DIV_OP; - alusel_o = `EXE_RES_ARITH; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_MOD_W: - begin - wreg_o = `WriteEnable; - aluop_o = `EXE_MOD_OP; + aluop_o = `EXE_SLT_OP; alusel_o = `EXE_RES_ARITH; reg1_read_o = 1'b1; - reg2_read_o = 1'b1; + reg2_read_o = 1'b0; + imm = {{20{imm_12[11]}}, imm_12}; // Signed Extension reg_waddr_o = op1; inst_valid = `InstValid; - end - `EXE_DIV_WU: - begin + end + `EXE_SLTUI: begin wreg_o = `WriteEnable; - aluop_o = `EXE_DIV_OP; + aluop_o = `EXE_SLTU_OP; alusel_o = `EXE_RES_ARITH; reg1_read_o = 1'b1; - reg2_read_o = 1'b1; + reg2_read_o = 1'b0; + imm = {{20{imm_12[11]}}, imm_12}; // Signed Extension reg_waddr_o = op1; inst_valid = `InstValid; - end - `EXE_MOD_WU: - begin + end + `EXE_ADDI_W: begin wreg_o = `WriteEnable; - aluop_o = `EXE_MOD_OP; + aluop_o = `EXE_ADD_OP; alusel_o = `EXE_RES_ARITH; reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_BREAK: - begin - wreg_o = `WriteDisable; - aluop_o = `EXE_BREAK_OP; - alusel_o = `EXE_RES_NOP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - inst_valid = `InstValid; - inst_break = `True_v; - end - `EXE_SYSCALL: - begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SYSCALL_OP; - alusel_o = `EXE_RES_NOP; - reg1_read_o = 1'b0; reg2_read_o = 1'b0; + imm = {{20{imm_12[11]}}, imm_12}; // Signed Extension + reg_waddr_o = op1; inst_valid = `InstValid; - inst_syscall = `True_v; - end - default: - begin - end - endcase - end - `EXE_SHIFT_ARITH: - begin - casez (opcode_3) - `EXE_SLLI_W: - begin + end + `EXE_ANDI: begin wreg_o = `WriteEnable; - aluop_o = `EXE_SLL_OP; - alusel_o = `EXE_RES_SHIFT; + aluop_o = `EXE_AND_OP; + alusel_o = `EXE_RES_LOGIC; reg1_read_o = 1'b1; reg2_read_o = 1'b0; - imm = {27'b0,imm_5}; + imm = {20'h0, imm_12}; reg_waddr_o = op1; inst_valid = `InstValid; - end - `EXE_SRLI_W: - begin + end + `EXE_ORI: begin wreg_o = `WriteEnable; - aluop_o = `EXE_SRL_OP; - alusel_o = `EXE_RES_SHIFT; + aluop_o = `EXE_OR_OP; + alusel_o = `EXE_RES_LOGIC; reg1_read_o = 1'b1; reg2_read_o = 1'b0; - imm = {27'b0,imm_5}; + imm = {20'h0, imm_12}; reg_waddr_o = op1; inst_valid = `InstValid; - end - `EXE_SRAI_W: - begin + end + `EXE_XORI: begin wreg_o = `WriteEnable; - aluop_o = `EXE_SRA_OP; - alusel_o = `EXE_RES_SHIFT; + aluop_o = `EXE_XOR_OP; + alusel_o = `EXE_RES_LOGIC; reg1_read_o = 1'b1; reg2_read_o = 1'b0; - imm = {27'b0,imm_5}; + imm = {20'h0, imm_12}; reg_waddr_o = op1; inst_valid = `InstValid; - end - default: - begin - end - endcase - end - default: - begin - - end - endcase - end - default: - begin - end - endcase + end + `EXE_LONG_ARITH: begin + case (opcode_3) + `EXE_ADD_W: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_ADD_OP; + alusel_o = `EXE_RES_ARITH; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_SUB_W: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_SUB_OP; + alusel_o = `EXE_RES_ARITH; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_SLT: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_SLT_OP; + alusel_o = `EXE_RES_ARITH; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_SLTU: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_SLTU_OP; + alusel_o = `EXE_RES_ARITH; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_NOR: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_NOR_OP; + alusel_o = `EXE_RES_LOGIC; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_AND: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_AND_OP; + alusel_o = `EXE_RES_LOGIC; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_OR: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_OR_OP; + alusel_o = `EXE_RES_LOGIC; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_XOR: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_XOR_OP; + alusel_o = `EXE_RES_LOGIC; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_SLL_W: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_SLL_OP; + alusel_o = `EXE_RES_SHIFT; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_SRL_W: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_SRL_OP; + alusel_o = `EXE_RES_SHIFT; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_SRA_W: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_SRA_OP; + alusel_o = `EXE_RES_SHIFT; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_MUL_W: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_MUL_OP; + alusel_o = `EXE_RES_ARITH; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_MULH_W: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_MULH_OP; + alusel_o = `EXE_RES_ARITH; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_MULH_WU: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_MULHU_OP; + alusel_o = `EXE_RES_ARITH; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + default: begin + end + + endcase + end + `EXE_DIV_ARITH: begin + casez (opcode_3) + `EXE_DIV_W: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_DIV_OP; + alusel_o = `EXE_RES_ARITH; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_MOD_W: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_MOD_OP; + alusel_o = `EXE_RES_ARITH; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_DIV_WU: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_DIV_OP; + alusel_o = `EXE_RES_ARITH; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_MOD_WU: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_MOD_OP; + alusel_o = `EXE_RES_ARITH; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_BREAK: begin + wreg_o = `WriteDisable; + aluop_o = `EXE_BREAK_OP; + alusel_o = `EXE_RES_NOP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + inst_valid = `InstValid; + inst_break = `True_v; + end + `EXE_SYSCALL: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_SYSCALL_OP; + alusel_o = `EXE_RES_NOP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + inst_valid = `InstValid; + inst_syscall = `True_v; + end + default: begin + end + endcase + end + `EXE_SHIFT_ARITH: begin + casez (opcode_3) + `EXE_SLLI_W: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_SLL_OP; + alusel_o = `EXE_RES_SHIFT; + reg1_read_o = 1'b1; + reg2_read_o = 1'b0; + imm = {27'b0, imm_5}; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_SRLI_W: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_SRL_OP; + alusel_o = `EXE_RES_SHIFT; + reg1_read_o = 1'b1; + reg2_read_o = 1'b0; + imm = {27'b0, imm_5}; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_SRAI_W: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_SRA_OP; + alusel_o = `EXE_RES_SHIFT; + reg1_read_o = 1'b1; + reg2_read_o = 1'b0; + imm = {27'b0, imm_5}; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + default: begin + end + endcase + end + default: begin + + end + endcase + end + default: begin + end + endcase end end - always @ (*) - begin - if (rst == `RstEnable) - reg1_o = `ZeroWord; - else if(opcode_2 == `EXE_CSR_RELATED) - reg1_o = csr_data_i; - else if ((reg1_read_o == 1'b1) && (reg1_addr_o == 0)) - reg1_o = `ZeroWord; - else if((reg1_read_o == 1'b1) && (ex_wreg_i_2 == 1'b1) && (ex_waddr_i_2 == reg1_addr_o)) - reg1_o = ex_wdata_i_2; - else if((reg1_read_o == 1'b1) && (mem_wreg_i_2 == 1'b1) && (mem_waddr_i_2 == reg1_addr_o)) - reg1_o = mem_wdata_i_2; - else if((reg1_read_o == 1'b1) && (ex_wreg_i_1 == 1'b1) && (ex_waddr_i_1 == reg1_addr_o)) - reg1_o = ex_wdata_i_1; - else if((reg1_read_o == 1'b1) && (mem_wreg_i_1 == 1'b1) && (mem_waddr_i_1 == reg1_addr_o)) - reg1_o = mem_wdata_i_1; - else if (reg1_read_o == 1'b1) - reg1_o = reg1_data_i; - else if (reg1_read_o == 1'b0) - reg1_o = imm; - else - reg1_o = `ZeroWord; + always @(*) begin + if (rst == `RstEnable) reg1_o = `ZeroWord; + else if (opcode_2[5:4] == 2'b00) + reg1_o = csr_data_i; // EXE_CSR_RELATED, TODO: replace magic number + else if ((reg1_read_o == 1'b1) && (reg1_addr_o == 0)) reg1_o = `ZeroWord; + else if ((reg1_read_o == 1'b1) && (ex_wreg_i_2 == 1'b1) && (ex_waddr_i_2 == reg1_addr_o)) + reg1_o = ex_wdata_i_2; + else if ((reg1_read_o == 1'b1) && (mem_wreg_i_2 == 1'b1) && (mem_waddr_i_2 == reg1_addr_o)) + reg1_o = mem_wdata_i_2; + else if ((reg1_read_o == 1'b1) && (ex_wreg_i_1 == 1'b1) && (ex_waddr_i_1 == reg1_addr_o)) + reg1_o = ex_wdata_i_1; + else if ((reg1_read_o == 1'b1) && (mem_wreg_i_1 == 1'b1) && (mem_waddr_i_1 == reg1_addr_o)) + reg1_o = mem_wdata_i_1; + else if (reg1_read_o == 1'b1) reg1_o = reg1_data_i; + else if (reg1_read_o == 1'b0) reg1_o = imm; + else reg1_o = `ZeroWord; end - always @ (*) - begin - if (rst == `RstEnable) - reg2_o = `ZeroWord; - else if(opcode_2 == `EXE_CSR_RELATED) - reg2_o = `ZeroWord; - else if ((reg2_read_o == 1'b1) && (reg2_addr_o == 0)) - reg2_o = `ZeroWord; - else if((reg2_read_o == 1'b1) && (ex_wreg_i_2 == 1'b1) && (ex_waddr_i_2 == reg2_addr_o)) - reg2_o = ex_wdata_i_2; - else if((reg2_read_o == 1'b1) && (mem_wreg_i_2 == 1'b1) && (mem_waddr_i_2 == reg2_addr_o)) - reg2_o = mem_wdata_i_2; - else if((reg2_read_o == 1'b1) && (ex_wreg_i_1 == 1'b1) && (ex_waddr_i_1 == reg2_addr_o)) - reg2_o = ex_wdata_i_1; - else if((reg2_read_o == 1'b1) && (mem_wreg_i_1 == 1'b1) && (mem_waddr_i_1 == reg2_addr_o)) - reg2_o = mem_wdata_i_1; - else if (reg2_read_o == 1'b1) - reg2_o = reg2_data_i; - else if (reg2_read_o == 1'b0) - reg2_o = imm; - else - reg2_o = `ZeroWord; + always @(*) begin + if (rst == `RstEnable) reg2_o = `ZeroWord; + else if (opcode_2[5:4] == 2'b00) reg2_o = `ZeroWord; + else if ((reg2_read_o == 1'b1) && (reg2_addr_o == 0)) reg2_o = `ZeroWord; + else if ((reg2_read_o == 1'b1) && (ex_wreg_i_2 == 1'b1) && (ex_waddr_i_2 == reg2_addr_o)) + reg2_o = ex_wdata_i_2; + else if ((reg2_read_o == 1'b1) && (mem_wreg_i_2 == 1'b1) && (mem_waddr_i_2 == reg2_addr_o)) + reg2_o = mem_wdata_i_2; + else if ((reg2_read_o == 1'b1) && (ex_wreg_i_1 == 1'b1) && (ex_waddr_i_1 == reg2_addr_o)) + reg2_o = ex_wdata_i_1; + else if ((reg2_read_o == 1'b1) && (mem_wreg_i_1 == 1'b1) && (mem_waddr_i_1 == reg2_addr_o)) + reg2_o = mem_wdata_i_1; + else if (reg2_read_o == 1'b1) reg2_o = reg2_data_i; + else if (reg2_read_o == 1'b0) reg2_o = imm; + else reg2_o = `ZeroWord; end endmodule diff --git a/src/vsrc/pipeline/2_decode/id_ex.v b/src/vsrc/pipeline/2_decode/id_ex.v index b8f2952..0178341 100644 --- a/src/vsrc/pipeline/2_decode/id_ex.v +++ b/src/vsrc/pipeline/2_decode/id_ex.v @@ -1,4 +1,4 @@ -`include "../../defines.v" +`include "defines.v" module id_ex ( input wire clk, input wire rst, @@ -6,130 +6,123 @@ module id_ex ( input wire excp_flush, input wire ertn_flush, - input wire[`AluOpBus] id_aluop, - input wire[`AluSelBus] id_alusel, - input wire[`RegBus] id_reg1, - input wire[`RegBus] id_reg2, - input wire[`RegAddrBus] id_wd, + input wire [`AluOpBus] id_aluop, + input wire [`AluSelBus] id_alusel, + input wire [`RegBus] id_reg1, + input wire [`RegBus] id_reg2, + input wire [`RegAddrBus] id_wd, input wire id_wreg, input wire id_inst_valid, - input wire[`InstAddrBus] id_inst_pc, - input wire[`RegBus] id_link_address, - input wire[`RegBus] id_inst, + input wire [`InstAddrBus] id_inst_pc, + input wire [`RegBus] id_link_address, + input wire [`RegBus] id_inst, input wire flush, - input wire[1:0] id_excepttype, - input wire[`RegBus] id_current_inst_address, + input wire [1:0] id_excepttype, + input wire [`RegBus] id_current_inst_address, input wire id_csr_we, - input wire[13:0] id_csr_addr, - input wire[`RegBus] id_csr_data, + input wire [13:0] id_csr_addr, + input wire [`RegBus] id_csr_data, - output reg[`AluOpBus] ex_aluop, - output reg[`AluSelBus] ex_alusel, - output reg[`RegBus] ex_reg1, - output reg[`RegBus] ex_reg2, - output reg[`RegAddrBus] ex_wd, + output reg [`AluOpBus] ex_aluop, + output reg [`AluSelBus] ex_alusel, + output reg [`RegBus] ex_reg1, + output reg [`RegBus] ex_reg2, + output reg [`RegAddrBus] ex_wd, output reg ex_wreg, output reg ex_inst_valid, - output reg[`InstAddrBus] ex_inst_pc, - output reg[`RegBus] ex_link_address, - output reg[`RegBus] ex_inst, - output reg[1:0]ex_excepttype, - output reg[`RegBus] ex_current_inst_address, + output reg [`InstAddrBus] ex_inst_pc, + output reg [`RegBus] ex_link_address, + output reg [`RegBus] ex_inst, + output reg [1:0] ex_excepttype, + output reg [`RegBus] ex_current_inst_address, output reg ex_csr_we, - output reg[13:0] ex_csr_addr, - output reg[`RegBus] ex_csr_data, + output reg [13:0] ex_csr_addr, + output reg [`RegBus] ex_csr_data, + + input wire [ `RegAddrBus] reg1_addr_i, + input wire [ `RegAddrBus] reg2_addr_i, + input wire [`InstAddrBus] pc_i_other, + input wire [ `RegAddrBus] reg1_addr_i_other, + input wire [ `RegAddrBus] reg2_addr_i_other, + input wire [ `RegAddrBus] waddr_i_other, - input wire[`RegAddrBus] reg1_addr_i, - input wire[`RegAddrBus] reg2_addr_i, - input wire[`InstAddrBus] pc_i_other, - input wire[`RegAddrBus] reg1_addr_i_other, - input wire[`RegAddrBus] reg2_addr_i_other, - input wire[`RegAddrBus] waddr_i_other, - input stallreq_from_id, output reg stallreq, input wire excp_i, - input wire[8:0] excp_num_i, + input wire [8:0] excp_num_i, output reg excp_o, - output reg[8:0] excp_num_o - ); - - - //always @(*) begin + output reg [8:0] excp_num_o +); + + + //always @(*) begin //stallreq = stallreq_from_id | stallreq1 | stallreq7; - //end + //end - always @(*) begin - stallreq = stallreq_from_id | ((id_inst_pc == pc_i_other + 4) && ( (reg1_addr_i == waddr_i_other) | (reg2_addr_i == waddr_i_other))); - end + always @(*) begin + stallreq = stallreq_from_id | ((id_inst_pc == pc_i_other + 4) && ( (reg1_addr_i == waddr_i_other) | (reg2_addr_i == waddr_i_other))); + end - always @(posedge clk) - begin - if(rst == `RstEnable) - begin - ex_aluop <= `EXE_NOP_OP; - ex_alusel <= `EXE_RES_NOP; - ex_reg1 <= `ZeroWord; - ex_reg2 <= `ZeroWord; - ex_wd <= `NOPRegAddr; - ex_wreg <= `WriteDisable; - ex_inst_pc <= `ZeroWord; - ex_inst_valid <= `InstInvalid; - ex_link_address <= `ZeroWord; - ex_inst <= `ZeroWord; - ex_excepttype <= 2'b00; - ex_current_inst_address <= `ZeroWord; - ex_csr_we <= 1'b0; - ex_csr_addr <= 14'b0; - ex_csr_data <= `ZeroWord; - excp_o <= 1'b0; - excp_num_o <= 9'b0; - end - else if(flush == 1'b1 || excp_flush == 1'b1 || ertn_flush == 1'b1) - begin - ex_aluop <= `EXE_NOP_OP; - ex_alusel <= `EXE_RES_NOP; - ex_reg1 <= `ZeroWord; - ex_reg2 <= `ZeroWord; - ex_wd <= `NOPRegAddr; - ex_wreg <= `WriteDisable; - ex_inst_pc <= `ZeroWord; - ex_inst_valid <= `InstInvalid; - ex_link_address <= `ZeroWord; - ex_inst <= `ZeroWord; - ex_excepttype <= 2'b00; - ex_current_inst_address <= `ZeroWord; - ex_csr_we <= 1'b0; - ex_csr_addr <= 14'b0; - ex_csr_data <= `ZeroWord; - excp_o <= 1'b0; - excp_num_o <= 9'b0; - end - else if(stall == `Stop || stallreq == `Stop) - begin + always @(posedge clk) begin + if (rst == `RstEnable) begin + ex_aluop <= `EXE_NOP_OP; + ex_alusel <= `EXE_RES_NOP; + ex_reg1 <= `ZeroWord; + ex_reg2 <= `ZeroWord; + ex_wd <= `NOPRegAddr; + ex_wreg <= `WriteDisable; + ex_inst_pc <= `ZeroWord; + ex_inst_valid <= `InstInvalid; + ex_link_address <= `ZeroWord; + ex_inst <= `ZeroWord; + ex_excepttype <= 2'b00; + ex_current_inst_address <= `ZeroWord; + ex_csr_we <= 1'b0; + ex_csr_addr <= 14'b0; + ex_csr_data <= `ZeroWord; + excp_o <= 1'b0; + excp_num_o <= 9'b0; + end else if (flush == 1'b1 || excp_flush == 1'b1 || ertn_flush == 1'b1) begin + ex_aluop <= `EXE_NOP_OP; + ex_alusel <= `EXE_RES_NOP; + ex_reg1 <= `ZeroWord; + ex_reg2 <= `ZeroWord; + ex_wd <= `NOPRegAddr; + ex_wreg <= `WriteDisable; + ex_inst_pc <= `ZeroWord; + ex_inst_valid <= `InstInvalid; + ex_link_address <= `ZeroWord; + ex_inst <= `ZeroWord; + ex_excepttype <= 2'b00; + ex_current_inst_address <= `ZeroWord; + ex_csr_we <= 1'b0; + ex_csr_addr <= 14'b0; + ex_csr_data <= `ZeroWord; + excp_o <= 1'b0; + excp_num_o <= 9'b0; + end else + if (stall == `Stop || stallreq == `Stop) begin - end - else - begin - ex_aluop <= id_aluop; - ex_alusel <= id_alusel; - ex_reg1 <= id_reg1; - ex_reg2 <= id_reg2; - ex_wd <= id_wd; - ex_wreg <= id_wreg; - ex_inst_pc <= id_inst_pc; - ex_inst_valid <= id_inst_valid; - ex_link_address <= id_link_address; - ex_inst <= id_inst; - ex_excepttype <= id_excepttype; - ex_current_inst_address <= id_current_inst_address; - ex_csr_we <= id_csr_we; - ex_csr_addr <= id_csr_addr; - ex_csr_data <= id_csr_data; - excp_o <= excp_i; - excp_num_o <= excp_num_i; + end else begin + ex_aluop <= id_aluop; + ex_alusel <= id_alusel; + ex_reg1 <= id_reg1; + ex_reg2 <= id_reg2; + ex_wd <= id_wd; + ex_wreg <= id_wreg; + ex_inst_pc <= id_inst_pc; + ex_inst_valid <= id_inst_valid; + ex_link_address <= id_link_address; + ex_inst <= id_inst; + ex_excepttype <= id_excepttype; + ex_current_inst_address <= id_current_inst_address; + ex_csr_we <= id_csr_we; + ex_csr_addr <= id_csr_addr; + ex_csr_data <= id_csr_data; + excp_o <= excp_i; + excp_num_o <= excp_num_i; end end diff --git a/src/vsrc/pipeline/3_execution/ex.v b/src/vsrc/pipeline/3_execution/ex.v index 977640e..d7050aa 100644 --- a/src/vsrc/pipeline/3_execution/ex.v +++ b/src/vsrc/pipeline/3_execution/ex.v @@ -1,39 +1,39 @@ -`include "../../defines.v" +`include "defines.v" module ex ( input wire rst, - input wire[`AluOpBus] aluop_i, - input wire[`AluSelBus] alusel_i, - input wire[`RegBus] reg1_i, - input wire[`RegBus] reg2_i, - input wire[`RegAddrBus] wd_i, + input wire [`AluOpBus] aluop_i, + input wire [`AluSelBus] alusel_i, + input wire [`RegBus] reg1_i, + input wire [`RegBus] reg2_i, + input wire [`RegAddrBus] wd_i, input wire wreg_i, input wire inst_valid_i, - input wire[`InstAddrBus] inst_pc_i, - input wire[`RegBus] inst_i, - input wire[`RegBus] link_addr_i, - input wire[1:0] excepttype_i, - input wire[`RegBus] current_inst_address_i, + input wire [`InstAddrBus] inst_pc_i, + input wire [`RegBus] inst_i, + input wire [`RegBus] link_addr_i, + input wire [1:0] excepttype_i, + input wire [`RegBus] current_inst_address_i, input wire ex_csr_we_i, - input wire [13:0]ex_csr_addr_i, - input wire [`RegBus]ex_csr_data_i, + input wire [13:0] ex_csr_addr_i, + input wire [`RegBus] ex_csr_data_i, - input wire[18:0] csr_vppn, + input wire [18:0] csr_vppn, - output reg[`RegAddrBus] wd_o, + output reg [`RegAddrBus] wd_o, output reg wreg_o, - output reg[`RegBus] wdata_o, + output reg [`RegBus] wdata_o, output reg inst_valid_o, - output reg[`InstAddrBus] inst_pc_o, - output wire[`AluOpBus] aluop_o, - output wire[`RegBus] mem_addr_o, - output wire[`RegBus] reg2_o, - output wire[1:0] excepttype_o, - output wire[`RegBus] current_inst_address_o, + output reg [`InstAddrBus] inst_pc_o, + output wire [`AluOpBus] aluop_o, + output wire [`RegBus] mem_addr_o, + output wire [`RegBus] reg2_o, + output wire [1:0] excepttype_o, + output wire [`RegBus] current_inst_address_o, output wire ex_csr_we_o, - output wire [13:0]ex_csr_addr_o, - output wire [`RegBus]ex_csr_data_o, + output wire [13:0] ex_csr_addr_o, + output wire [`RegBus] ex_csr_data_o, output wire stallreq, @@ -41,223 +41,173 @@ module ex ( input wire [8:0] excp_num_i, output wire excp_o, output wire [9:0] excp_num_o - ); - - reg[`RegBus] logicout; - reg[`RegBus] shiftout; - reg[`RegBus] moveout; - reg[`RegBus] arithout; - - assign aluop_o = aluop_i; - assign mem_addr_o = reg1_i + {{20{inst_i[21]}},inst_i[21:10]}; - assign reg2_o = reg2_i; - - assign excepttype_o = excepttype_i; - assign current_inst_address_o = current_inst_address_i; - - assign ex_csr_we_o = ex_csr_we_i; - assign ex_csr_addr_o = ex_csr_addr_i; - assign ex_csr_data_o = ex_csr_data_i; - - assign excp_o = excp_i || 1'b0; - assign excp_num_o = {1'b0, excp_num_i}; - - always @(*) - begin - if(rst == `RstEnable) - begin - logicout = `ZeroWord; - end - else - begin - inst_pc_o = inst_pc_i; - inst_valid_o = inst_valid_i; - case (aluop_i) - `EXE_OR_OP: - begin - logicout = reg1_i | reg2_i; - end - `EXE_AND_OP: - begin - logicout = reg1_i & reg2_i; - end - `EXE_XOR_OP: - begin - logicout = reg1_i ^ reg2_i; - end - `EXE_NOR_OP: - begin - logicout = ~( reg1_i | reg2_i); - end - default: - begin - end - endcase +); + + reg [`RegBus] logicout; + reg [`RegBus] shiftout; + reg [`RegBus] moveout; + reg [`RegBus] arithout; + + assign aluop_o = aluop_i; + assign mem_addr_o = reg1_i + {{20{inst_i[21]}}, inst_i[21:10]}; + assign reg2_o = reg2_i; + + assign excepttype_o = excepttype_i; + assign current_inst_address_o = current_inst_address_i; + + assign ex_csr_we_o = ex_csr_we_i; + assign ex_csr_addr_o = ex_csr_addr_i; + assign ex_csr_data_o = ex_csr_data_i; + + assign excp_o = excp_i || 1'b0; + assign excp_num_o = {1'b0, excp_num_i}; + + always @(*) begin + if (rst == `RstEnable) begin + logicout = `ZeroWord; + end else begin + inst_pc_o = inst_pc_i; + inst_valid_o = inst_valid_i; + case (aluop_i) + `EXE_OR_OP: begin + logicout = reg1_i | reg2_i; + end + `EXE_AND_OP: begin + logicout = reg1_i & reg2_i; + end + `EXE_XOR_OP: begin + logicout = reg1_i ^ reg2_i; + end + `EXE_NOR_OP: begin + logicout = ~(reg1_i | reg2_i); + end + default: begin + end + endcase end end - always @(*) - begin - if(rst == `RstEnable) - begin - shiftout = `ZeroWord; - end - else - begin - // inst_pc_o = inst_pc_i; - // inst_valid_o = inst_valid_i; - case (aluop_i) - `EXE_SLL_OP: - begin - shiftout = reg1_i << reg2_i[4:0]; - end - `EXE_SRL_OP: - begin - shiftout = reg1_i >> reg2_i[4:0]; - end - `EXE_SRA_OP: - begin - shiftout = ({32{reg1_i[31]}} << (6'd32-{1'b0,reg2_i[4:0]})) | reg1_i >> reg2_i[4:0]; - end - default: - begin - end - endcase + always @(*) begin + if (rst == `RstEnable) begin + shiftout = `ZeroWord; + end else begin + // inst_pc_o = inst_pc_i; + // inst_valid_o = inst_valid_i; + case (aluop_i) + `EXE_SLL_OP: begin + shiftout = reg1_i << reg2_i[4:0]; + end + `EXE_SRL_OP: begin + shiftout = reg1_i >> reg2_i[4:0]; + end + `EXE_SRA_OP: begin + shiftout = ({32{reg1_i[31]}} << (6'd32-{1'b0,reg2_i[4:0]})) | reg1_i >> reg2_i[4:0]; + end + default: begin + end + endcase end end - //比较模块 - wire reg1_lt_reg2; - wire[`RegBus] reg2_i_mux; - wire[`RegBus] reg1_i_mux; - wire[`RegBus] result_compare; + //比较模块 + wire reg1_lt_reg2; + wire [`RegBus] reg2_i_mux; + wire [`RegBus] reg1_i_mux; + wire [`RegBus] result_compare; - assign reg2_i_mux = (aluop_i == `EXE_SLT_OP) ? {~reg2_i[`RegWidth-1], reg2_i[`RegWidth-2:0]} : reg2_i; // shifted encoding when signed comparison - assign reg1_i_mux = (aluop_i == `EXE_SLT_OP) ? {~reg1_i[`RegWidth-1], reg1_i[`RegWidth-2:0]} : reg1_i; - assign result_compare = reg1_i + reg2_i_mux; - assign reg1_lt_reg2 = (reg1_i_mux < reg2_i_mux); + assign reg2_i_mux = (aluop_i == `EXE_SLT_OP) ? {~reg2_i[`RegWidth-1], reg2_i[`RegWidth-2:0]} : reg2_i; // shifted encoding when signed comparison + assign reg1_i_mux = (aluop_i == `EXE_SLT_OP) ? {~reg1_i[`RegWidth-1], reg1_i[`RegWidth-2:0]} : reg1_i; + assign result_compare = reg1_i + reg2_i_mux; + assign reg1_lt_reg2 = (reg1_i_mux < reg2_i_mux); - //乘法模块 + //乘法模块 - wire[`RegBus] opdata1_mul; - wire[`RegBus] opdata2_mul; - wire[`DoubleRegBus] hilo_temp; - reg[`DoubleRegBus]mulres; + wire [`RegBus] opdata1_mul; + wire [`RegBus] opdata2_mul; + wire [`DoubleRegBus] hilo_temp; + reg [`DoubleRegBus] mulres; - assign opdata1_mul = (((aluop_i == `EXE_MUL_OP) || (aluop_i == `EXE_MULH_OP)) + assign opdata1_mul = (((aluop_i == `EXE_MUL_OP) || (aluop_i == `EXE_MULH_OP)) && (reg1_i[31] == 1'b1)) ? (~reg1_i + 1) : reg1_i; - assign opdata2_mul = (((aluop_i == `EXE_MUL_OP) || (aluop_i == `EXE_MULH_OP)) + assign opdata2_mul = (((aluop_i == `EXE_MUL_OP) || (aluop_i == `EXE_MULH_OP)) && (reg2_i[31] == 1'b1)) ? (~reg2_i + 1) : reg1_i; - assign hilo_temp = opdata1_mul * opdata2_mul; + assign hilo_temp = opdata1_mul * opdata2_mul; - always @(*) - begin - if(rst == `RstEnable) - mulres = {`ZeroWord,`ZeroWord}; - else if((aluop_i == `EXE_MUL_OP) || (aluop_i == `EXE_MULH_OP)) - begin - if(reg1_i[31] ^ reg2_i[31] == 1'b1) - mulres = ~hilo_temp + 1; - else - mulres = hilo_temp; - end - else - mulres = hilo_temp; + always @(*) begin + if (rst == `RstEnable) mulres = {`ZeroWord, `ZeroWord}; + else if ((aluop_i == `EXE_MUL_OP) || (aluop_i == `EXE_MULH_OP)) begin + if (reg1_i[31] ^ reg2_i[31] == 1'b1) mulres = ~hilo_temp + 1; + else mulres = hilo_temp; + end else mulres = hilo_temp; end - always @(*) - begin - if(rst == `RstEnable) - begin - arithout = `ZeroWord; - end - else - begin - // inst_pc_o = inst_pc_i; - // inst_valid_o = inst_valid_i; - case (aluop_i) - `EXE_ADD_OP: - arithout = reg1_i + reg2_i; - `EXE_SUB_OP: - arithout = reg1_i - reg2_i; - `EXE_MUL_OP: - arithout = mulres[31:0]; - `EXE_MULH_OP,`EXE_MULHU_OP: - arithout = mulres[63:32]; - `EXE_DIV_OP: - arithout = reg1_i / reg2_i; - `EXE_MOD_OP: - arithout = reg1_i % reg2_i; - `EXE_SLT_OP,`EXE_SLTU_OP: - arithout = {31'b0,reg1_lt_reg2}; - default: - begin - end - endcase + always @(*) begin + if (rst == `RstEnable) begin + arithout = `ZeroWord; + end else begin + // inst_pc_o = inst_pc_i; + // inst_valid_o = inst_valid_i; + case (aluop_i) + `EXE_ADD_OP: arithout = reg1_i + reg2_i; + `EXE_SUB_OP: arithout = reg1_i - reg2_i; + `EXE_MUL_OP: arithout = mulres[31:0]; + `EXE_MULH_OP, `EXE_MULHU_OP: arithout = mulres[63:32]; + `EXE_DIV_OP: arithout = reg1_i / reg2_i; + `EXE_MOD_OP: arithout = reg1_i % reg2_i; + `EXE_SLT_OP, `EXE_SLTU_OP: arithout = {31'b0, reg1_lt_reg2}; + default: begin + end + endcase end end - always @(*) - begin - if(rst == `RstEnable) - begin - moveout = `ZeroWord; - end - else - begin - // inst_pc_o = inst_pc_i; - // inst_valid_o = inst_valid_i; - case (aluop_i) - `EXE_LUI_OP: - begin - moveout = reg2_i; - end - `EXE_PCADD_OP: - begin - moveout = reg2_i + inst_pc_o; - end - default: - begin - end - endcase + always @(*) begin + if (rst == `RstEnable) begin + moveout = `ZeroWord; + end else begin + // inst_pc_o = inst_pc_i; + // inst_valid_o = inst_valid_i; + case (aluop_i) + `EXE_LUI_OP: begin + moveout = reg2_i; + end + `EXE_PCADD_OP: begin + moveout = reg2_i + inst_pc_o; + end + default: begin + end + endcase end end - always @(*) - begin - wd_o = wd_i; - wreg_o = wreg_i; - case (alusel_i) - `EXE_RES_LOGIC: - begin - wdata_o = logicout; - end - `EXE_RES_SHIFT: - begin - wdata_o = shiftout; - end - `EXE_RES_MOVE: - begin - wdata_o = moveout; - end - `EXE_RES_ARITH: - begin - wdata_o = arithout; - end - `EXE_RES_JUMP: - begin - wdata_o = link_addr_i; - end - default: - begin - wdata_o = `ZeroWord; - end - endcase + always @(*) begin + wd_o = wd_i; + wreg_o = wreg_i; + case (alusel_i) + `EXE_RES_LOGIC: begin + wdata_o = logicout; + end + `EXE_RES_SHIFT: begin + wdata_o = shiftout; + end + `EXE_RES_MOVE: begin + wdata_o = moveout; + end + `EXE_RES_ARITH: begin + wdata_o = arithout; + end + `EXE_RES_JUMP: begin + wdata_o = link_addr_i; + end + default: begin + wdata_o = `ZeroWord; + end + endcase end endmodule diff --git a/src/vsrc/pipeline/3_execution/ex_mem.v b/src/vsrc/pipeline/3_execution/ex_mem.v index 14ca363..6ce919d 100644 --- a/src/vsrc/pipeline/3_execution/ex_mem.v +++ b/src/vsrc/pipeline/3_execution/ex_mem.v @@ -1,4 +1,4 @@ -`include "../../defines.v" +`include "defines.v" module ex_mem ( input wire clk, @@ -7,98 +7,91 @@ module ex_mem ( input wire excp_flush, input wire ertn_flush, - input wire[`RegAddrBus] ex_wd, + input wire [`RegAddrBus] ex_wd, input wire ex_wreg, - input wire[`RegBus] ex_wdata, + input wire [`RegBus] ex_wdata, input wire ex_inst_valid, - input wire[`InstAddrBus] ex_inst_pc, - input wire[`AluOpBus] ex_aluop, - input wire[`RegBus] ex_mem_addr, - input wire[`RegBus] ex_reg2, + input wire [`InstAddrBus] ex_inst_pc, + input wire [`AluOpBus] ex_aluop, + input wire [`RegBus] ex_mem_addr, + input wire [`RegBus] ex_reg2, input wire flush, - input wire[1:0] ex_excepttype, - input wire[`RegBus] ex_current_inst_address, + input wire [1:0] ex_excepttype, + input wire [`RegBus] ex_current_inst_address, input wire ex_csr_we, - input wire [13:0]ex_csr_addr, - input wire [`RegBus]ex_csr_data, + input wire [13:0] ex_csr_addr, + input wire [`RegBus] ex_csr_data, input wire excp_i, input wire [9:0] excp_num_i, - output reg[`RegAddrBus] mem_wd, + output reg [`RegAddrBus] mem_wd, output reg mem_wreg, - output reg[`RegBus] mem_wdata, + output reg [`RegBus] mem_wdata, output reg mem_inst_valid, - output reg[`InstAddrBus] mem_inst_pc, - output reg[`AluOpBus] mem_aluop, - output reg[`RegBus] mem_mem_addr, - output reg[`RegBus] mem_reg2, - output reg[1:0] mem_excepttype, - output reg[`RegBus] mem_current_inst_address, + output reg [`InstAddrBus] mem_inst_pc, + output reg [`AluOpBus] mem_aluop, + output reg [`RegBus] mem_mem_addr, + output reg [`RegBus] mem_reg2, + output reg [1:0] mem_excepttype, + output reg [`RegBus] mem_current_inst_address, output reg mem_csr_we, - output reg[13:0] mem_csr_addr, - output reg[`RegBus] mem_csr_data, + output reg [13:0] mem_csr_addr, + output reg [`RegBus] mem_csr_data, output reg excp_o, output reg [9:0] excp_num_o - ); +); - always @ (posedge clk) - begin - if (rst == `RstEnable) - begin - mem_wd <= `NOPRegAddr; - mem_wreg <= `WriteDisable; - mem_wdata <= `ZeroWord; - mem_inst_pc <= `ZeroWord; - mem_inst_valid <= `InstInvalid; - mem_aluop <= `EXE_NOP_OP; - mem_mem_addr <= `ZeroWord; - mem_reg2 <= `ZeroWord; - mem_excepttype <= 2'b00; - mem_current_inst_address <= `ZeroWord; - mem_csr_we <= 1'b1; - mem_csr_addr <= 14'b0; - mem_csr_data <= `ZeroWord; - excp_o <= 1'b0; - excp_num_o <= 10'b0; - end - else if(flush == 1'b1 || excp_flush == 1'b1 || ertn_flush == 1'b1) - begin - mem_wd <= `NOPRegAddr; - mem_wreg <= `WriteDisable; - mem_wdata <= `ZeroWord; - mem_inst_pc <= `ZeroWord; - mem_inst_valid <= `InstInvalid; - mem_aluop <= `EXE_NOP_OP; - mem_mem_addr <= `ZeroWord; - mem_reg2 <= `ZeroWord; - mem_excepttype <= 2'b00; - mem_current_inst_address <= `ZeroWord; - mem_csr_we <= 1'b1; - mem_csr_addr <= 14'b0; - mem_csr_data <= `ZeroWord; - excp_o <= 1'b0; - excp_num_o <= 10'b0; - end - else if(stall == `Stop) - begin - end - else - begin - mem_wd <= ex_wd; - mem_wreg <= ex_wreg; - mem_wdata <= ex_wdata; - mem_inst_pc <= ex_inst_pc; - mem_inst_valid <= ex_inst_valid; - mem_aluop <= ex_aluop; - mem_mem_addr <= ex_mem_addr; - mem_reg2 <= ex_reg2; - mem_excepttype <= ex_excepttype; - mem_current_inst_address <= ex_current_inst_address; - mem_csr_we <= ex_csr_we; - mem_csr_addr <= ex_csr_addr; - mem_csr_data <= ex_csr_data; - excp_o <= excp_i; - excp_num_o <= excp_num_i; + always @(posedge clk) begin + if (rst == `RstEnable) begin + mem_wd <= `NOPRegAddr; + mem_wreg <= `WriteDisable; + mem_wdata <= `ZeroWord; + mem_inst_pc <= `ZeroWord; + mem_inst_valid <= `InstInvalid; + mem_aluop <= `EXE_NOP_OP; + mem_mem_addr <= `ZeroWord; + mem_reg2 <= `ZeroWord; + mem_excepttype <= 2'b00; + mem_current_inst_address <= `ZeroWord; + mem_csr_we <= 1'b1; + mem_csr_addr <= 14'b0; + mem_csr_data <= `ZeroWord; + excp_o <= 1'b0; + excp_num_o <= 10'b0; + end else if (flush == 1'b1 || excp_flush == 1'b1 || ertn_flush == 1'b1) begin + mem_wd <= `NOPRegAddr; + mem_wreg <= `WriteDisable; + mem_wdata <= `ZeroWord; + mem_inst_pc <= `ZeroWord; + mem_inst_valid <= `InstInvalid; + mem_aluop <= `EXE_NOP_OP; + mem_mem_addr <= `ZeroWord; + mem_reg2 <= `ZeroWord; + mem_excepttype <= 2'b00; + mem_current_inst_address <= `ZeroWord; + mem_csr_we <= 1'b1; + mem_csr_addr <= 14'b0; + mem_csr_data <= `ZeroWord; + excp_o <= 1'b0; + excp_num_o <= 10'b0; + end else + if (stall == `Stop) begin + end else begin + mem_wd <= ex_wd; + mem_wreg <= ex_wreg; + mem_wdata <= ex_wdata; + mem_inst_pc <= ex_inst_pc; + mem_inst_valid <= ex_inst_valid; + mem_aluop <= ex_aluop; + mem_mem_addr <= ex_mem_addr; + mem_reg2 <= ex_reg2; + mem_excepttype <= ex_excepttype; + mem_current_inst_address <= ex_current_inst_address; + mem_csr_we <= ex_csr_we; + mem_csr_addr <= ex_csr_addr; + mem_csr_data <= ex_csr_data; + excp_o <= excp_i; + excp_num_o <= excp_num_i; end end diff --git a/src/vsrc/pipeline/4_mem/mem.v b/src/vsrc/pipeline/4_mem/mem.v index e2c7f84..534aa1b 100644 --- a/src/vsrc/pipeline/4_mem/mem.v +++ b/src/vsrc/pipeline/4_mem/mem.v @@ -1,31 +1,31 @@ -`timescale 1ns/1ns +`timescale 1ns / 1ns -`include "../../defines.v" -`include "../../csr_defines.v" +`include "defines.v" +`include "csr_defines.v" module mem ( input wire rst, - input wire[`InstAddrBus] inst_pc_i, - input wire[`RegAddrBus] wd_i, + input wire [`InstAddrBus] inst_pc_i, + input wire [`RegAddrBus] wd_i, input wire wreg_i, - input wire[`RegBus] wdata_i, - input wire[`AluOpBus] aluop_i, - input wire[`RegBus] mem_addr_i, - input wire[`RegBus] reg2_i, + input wire [`RegBus] wdata_i, + input wire [`AluOpBus] aluop_i, + input wire [`RegBus] mem_addr_i, + input wire [`RegBus] reg2_i, - input wire[`RegBus] mem_data_i, + input wire [`RegBus] mem_data_i, input wire LLbit_i, input wire wb_LLbit_we_i, input wire wb_LLbit_value_i, - input wire[1:0] excepttype_i, - input wire[`RegBus] current_inst_address_i, + input wire [1:0] excepttype_i, + input wire [`RegBus] current_inst_address_i, input wire mem_csr_we_i, - input wire[13:0] mem_csr_addr_i, - input wire[`RegBus] mem_csr_data_i, + input wire [13:0] mem_csr_addr_i, + input wire [`RegBus] mem_csr_data_i, input wire excp_i, input wire [9:0] excp_num_i, @@ -33,351 +33,304 @@ module mem ( //from csr input wire csr_pg, input wire csr_da, - input wire [31:0]csr_dmw0, - input wire [31:0]csr_dmw1, - input wire [1:0]csr_plv, - input wire [1:0]csr_datf, - input wire disable_cache, + input wire [31:0] csr_dmw0, + input wire [31:0] csr_dmw1, + input wire [1:0] csr_plv, + input wire [1:0] csr_datf, + input wire disable_cache, //to addr trans - output wire data_addr_trans_en, + output wire data_addr_trans_en, output wire dmw0_en, output wire dmw1_en, - output wire cacop_op_mode_di, + output wire cacop_op_mode_di, //tlb input wire data_tlb_found, - input wire [4:0]data_tlb_index, + input wire [4:0] data_tlb_index, input wire data_tlb_v, input wire data_tlb_d, input wire [1:0] data_tlb_mat, input wire [1:0] data_tlb_plv, - output reg[`InstAddrBus] inst_pc_o, - output reg[`RegAddrBus] wd_o, + output reg [`InstAddrBus] inst_pc_o, + output reg [`RegAddrBus] wd_o, output reg wreg_o, - output reg[`RegBus] wdata_o, - output reg[`AluOpBus] aluop_o, + output reg [`RegBus] wdata_o, + output reg [`AluOpBus] aluop_o, - output reg[`RegBus] mem_addr_o, + output reg [`RegBus] mem_addr_o, output wire mem_we_o, - output reg[3:0] mem_sel_o, - output reg[`RegBus] mem_data_o, + output reg [3:0] mem_sel_o, + output reg [`RegBus] mem_data_o, output reg mem_ce_o, output reg LLbit_we_o, output reg LLbit_value_o, - output wire[1:0] excepttype_o, - output wire[`RegBus] current_inst_address_o, + output wire [1:0] excepttype_o, + output wire [`RegBus] current_inst_address_o, output wire mem_csr_we_o, - output wire[13:0] mem_csr_addr_o, - output wire[`RegBus] mem_csr_data_o, + output wire [13:0] mem_csr_addr_o, + output wire [`RegBus] mem_csr_data_o, output wire excp_o, - output wire[15:0] excp_num_o - ); - - reg mem_we; - reg LLbit; - wire access_mem; - wire mem_store_op; - wire mem_load_op; - wire excp_adem; - wire pg_mode; - wire da_mode; - wire excp_tlbr; - wire excp_pil; - wire excp_pis; - wire excp_pme; - wire excp_ppi; - - assign access_mem = mem_load_op || mem_store_op; - - assign mem_load_op = aluop_i == `EXE_LD_B_OP || aluop_i == `EXE_LD_BU_OP || aluop_i == `EXE_LD_H_OP || aluop_i == `EXE_LD_HU_OP || + output wire [15:0] excp_num_o +); + + reg mem_we; + reg LLbit; + wire access_mem; + wire mem_store_op; + wire mem_load_op; + wire excp_adem; + wire pg_mode; + wire da_mode; + wire excp_tlbr; + wire excp_pil; + wire excp_pis; + wire excp_pme; + wire excp_ppi; + + assign access_mem = mem_load_op || mem_store_op; + + assign mem_load_op = aluop_i == `EXE_LD_B_OP || aluop_i == `EXE_LD_BU_OP || aluop_i == `EXE_LD_H_OP || aluop_i == `EXE_LD_HU_OP || aluop_i == `EXE_LD_W_OP || aluop_i == `EXE_LL_OP; - - assign mem_store_op = aluop_i == `EXE_ST_B_OP || aluop_i == `EXE_ST_H_OP || aluop_i == `EXE_ST_W_OP || aluop_i == `EXE_SC_OP; - - assign mem_we_o = mem_we & (~(|excepttype_i)); - - assign excepttype_o = excepttype_i; - assign current_inst_address_o = current_inst_address_i; - - assign mem_csr_we_o = mem_csr_we_i; - assign mem_csr_addr_o = mem_csr_we_o; - assign mem_csr_data_o = mem_csr_data_i; - - //addr dmw trans - assign dmw0_en = ((csr_dmw0[`PLV0] && csr_plv == 2'd0) || (csr_dmw0[`PLV3] && csr_plv == 2'd3)) && (wdata_i[31:29] == csr_dmw0[`VSEG]); - assign dmw1_en = ((csr_dmw1[`PLV0] && csr_plv == 2'd0) || (csr_dmw1[`PLV3] && csr_plv == 2'd3)) && (wdata_i[31:29] == csr_dmw1[`VSEG]); - - assign pg_mode = !csr_da && csr_pg; - assign da_mode = csr_da && !csr_pg; - - assign data_addr_trans_en = pg_mode && !dmw0_en && !dmw1_en && !cacop_op_mode_di; - - assign excp_tlbr = access_mem && !data_tlb_found && data_addr_trans_en; - assign excp_pil = mem_load_op && !data_tlb_v && data_addr_trans_en; //cache will generate pil exception?? - assign excp_pis = mem_store_op && !data_tlb_v && data_addr_trans_en; - assign excp_ppi = access_mem && data_tlb_v && (csr_plv > data_tlb_plv) && data_addr_trans_en; - assign excp_pme = mem_store_op && data_tlb_v && (csr_plv <= data_tlb_plv) && !data_tlb_d && data_addr_trans_en; - - assign excp_o = excp_tlbr || excp_pil || excp_pis || excp_ppi || excp_pme || excp_adem || excp_i; - assign excp_num_o = {excp_pil, excp_pis, excp_ppi, excp_pme, excp_tlbr, excp_adem, excp_num_i}; - - always @(*) - begin - if(rst == `RstEnable) - LLbit = 1'b0; - else - begin - if(wb_LLbit_we_i == 1'b1) - LLbit = wb_LLbit_value_i; - else - LLbit = LLbit_i; - end - end - always @ (*) - begin - if (rst == `RstEnable) - begin - wd_o = `NOPRegAddr; - wreg_o = `WriteDisable; - wdata_o = `ZeroWord; - mem_addr_o = `ZeroWord; - mem_we = `WriteDisable; - mem_sel_o = 4'b0000; - mem_data_o = `ZeroWord; - mem_ce_o = `ChipDisable; - LLbit_we_o = 1'b0; - LLbit_value_o = 1'b0; - inst_pc_o = `ZeroWord; - end - else - begin - wd_o = wd_i; - wreg_o = wreg_i; - wdata_o = wdata_i; - mem_addr_o = `ZeroWord; - mem_we = `WriteDisable; - mem_ce_o = `ChipDisable; - mem_sel_o = 4'b1111; - LLbit_we_o = 1'b0; - LLbit_value_o = 1'b0; - inst_pc_o = inst_pc_i; - case (aluop_i) - `EXE_LD_B_OP: - begin - mem_addr_o = mem_addr_i; - mem_we = `WriteDisable; - mem_ce_o = `ChipEnable; - case(mem_addr_i[1:0]) - 2'b00: - begin - wdata_o = {{24{mem_data_i[31]}},mem_data_i[31:24]}; - mem_sel_o = 4'b1000; - end - 2'b01: - begin - wdata_o = {{24{mem_data_i[23]}},mem_data_i[23:16]}; - mem_sel_o = 4'b0100; - end - 2'b10: - begin - wdata_o = {{24{mem_data_i[15]}},mem_data_i[15:8]}; - mem_sel_o = 4'b0010; - end - 2'b11: - begin - wdata_o = {{24{mem_data_i[7]}},mem_data_i[7:0]}; - mem_sel_o = 4'b0001; - end - default: - begin - wdata_o = `ZeroWord; - end - endcase - end - `EXE_LD_H_OP: - begin - mem_addr_o = mem_addr_i; - mem_we = `WriteDisable; - mem_ce_o = `ChipEnable; - case(mem_addr_i[1:0]) - 2'b00: - begin - wdata_o = {{16{mem_data_i[31]}},mem_data_i[31:16]}; - mem_sel_o = 4'b1100; - end + assign mem_store_op = aluop_i == `EXE_ST_B_OP || aluop_i == `EXE_ST_H_OP || aluop_i == `EXE_ST_W_OP || aluop_i == `EXE_SC_OP; - 2'b10: - begin - wdata_o = {{16{mem_data_i[15]}},mem_data_i[15:0]}; - mem_sel_o = 4'b0011; - end + assign mem_we_o = mem_we & (~(|excepttype_i)); - default: - begin - wdata_o = `ZeroWord; - end - endcase - end - `EXE_LD_W_OP: - begin - mem_addr_o = mem_addr_i; - mem_we = `WriteDisable; - mem_ce_o = `ChipEnable; - mem_sel_o = 4'b1111; - wdata_o = mem_data_i; - end - `EXE_LD_BU_OP: - begin - mem_addr_o = mem_addr_i; - mem_we = `WriteDisable; - mem_ce_o = `ChipEnable; - case(mem_addr_i[1:0]) - 2'b00: - begin - wdata_o = {{24{1'b0}},mem_data_i[31:24]}; - mem_sel_o = 4'b1000; - end - 2'b01: - begin - wdata_o = {{24{1'b0}},mem_data_i[23:16]}; - mem_sel_o = 4'b0100; - end - 2'b10: - begin - wdata_o = {{24{1'b0}},mem_data_i[15:8]}; - mem_sel_o = 4'b0010; - end - 2'b11: - begin - wdata_o = {{24{1'b0}},mem_data_i[7:0]}; - mem_sel_o = 4'b0001; - end - default: - begin - wdata_o = `ZeroWord; - end - endcase - end - `EXE_LD_HU_OP: - begin - mem_addr_o = mem_addr_i; - mem_we = `WriteDisable; - mem_ce_o = `ChipEnable; - case(mem_addr_i[1:0]) - 2'b00: - begin - wdata_o = {{16{1'b0}},mem_data_i[31:16]}; - mem_sel_o = 4'b1100; - end - 2'b10: - begin - wdata_o = {{16{1'b0}},mem_data_i[15:0]}; - mem_sel_o = 4'b0011; - end - default: - begin - wdata_o = `ZeroWord; - end - endcase - end - `EXE_ST_B_OP: - begin - mem_addr_o = mem_addr_i; - mem_we = `WriteEnable; - mem_ce_o = `ChipEnable; - mem_data_o = {reg2_i[7:0],reg2_i[7:0],reg2_i[7:0],reg2_i[7:0]}; - case(mem_addr_i[1:0]) - 2'b00: - begin - mem_sel_o = 4'b1000; - end - 2'b01: - begin - mem_sel_o = 4'b0100; - end - 2'b10: - begin - mem_sel_o = 4'b0010; - end - 2'b11: - begin - mem_sel_o = 4'b0001; - end - default: - begin - mem_sel_o = 4'b0000; - end - endcase - end - `EXE_ST_H_OP: - begin - mem_addr_o = mem_addr_i; - mem_we = `WriteEnable; - mem_ce_o = `ChipEnable; - mem_data_o = {reg2_i[15:0],reg2_i[15:0]}; - case(mem_addr_i[1:0]) - 2'b00: - begin - mem_sel_o = 4'b1100; - end - 2'b10: - begin - mem_sel_o = 4'b0011; - end - default: - begin - mem_sel_o = 4'b0000; - end - endcase - end - `EXE_ST_W_OP: - begin - mem_addr_o = mem_addr_i; - mem_we = `WriteEnable; - mem_ce_o = `ChipEnable; - mem_data_o = reg2_i; - mem_sel_o = 4'b1111; - end - `EXE_LL_OP: - begin - mem_addr_o = mem_addr_i; - mem_we = `WriteDisable; - mem_ce_o = `ChipEnable; - mem_sel_o = 4'b1111; - wdata_o = mem_data_i; - LLbit_we_o = 1'b1; - LLbit_value_o = 1'b1; - end - `EXE_SC_OP: - begin - if(LLbit == 1'b1) - begin + assign excepttype_o = excepttype_i; + assign current_inst_address_o = current_inst_address_i; + + assign mem_csr_we_o = mem_csr_we_i; + assign mem_csr_addr_o = mem_csr_we_o; + assign mem_csr_data_o = mem_csr_data_i; + + //addr dmw trans + assign dmw0_en = ((csr_dmw0[`PLV0] && csr_plv == 2'd0) || (csr_dmw0[`PLV3] && csr_plv == 2'd3)) && (wdata_i[31:29] == csr_dmw0[`VSEG]); + assign dmw1_en = ((csr_dmw1[`PLV0] && csr_plv == 2'd0) || (csr_dmw1[`PLV3] && csr_plv == 2'd3)) && (wdata_i[31:29] == csr_dmw1[`VSEG]); + + assign pg_mode = !csr_da && csr_pg; + assign da_mode = csr_da && !csr_pg; + + assign data_addr_trans_en = pg_mode && !dmw0_en && !dmw1_en && !cacop_op_mode_di; + + assign excp_tlbr = access_mem && !data_tlb_found && data_addr_trans_en; + assign excp_pil = mem_load_op && !data_tlb_v && data_addr_trans_en; //cache will generate pil exception?? + assign excp_pis = mem_store_op && !data_tlb_v && data_addr_trans_en; + assign excp_ppi = access_mem && data_tlb_v && (csr_plv > data_tlb_plv) && data_addr_trans_en; + assign excp_pme = mem_store_op && data_tlb_v && (csr_plv <= data_tlb_plv) && !data_tlb_d && data_addr_trans_en; + + assign excp_o = excp_tlbr || excp_pil || excp_pis || excp_ppi || excp_pme || excp_adem || excp_i; + assign excp_num_o = {excp_pil, excp_pis, excp_ppi, excp_pme, excp_tlbr, excp_adem, excp_num_i}; + + always @(*) begin + if (rst == `RstEnable) LLbit = 1'b0; + else begin + if (wb_LLbit_we_i == 1'b1) LLbit = wb_LLbit_value_i; + else LLbit = LLbit_i; + end + end + + always @(*) begin + if (rst == `RstEnable) begin + wd_o = `NOPRegAddr; + wreg_o = `WriteDisable; + wdata_o = `ZeroWord; + mem_addr_o = `ZeroWord; + mem_we = `WriteDisable; + mem_sel_o = 4'b0000; + mem_data_o = `ZeroWord; + mem_ce_o = `ChipDisable; + LLbit_we_o = 1'b0; + LLbit_value_o = 1'b0; + inst_pc_o = `ZeroWord; + end else begin + wd_o = wd_i; + wreg_o = wreg_i; + wdata_o = wdata_i; + mem_addr_o = `ZeroWord; + mem_we = `WriteDisable; + mem_ce_o = `ChipDisable; + mem_sel_o = 4'b1111; + LLbit_we_o = 1'b0; + LLbit_value_o = 1'b0; + inst_pc_o = inst_pc_i; + case (aluop_i) + `EXE_LD_B_OP: begin + mem_addr_o = mem_addr_i; + mem_we = `WriteDisable; + mem_ce_o = `ChipEnable; + case (mem_addr_i[1:0]) + 2'b00: begin + wdata_o = {{24{mem_data_i[31]}}, mem_data_i[31:24]}; + mem_sel_o = 4'b1000; + end + 2'b01: begin + wdata_o = {{24{mem_data_i[23]}}, mem_data_i[23:16]}; + mem_sel_o = 4'b0100; + end + 2'b10: begin + wdata_o = {{24{mem_data_i[15]}}, mem_data_i[15:8]}; + mem_sel_o = 4'b0010; + end + 2'b11: begin + wdata_o = {{24{mem_data_i[7]}}, mem_data_i[7:0]}; + mem_sel_o = 4'b0001; + end + default: begin + wdata_o = `ZeroWord; + end + endcase + end + `EXE_LD_H_OP: begin + mem_addr_o = mem_addr_i; + mem_we = `WriteDisable; + mem_ce_o = `ChipEnable; + case (mem_addr_i[1:0]) + 2'b00: begin + wdata_o = {{16{mem_data_i[31]}}, mem_data_i[31:16]}; + mem_sel_o = 4'b1100; + end + + 2'b10: begin + wdata_o = {{16{mem_data_i[15]}}, mem_data_i[15:0]}; + mem_sel_o = 4'b0011; + end + + default: begin + wdata_o = `ZeroWord; + end + endcase + end + `EXE_LD_W_OP: begin + mem_addr_o = mem_addr_i; + mem_we = `WriteDisable; + mem_ce_o = `ChipEnable; + mem_sel_o = 4'b1111; + wdata_o = mem_data_i; + end + `EXE_LD_BU_OP: begin + mem_addr_o = mem_addr_i; + mem_we = `WriteDisable; + mem_ce_o = `ChipEnable; + case (mem_addr_i[1:0]) + 2'b00: begin + wdata_o = {{24{1'b0}}, mem_data_i[31:24]}; + mem_sel_o = 4'b1000; + end + 2'b01: begin + wdata_o = {{24{1'b0}}, mem_data_i[23:16]}; + mem_sel_o = 4'b0100; + end + 2'b10: begin + wdata_o = {{24{1'b0}}, mem_data_i[15:8]}; + mem_sel_o = 4'b0010; + end + 2'b11: begin + wdata_o = {{24{1'b0}}, mem_data_i[7:0]}; + mem_sel_o = 4'b0001; + end + default: begin + wdata_o = `ZeroWord; + end + endcase + end + `EXE_LD_HU_OP: begin + mem_addr_o = mem_addr_i; + mem_we = `WriteDisable; + mem_ce_o = `ChipEnable; + case (mem_addr_i[1:0]) + 2'b00: begin + wdata_o = {{16{1'b0}}, mem_data_i[31:16]}; + mem_sel_o = 4'b1100; + end + 2'b10: begin + wdata_o = {{16{1'b0}}, mem_data_i[15:0]}; + mem_sel_o = 4'b0011; + end + default: begin + wdata_o = `ZeroWord; + end + endcase + end + `EXE_ST_B_OP: begin + mem_addr_o = mem_addr_i; + mem_we = `WriteEnable; + mem_ce_o = `ChipEnable; + mem_data_o = {reg2_i[7:0], reg2_i[7:0], reg2_i[7:0], reg2_i[7:0]}; + case (mem_addr_i[1:0]) + 2'b00: begin + mem_sel_o = 4'b1000; + end + 2'b01: begin + mem_sel_o = 4'b0100; + end + 2'b10: begin + mem_sel_o = 4'b0010; + end + 2'b11: begin + mem_sel_o = 4'b0001; + end + default: begin + mem_sel_o = 4'b0000; + end + endcase + end + `EXE_ST_H_OP: begin + mem_addr_o = mem_addr_i; + mem_we = `WriteEnable; + mem_ce_o = `ChipEnable; + mem_data_o = {reg2_i[15:0], reg2_i[15:0]}; + case (mem_addr_i[1:0]) + 2'b00: begin + mem_sel_o = 4'b1100; + end + 2'b10: begin + mem_sel_o = 4'b0011; + end + default: begin + mem_sel_o = 4'b0000; + end + endcase + end + `EXE_ST_W_OP: begin mem_addr_o = mem_addr_i; mem_we = `WriteEnable; mem_ce_o = `ChipEnable; mem_data_o = reg2_i; mem_sel_o = 4'b1111; + end + `EXE_LL_OP: begin + mem_addr_o = mem_addr_i; + mem_we = `WriteDisable; + mem_ce_o = `ChipEnable; + mem_sel_o = 4'b1111; + wdata_o = mem_data_i; LLbit_we_o = 1'b1; - LLbit_value_o = 1'b0; - wdata_o = 32'b1; - end - else - begin - wdata_o = 32'b0; - end - end - default: - begin - - end - endcase + LLbit_value_o = 1'b1; + end + `EXE_SC_OP: begin + if (LLbit == 1'b1) begin + mem_addr_o = mem_addr_i; + mem_we = `WriteEnable; + mem_ce_o = `ChipEnable; + mem_data_o = reg2_i; + mem_sel_o = 4'b1111; + LLbit_we_o = 1'b1; + LLbit_value_o = 1'b0; + wdata_o = 32'b1; + end else begin + wdata_o = 32'b0; + end + end + default: begin + + end + endcase end end diff --git a/src/vsrc/pipeline/4_mem/mem_wb.v b/src/vsrc/pipeline/4_mem/mem_wb.v index 38bd68e..518c0ff 100644 --- a/src/vsrc/pipeline/4_mem/mem_wb.v +++ b/src/vsrc/pipeline/4_mem/mem_wb.v @@ -1,17 +1,17 @@ -`include "../../csr_defines.v" -`include "../../defines.v" +`include "csr_defines.v" +`include "defines.v" module mem_wb ( input wire clk, input wire rst, input wire stall, - input wire[`RegAddrBus] mem_wd, + input wire [`RegAddrBus] mem_wd, input wire mem_wreg, - input wire[`RegBus] mem_wdata, - input wire[`InstAddrBus] mem_inst_pc, - input wire[`InstBus] mem_instr, - input wire[`AluOpBus] mem_aluop, + input wire [`RegBus] mem_wdata, + input wire [`InstAddrBus] mem_inst_pc, + input wire [`InstBus] mem_instr, + input wire [`AluOpBus] mem_aluop, input wire mem_inst_valid, input wire mem_LLbit_we, @@ -22,146 +22,138 @@ module mem_wb ( input wire [15:0] excp_num, input wire mem_csr_we, - input wire[13:0] mem_csr_addr, - input wire[`RegBus] mem_csr_data, + input wire [13:0] mem_csr_addr, + input wire [`RegBus] mem_csr_data, - output reg[`RegAddrBus] wb_wd, + output reg [`RegAddrBus] wb_wd, output reg wb_wreg, - output reg[`RegBus] wb_wdata, + output reg [`RegBus] wb_wdata, output reg wb_csr_we, - output reg[13:0] wb_csr_addr, - output reg[`RegBus] wb_csr_data, + output reg [13:0] wb_csr_addr, + output reg [`RegBus] wb_csr_data, - output reg[`InstAddrBus] debug_commit_pc, + output reg [`InstAddrBus] debug_commit_pc, output reg debug_commit_valid, - output reg[`InstBus] debug_commit_instr, + output reg [`InstBus] debug_commit_instr, output reg wb_LLbit_we, output reg wb_LLbit_value, input wire excp_i, - input wire[15:0] excp_num_i, + input wire [15:0] excp_num_i, output reg excp_o, - output reg[15:0] excp_num_o, + output reg [15:0] excp_num_o, //to csr - output wire[31:0] csr_era, - output wire[8:0] csr_esubcode, - output wire[5:0] csr_ecode, + output wire [31:0] csr_era, + output wire [8:0] csr_esubcode, + output wire [5:0] csr_ecode, output wire excp_flush, output wire ertn_flush, output wire va_error, - output wire[31:0] bad_va, + output wire [31:0] bad_va, output wire excp_tlbrefill, output wire excp_tlb, - output wire[18:0] excp_tlb_vppn - ); + output wire [18:0] excp_tlb_vppn +); - reg debug_commit_valid_0; - reg debug_commit_valid_1; - reg [`InstBus] debug_commit_pc_0; + reg debug_commit_valid_0; + reg debug_commit_valid_1; + reg [`InstBus] debug_commit_pc_0; - reg wb_valid; + reg wb_valid; - assign csr_era = mem_inst_pc; - assign excp_flush = excp_i; - assign ertn_flush = mem_instr == `EXE_ERTN_OP; + assign csr_era = mem_inst_pc; + assign excp_flush = excp_i; + assign ertn_flush = mem_instr == `EXE_ERTN_OP; - assign csr_ecode = excp_num[0] ? `ECODE_INT : excp_num[1] ? `ECODE_ADEF : excp_num[2] ? `ECODE_TLBR : excp_num[3] ? `ECODE_PIF : + assign csr_ecode = excp_num[0] ? `ECODE_INT : excp_num[1] ? `ECODE_ADEF : excp_num[2] ? `ECODE_TLBR : excp_num[3] ? `ECODE_PIF : excp_num[4] ? `ECODE_PPI : excp_num[5] ? `ECODE_SYS :excp_num[6] ? `ECODE_BRK : excp_num[7] ? `ECODE_INE : excp_num[8] ? `ECODE_IPE :excp_num[9] ? `ECODE_ALE : excp_num[10] ? `ECODE_ADEM : excp_num[11] ? `ECODE_TLBR : excp_num[12] ? `ECODE_PME :excp_num[13] ? `ECODE_PPI : excp_num[14] ? `ECODE_PIS :excp_num[15] ? `ECODE_PIL : 6'b0 ; - assign va_error = excp_num[0] ? 1'b0 : excp_num[1] ? wb_valid : excp_num[2] ? wb_valid : excp_num[3] ? wb_valid : + assign va_error = excp_num[0] ? 1'b0 : excp_num[1] ? wb_valid : excp_num[2] ? wb_valid : excp_num[3] ? wb_valid : excp_num[4] ? wb_valid : excp_num[5] ? 1'b0 :excp_num[6] ? 1'b0 : excp_num[7] ? 1'b0 : excp_num[8] ? 1'b0 :excp_num[9] ? wb_valid : excp_num[10] ? wb_valid : excp_num[11] ? wb_valid : excp_num[12] ? wb_valid :excp_num[13] ? wb_valid : excp_num[14] ? wb_valid :excp_num[15] ? wb_valid : 1'b0 ; - assign bad_va = excp_num[0] ? 32'b0 : excp_num[1] ? mem_inst_pc : excp_num[2] ? mem_inst_pc : excp_num[3] ? mem_inst_pc : + assign bad_va = excp_num[0] ? 32'b0 : excp_num[1] ? mem_inst_pc : excp_num[2] ? mem_inst_pc : excp_num[3] ? mem_inst_pc : excp_num[4] ? mem_inst_pc : excp_num[5] ? 32'b0 :excp_num[6] ? 32'b0 : excp_num[7] ? 32'b0 : excp_num[8] ? 32'b0 :excp_num[9] ? wb_wdata : excp_num[10] ? wb_wdata : excp_num[11] ? wb_wdata : excp_num[12] ? wb_wdata :excp_num[13] ? wb_wdata : excp_num[14] ? wb_wdata :excp_num[15] ? wb_wdata : 32'b0 ; - assign csr_esubcode = excp_num[0] ? 9'b0 : excp_num[1] ? `ESUBCODE_ADEF : excp_num[2] ? 9'b0 : excp_num[3] ? 9'b0 : + assign csr_esubcode = excp_num[0] ? 9'b0 : excp_num[1] ? `ESUBCODE_ADEF : excp_num[2] ? 9'b0 : excp_num[3] ? 9'b0 : excp_num[4] ? 9'b0 : excp_num[5] ? 9'b0 :excp_num[6] ? 9'b0 : excp_num[7] ? 9'b0 : excp_num[8] ? 9'b0 :excp_num[9] ? 9'b0 : excp_num[10] ? `ESUBCODE_ADEM : excp_num[11] ? 9'b0 : excp_num[12] ? 9'b0 :excp_num[13] ? 9'b0 : excp_num[14] ? 9'b0 :excp_num[15] ? 9'b0 : 9'b0 ; - assign csr_esubcode = excp_num[0] ? 1'b0 : excp_num[1] ? 1'b0 : excp_num[2] ? wb_valid : excp_num[3] ? 1'b0 : + assign csr_esubcode = excp_num[0] ? 1'b0 : excp_num[1] ? 1'b0 : excp_num[2] ? wb_valid : excp_num[3] ? 1'b0 : excp_num[4] ? 1'b0 : excp_num[5] ? 1'b0 :excp_num[6] ? 1'b0 : excp_num[7] ? 1'b0 : excp_num[8] ? 1'b0 :excp_num[9] ? 1'b0 : excp_num[10] ? 1'b0 : excp_num[11] ? wb_valid : excp_num[12] ? 1'b0 :excp_num[13] ? 1'b0 : excp_num[14] ? 1'b0 :excp_num[15] ? 1'b0 : 1'b0 ; - - assign excp_tlb = excp_num[0] ? 1'b0 : excp_num[1] ? 1'b0 : excp_num[2] ? wb_valid : excp_num[3] ? wb_valid : + + assign excp_tlb = excp_num[0] ? 1'b0 : excp_num[1] ? 1'b0 : excp_num[2] ? wb_valid : excp_num[3] ? wb_valid : excp_num[4] ? wb_valid : excp_num[5] ? 1'b0 :excp_num[6] ? 1'b0 : excp_num[7] ? 1'b0 : excp_num[8] ? 1'b0 :excp_num[9] ? 1'b0 : excp_num[10] ? 1'b0 : excp_num[11] ? wb_valid : excp_num[12] ? wb_valid :excp_num[13] ? wb_valid : excp_num[14] ? wb_valid :excp_num[15] ? wb_valid : 1'b0 ; - - assign excp_tlb_vppn = excp_num[0] ? 19'b0 : excp_num[1] ? 19'b0 : excp_num[2] ? mem_inst_pc[31:13] : excp_num[3] ? mem_inst_pc[31:13] : + + assign excp_tlb_vppn = excp_num[0] ? 19'b0 : excp_num[1] ? 19'b0 : excp_num[2] ? mem_inst_pc[31:13] : excp_num[3] ? mem_inst_pc[31:13] : excp_num[4] ? mem_inst_pc[31:13] : excp_num[5] ? 19'b0 :excp_num[6] ? 19'b0 : excp_num[7] ? 19'b0 : excp_num[8] ? 19'b0 :excp_num[9] ? 19'b0 : excp_num[10] ? 19'b0 : excp_num[11] ? wb_wdata[31:13] : excp_num[12] ? wb_wdata[31:13] :excp_num[13] ? wb_wdata[31:13] : excp_num[14] ? wb_wdata[31:13] :excp_num[15] ? wb_wdata[31:13] : 1'b0 ; - always @ (posedge clk) - begin - if (rst == `RstEnable) - begin - wb_wd <= `NOPRegAddr; - wb_wreg <= `WriteDisable; - wb_wdata <= `ZeroWord; - wb_valid <= 1'b0; - wb_LLbit_we <= 1'b0; - wb_LLbit_value <= 1'b0; - wb_csr_we <= 1'b0; - wb_csr_addr <= 14'b0; - wb_csr_data <= `ZeroWord; - debug_commit_instr <= `ZeroWord; - debug_commit_pc <= `ZeroWord; - debug_commit_valid <= `InstInvalid; - end - else if(flush == 1'b1 || excp_i == 1'b1 || mem_instr == `EXE_ERTN_OP) - begin - wb_wd <= `NOPRegAddr; - wb_wreg <= `WriteDisable; - wb_wdata <= `ZeroWord; - wb_valid <= 1'b0; - wb_LLbit_we <= 1'b0; - wb_LLbit_value <= 1'b0; - wb_csr_we <= 1'b0; - wb_csr_addr <= 14'b0; - wb_csr_data <= `ZeroWord; - debug_commit_instr <= `ZeroWord; - debug_commit_pc <= `ZeroWord; - debug_commit_valid <= `InstInvalid; - end - else if(stall == `Stop) - begin - debug_commit_pc <= `ZeroWord; - debug_commit_instr <= `ZeroWord; - debug_commit_valid <= ~`InstInvalid; - end - else - begin - wb_wd <= mem_wd; - wb_wreg <= mem_wreg; - wb_wdata <= mem_wdata; - wb_valid <= 1'b1; - wb_LLbit_we <= mem_LLbit_we; - wb_LLbit_value <= mem_LLbit_value; - wb_csr_we <= mem_csr_we; - wb_csr_addr <= mem_csr_addr; - wb_csr_data <= mem_csr_data; - debug_commit_pc <= mem_inst_pc; - // debug_commit_pc <= debug_commit_pc_0; - debug_commit_valid <= ~mem_inst_valid; - // debug_commit_valid_1 <= debug_commit_valid_0; - // debug_commit_valid <= ~debug_commit_valid_1; - debug_commit_instr <= mem_instr; + always @(posedge clk) begin + if (rst == `RstEnable) begin + wb_wd <= `NOPRegAddr; + wb_wreg <= `WriteDisable; + wb_wdata <= `ZeroWord; + wb_valid <= 1'b0; + wb_LLbit_we <= 1'b0; + wb_LLbit_value <= 1'b0; + wb_csr_we <= 1'b0; + wb_csr_addr <= 14'b0; + wb_csr_data <= `ZeroWord; + debug_commit_instr <= `ZeroWord; + debug_commit_pc <= `ZeroWord; + debug_commit_valid <= `InstInvalid; + end else if (flush == 1'b1 || excp_i == 1'b1 || mem_instr == `EXE_ERTN_OP) begin + wb_wd <= `NOPRegAddr; + wb_wreg <= `WriteDisable; + wb_wdata <= `ZeroWord; + wb_valid <= 1'b0; + wb_LLbit_we <= 1'b0; + wb_LLbit_value <= 1'b0; + wb_csr_we <= 1'b0; + wb_csr_addr <= 14'b0; + wb_csr_data <= `ZeroWord; + debug_commit_instr <= `ZeroWord; + debug_commit_pc <= `ZeroWord; + debug_commit_valid <= `InstInvalid; + end else if (stall == `Stop) begin + debug_commit_pc <= `ZeroWord; + debug_commit_instr <= `ZeroWord; + debug_commit_valid <= ~`InstInvalid; + end else begin + wb_wd <= mem_wd; + wb_wreg <= mem_wreg; + wb_wdata <= mem_wdata; + wb_valid <= 1'b1; + wb_LLbit_we <= mem_LLbit_we; + wb_LLbit_value <= mem_LLbit_value; + wb_csr_we <= mem_csr_we; + wb_csr_addr <= mem_csr_addr; + wb_csr_data <= mem_csr_data; + debug_commit_pc <= mem_inst_pc; + // debug_commit_pc <= debug_commit_pc_0; + debug_commit_valid <= ~mem_inst_valid; + // debug_commit_valid_1 <= debug_commit_valid_0; + // debug_commit_valid <= ~debug_commit_valid_1; + debug_commit_instr <= mem_instr; end end - endmodule +endmodule From 260a0c6eb7cdd5c86233c25a97d7d269e1a1fc99 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Mon, 2 May 2022 20:09:19 +0800 Subject: [PATCH 046/114] feat: add difftest reg & csr --- src/vsrc/cpu_top.v | 123 ++++++++++++++++++++++++---- src/vsrc/regfile.v | 195 +++++++++++++++++++-------------------------- 2 files changed, 191 insertions(+), 127 deletions(-) diff --git a/src/vsrc/cpu_top.v b/src/vsrc/cpu_top.v index bc9d8b4..9394eb1 100644 --- a/src/vsrc/cpu_top.v +++ b/src/vsrc/cpu_top.v @@ -1215,9 +1215,9 @@ module cpu_top ( wire [13:0] wb_csr_addr_1; wire [`RegBus] wb_csr_data_1; - assign debug_commit_wreg_1 = wb_wreg_1; - assign debug_commit_reg_waddr_1 = wb_reg_waddr_1; - assign debug_commit_reg_wdata_1 = wb_reg_wdata_1; + assign debug0_wb_rf_wen = wb_wreg_1; + assign debug0_wb_rf_wnum = wb_reg_waddr_1; + assign debug0_wb_rf_wdata = wb_reg_wdata_1; wire wb_excp_o_1; @@ -1374,19 +1374,18 @@ module cpu_top ( .waddr_2(wb_reg_waddr_2), .wdata_2(wb_reg_wdata_2), - .re1_1 (reg1_read_1), - .raddr1_1 (reg1_addr_1), - .rdata1_1 (reg1_data_1), - .re2_1 (reg2_read_1), - .raddr2_1 (reg2_addr_1), - .rdata2_1 (reg2_data_1), - .re1_2 (reg1_read_2), - .raddr1_2 (reg1_addr_2), - .rdata1_2 (reg1_data_2), - .re2_2 (reg2_read_2), - .raddr2_2 (reg2_addr_2), - .rdata2_2 (reg2_data_2), - .debug_reg(debug_reg) + .re1_1 (reg1_read_1), + .raddr1_1(reg1_addr_1), + .rdata1_1(reg1_data_1), + .re2_1 (reg2_read_1), + .raddr2_1(reg2_addr_1), + .rdata2_1(reg2_data_1), + .re1_2 (reg1_read_2), + .raddr1_2(reg1_addr_2), + .rdata1_2(reg1_data_2), + .re2_2 (reg2_read_2), + .raddr2_2(reg2_addr_2), + .rdata2_2(reg2_data_2) ); ctrl u_ctrl ( @@ -1544,5 +1543,97 @@ module cpu_top ( .csr_pg (csr_pg) ); + // Difftest DPI-C +`ifdef SIMU // SIMU is defined in chiplab run_func/Makefile + DifftestInstrCommit difftest_instr_commit_0 ( // TODO: not finished yet, blank signal is needed + .clock (aclk), + .coreid (0), // Only one core, so always 0 + .index (0), // Commit channel index + .valid (debug_commit_valid_1), + .pc (debug_commit_pc_1), + .instr (debug_commit_instr_1), + .skip (0), // Not sure meaning, but keep 0 for now + .is_TLBFILL (), + .TLBFILL_index (), + .is_CNTinst (), + .timer_64_value(), + .wen (debug0_wb_rf_wen), + .wdest ({3'b0, debug0_wb_rf_wnum}), + .wdata (debug0_wb_rf_wdata), + .csr_rstat (), + .csr_data () + ); + + DifftestCSRRegState DifftestCSRRegState ( + .clock (aclk), + .coreid (0), // Only one core, so always 0 + .crmd (u_cs_reg.csr_crmd), + .prmd (u_cs_reg.csr_prmd), + .euen (0), // TODO: Not sure meaning + .ecfg (u_cs_reg.csr_ectl), // ectl + .estat (u_cs_reg.csr_estat), + .era (u_cs_reg.csr_era), + .badv (u_cs_reg.csr_badv), + .eentry (u_cs_reg.csr_eentry), + .tlbrentry(u_cs_reg.csr_tlbrentry), + .tlbidx (u_cs_reg.csr_tlbidx), + .tlbehi (u_cs_reg.csr_tlbehi), + .tlbelo0 (u_cs_reg.csr_tlbelo0), + .tlbelo1 (u_cs_reg.csr_tlbelo1), + .asid (u_cs_reg.csr_asid), + .pgdl (u_cs_reg.csr_pgdl), + .pgdh (u_cs_reg.csr_pgdh), + .save0 (u_cs_reg.csr_save0), + .save1 (u_cs_reg.csr_save1), + .save2 (u_cs_reg.csr_save2), + .save3 (u_cs_reg.csr_save3), + .tid (u_cs_reg.csr_tid), + .tcfg (u_cs_reg.csr_tcfg), + .tval (u_cs_reg.csr_tval), + .ticlr (u_cs_reg.csr_ticlr), + .llbctl (u_cs_reg.csr_llbctl), + .dmw0 (u_cs_reg.csr_dmw0), + .dmw1 (u_cs_reg.csr_dmw1) + ); + + + DifftestGRegState difftest_gpr_state ( + .clock (aclk), + .coreid(0), + .gpr_0 (0), + .gpr_1 (u_regfile.regs[1]), + .gpr_2 (u_regfile.regs[2]), + .gpr_3 (u_regfile.regs[3]), + .gpr_4 (u_regfile.regs[4]), + .gpr_5 (u_regfile.regs[5]), + .gpr_6 (u_regfile.regs[6]), + .gpr_7 (u_regfile.regs[7]), + .gpr_8 (u_regfile.regs[8]), + .gpr_9 (u_regfile.regs[9]), + .gpr_10(u_regfile.regs[10]), + .gpr_11(u_regfile.regs[11]), + .gpr_12(u_regfile.regs[12]), + .gpr_13(u_regfile.regs[13]), + .gpr_14(u_regfile.regs[14]), + .gpr_15(u_regfile.regs[15]), + .gpr_16(u_regfile.regs[16]), + .gpr_17(u_regfile.regs[17]), + .gpr_18(u_regfile.regs[18]), + .gpr_19(u_regfile.regs[19]), + .gpr_20(u_regfile.regs[20]), + .gpr_21(u_regfile.regs[21]), + .gpr_22(u_regfile.regs[22]), + .gpr_23(u_regfile.regs[23]), + .gpr_24(u_regfile.regs[24]), + .gpr_25(u_regfile.regs[25]), + .gpr_26(u_regfile.regs[26]), + .gpr_27(u_regfile.regs[27]), + .gpr_28(u_regfile.regs[28]), + .gpr_29(u_regfile.regs[29]), + .gpr_30(u_regfile.regs[30]), + .gpr_31(u_regfile.regs[31]) + ); +`endif + endmodule diff --git a/src/vsrc/regfile.v b/src/vsrc/regfile.v index 7408204..b566756 100644 --- a/src/vsrc/regfile.v +++ b/src/vsrc/regfile.v @@ -3,11 +3,11 @@ module regfile ( input wire clk, input wire rst, - input wire[`InstAddrBus] pc_i_1, + input wire [`InstAddrBus] pc_i_1, input wire we_1, input wire [`RegAddrBus] waddr_1, input wire [`RegBus] wdata_1, - input wire[`InstAddrBus] pc_i_2, + input wire [`InstAddrBus] pc_i_2, input wire we_2, input wire [`RegAddrBus] waddr_2, input wire [`RegBus] wdata_2, @@ -24,127 +24,100 @@ module regfile ( output reg [`RegBus] rdata2_1, input wire re2_2, input wire [`RegAddrBus] raddr2_2, - output reg [`RegBus] rdata2_2, - - output wire[1023:0] debug_reg + output reg [`RegBus] rdata2_2 ); - -reg[`RegBus] regs[0:`RegNum-1]; -assign debug_reg = {regs[31],regs[30],regs[29],regs[28],regs[27],regs[26],regs[25],regs[24],regs[23],regs[22],regs[21],regs[20],regs[19],regs[18],regs[17],regs[16],regs[15],regs[14],regs[13],regs[12],regs[11],regs[10],regs[9],regs[8],regs[7],regs[6],regs[5],regs[4],regs[3],regs[2],regs[1],regs[0]}; + reg [`RegBus] regs[0:`RegNum-1]; -always @ (posedge clk)begin - if (rst == `RstEnable)begin - regs[31] <= `ZeroWord; - regs[30] <= `ZeroWord; - regs[29] <= `ZeroWord; - regs[28] <= `ZeroWord; - regs[27] <= `ZeroWord; - regs[26] <= `ZeroWord; - regs[25] <= `ZeroWord; - regs[24] <= `ZeroWord; - regs[23] <= `ZeroWord; - regs[22] <= `ZeroWord; - regs[21] <= `ZeroWord; - regs[20] <= `ZeroWord; - regs[19] <= `ZeroWord; - regs[18] <= `ZeroWord; - regs[17] <= `ZeroWord; - regs[16] <= `ZeroWord; - regs[15] <= `ZeroWord; - regs[14] <= `ZeroWord; - regs[13] <= `ZeroWord; - regs[12] <= `ZeroWord; - regs[11] <= `ZeroWord; - regs[10] <= `ZeroWord; - regs[9] <= `ZeroWord; - regs[8] <= `ZeroWord; - regs[7] <= `ZeroWord; - regs[6] <= `ZeroWord; - regs[5] <= `ZeroWord; - regs[4] <= `ZeroWord; - regs[3] <= `ZeroWord; - regs[2] <= `ZeroWord; - regs[1] <= `ZeroWord; - regs[0] <= `ZeroWord; - end else begin //同时写入一个位置,将后面的写入 - if ((we_1 == `WriteEnable) && (we_2 == `WriteEnable) && waddr_1 == waddr_2)begin - if(pc_i_1 > pc_i_2) - regs[waddr_1] <= wdata_1; - else - regs[waddr_1] <= wdata_2; - end - else begin - if ((we_1 == `WriteEnable) && !(waddr_1 == `RegNumLog2'h0)) - regs[waddr_1] <= wdata_1; - if ((we_2 == `WriteEnable) && !(waddr_2 == `RegNumLog2'h0)) - regs[waddr_2] <= wdata_2; + always @(posedge clk) begin + if (rst == `RstEnable) begin + regs[31] <= `ZeroWord; + regs[30] <= `ZeroWord; + regs[29] <= `ZeroWord; + regs[28] <= `ZeroWord; + regs[27] <= `ZeroWord; + regs[26] <= `ZeroWord; + regs[25] <= `ZeroWord; + regs[24] <= `ZeroWord; + regs[23] <= `ZeroWord; + regs[22] <= `ZeroWord; + regs[21] <= `ZeroWord; + regs[20] <= `ZeroWord; + regs[19] <= `ZeroWord; + regs[18] <= `ZeroWord; + regs[17] <= `ZeroWord; + regs[16] <= `ZeroWord; + regs[15] <= `ZeroWord; + regs[14] <= `ZeroWord; + regs[13] <= `ZeroWord; + regs[12] <= `ZeroWord; + regs[11] <= `ZeroWord; + regs[10] <= `ZeroWord; + regs[9] <= `ZeroWord; + regs[8] <= `ZeroWord; + regs[7] <= `ZeroWord; + regs[6] <= `ZeroWord; + regs[5] <= `ZeroWord; + regs[4] <= `ZeroWord; + regs[3] <= `ZeroWord; + regs[2] <= `ZeroWord; + regs[1] <= `ZeroWord; + regs[0] <= `ZeroWord; + end else begin //同时写入一个位置,将后面的写入 + if ((we_1 == `WriteEnable) && (we_2 == `WriteEnable) && waddr_1 == waddr_2) begin + if (pc_i_1 > pc_i_2) regs[waddr_1] <= wdata_1; + else regs[waddr_1] <= wdata_2; + end else begin + if ((we_1 == `WriteEnable) && !(waddr_1 == `RegNumLog2'h0)) + regs[waddr_1] <= wdata_1; + if ((we_2 == `WriteEnable) && !(waddr_2 == `RegNumLog2'h0)) + regs[waddr_2] <= wdata_2; + end end end -end - always @ (*) - begin - if (rst == `RstEnable) - rdata1_1 = `ZeroWord; - else if (raddr1_1 == `RegNumLog2'h0) - rdata1_1 = `ZeroWord; - else if ((raddr1_1 == waddr_1) && (we_1 == `WriteEnable) && (re1_1 == `ReadEnable)) - rdata1_1 = wdata_1; - else if ((raddr1_1 == waddr_2) && (we_2 == `WriteEnable) && (re1_1 == `ReadEnable)) - rdata1_1 = wdata_2; - else if (re1_1 == `ReadEnable) - rdata1_1 = regs[raddr1_1]; - else - rdata1_1 = `ZeroWord; + always @(*) begin + if (rst == `RstEnable) rdata1_1 = `ZeroWord; + else if (raddr1_1 == `RegNumLog2'h0) rdata1_1 = `ZeroWord; + else if ((raddr1_1 == waddr_1) && (we_1 == `WriteEnable) && (re1_1 == `ReadEnable)) + rdata1_1 = wdata_1; + else if ((raddr1_1 == waddr_2) && (we_2 == `WriteEnable) && (re1_1 == `ReadEnable)) + rdata1_1 = wdata_2; + else if (re1_1 == `ReadEnable) rdata1_1 = regs[raddr1_1]; + else rdata1_1 = `ZeroWord; end - always @ (*) - begin - if (rst == `RstEnable) - rdata1_2 = `ZeroWord; - else if (raddr1_2 == `RegNumLog2'h0) - rdata1_2 = `ZeroWord; - else if ((raddr1_2 == waddr_1) && (we_1 == `WriteEnable) && (re1_2 == `ReadEnable)) - rdata1_2 = wdata_1; - else if ((raddr1_2 == waddr_2) && (we_2 == `WriteEnable) && (re1_2 == `ReadEnable)) - rdata1_2 = wdata_2; - else if (re1_2 == `ReadEnable) - rdata1_2 = regs[raddr1_2]; - else - rdata1_2= `ZeroWord; + always @(*) begin + if (rst == `RstEnable) rdata1_2 = `ZeroWord; + else if (raddr1_2 == `RegNumLog2'h0) rdata1_2 = `ZeroWord; + else if ((raddr1_2 == waddr_1) && (we_1 == `WriteEnable) && (re1_2 == `ReadEnable)) + rdata1_2 = wdata_1; + else if ((raddr1_2 == waddr_2) && (we_2 == `WriteEnable) && (re1_2 == `ReadEnable)) + rdata1_2 = wdata_2; + else if (re1_2 == `ReadEnable) rdata1_2 = regs[raddr1_2]; + else rdata1_2 = `ZeroWord; end - always @ (*) - begin - if (rst == `RstEnable) - rdata2_1 = `ZeroWord; - else if (raddr2_1 == `RegNumLog2'h0) - rdata2_1 = `ZeroWord; - else if ((raddr2_1 == waddr_1) && (we_1 == `WriteEnable) && (re2_1 == `ReadEnable)) - rdata2_1 = wdata_1; - else if ((raddr2_1 == waddr_2) && (we_2 == `WriteEnable) && (re2_1 == `ReadEnable)) - rdata2_1 = wdata_2; - else if (re2_1 == `ReadEnable) - rdata2_1 = regs[raddr2_1]; - else - rdata2_1 = `ZeroWord; + always @(*) begin + if (rst == `RstEnable) rdata2_1 = `ZeroWord; + else if (raddr2_1 == `RegNumLog2'h0) rdata2_1 = `ZeroWord; + else if ((raddr2_1 == waddr_1) && (we_1 == `WriteEnable) && (re2_1 == `ReadEnable)) + rdata2_1 = wdata_1; + else if ((raddr2_1 == waddr_2) && (we_2 == `WriteEnable) && (re2_1 == `ReadEnable)) + rdata2_1 = wdata_2; + else if (re2_1 == `ReadEnable) rdata2_1 = regs[raddr2_1]; + else rdata2_1 = `ZeroWord; end - always @ (*) - begin - if (rst == `RstEnable) - rdata2_2 = `ZeroWord; - else if (raddr2_2 == `RegNumLog2'h0) - rdata2_2 = `ZeroWord; - else if ((raddr2_2 == waddr_1) && (we_1 == `WriteEnable) && (re2_2 == `ReadEnable)) - rdata2_2 = wdata_1; - else if ((raddr2_2 == waddr_2) && (we_2 == `WriteEnable) && (re2_2 == `ReadEnable)) - rdata2_2 = wdata_2; - else if (re2_1 == `ReadEnable) - rdata2_2 = regs[raddr2_2]; - else - rdata2_2 = `ZeroWord; + always @(*) begin + if (rst == `RstEnable) rdata2_2 = `ZeroWord; + else if (raddr2_2 == `RegNumLog2'h0) rdata2_2 = `ZeroWord; + else if ((raddr2_2 == waddr_1) && (we_1 == `WriteEnable) && (re2_2 == `ReadEnable)) + rdata2_2 = wdata_1; + else if ((raddr2_2 == waddr_2) && (we_2 == `WriteEnable) && (re2_2 == `ReadEnable)) + rdata2_2 = wdata_2; + else if (re2_1 == `ReadEnable) rdata2_2 = regs[raddr2_2]; + else rdata2_2 = `ZeroWord; end endmodule From 68a2507facb725fa40ef6ab70f697dbc3b83486e Mon Sep 17 00:00:00 2001 From: Easton Man Date: Mon, 2 May 2022 23:26:09 +0800 Subject: [PATCH 047/114] refactor: simplify rst --- src/vsrc/cpu_top.v | 2 +- src/vsrc/regfile.v | 35 +++-------------------------------- 2 files changed, 4 insertions(+), 33 deletions(-) diff --git a/src/vsrc/cpu_top.v b/src/vsrc/cpu_top.v index 9394eb1..def1354 100644 --- a/src/vsrc/cpu_top.v +++ b/src/vsrc/cpu_top.v @@ -1549,7 +1549,7 @@ module cpu_top ( .clock (aclk), .coreid (0), // Only one core, so always 0 .index (0), // Commit channel index - .valid (debug_commit_valid_1), + .valid (~debug_commit_valid_1), // TODO: flip valid definition in CPU .pc (debug_commit_pc_1), .instr (debug_commit_instr_1), .skip (0), // Not sure meaning, but keep 0 for now diff --git a/src/vsrc/regfile.v b/src/vsrc/regfile.v index b566756..5e1a43f 100644 --- a/src/vsrc/regfile.v +++ b/src/vsrc/regfile.v @@ -31,38 +31,9 @@ module regfile ( always @(posedge clk) begin if (rst == `RstEnable) begin - regs[31] <= `ZeroWord; - regs[30] <= `ZeroWord; - regs[29] <= `ZeroWord; - regs[28] <= `ZeroWord; - regs[27] <= `ZeroWord; - regs[26] <= `ZeroWord; - regs[25] <= `ZeroWord; - regs[24] <= `ZeroWord; - regs[23] <= `ZeroWord; - regs[22] <= `ZeroWord; - regs[21] <= `ZeroWord; - regs[20] <= `ZeroWord; - regs[19] <= `ZeroWord; - regs[18] <= `ZeroWord; - regs[17] <= `ZeroWord; - regs[16] <= `ZeroWord; - regs[15] <= `ZeroWord; - regs[14] <= `ZeroWord; - regs[13] <= `ZeroWord; - regs[12] <= `ZeroWord; - regs[11] <= `ZeroWord; - regs[10] <= `ZeroWord; - regs[9] <= `ZeroWord; - regs[8] <= `ZeroWord; - regs[7] <= `ZeroWord; - regs[6] <= `ZeroWord; - regs[5] <= `ZeroWord; - regs[4] <= `ZeroWord; - regs[3] <= `ZeroWord; - regs[2] <= `ZeroWord; - regs[1] <= `ZeroWord; - regs[0] <= `ZeroWord; + for (integer i = 0; i < 32; i = i + 1) begin + regs[i] <= 0; + end end else begin //同时写入一个位置,将后面的写入 if ((we_1 == `WriteEnable) && (we_2 == `WriteEnable) && waddr_1 == waddr_2) begin if (pc_i_1 > pc_i_2) regs[waddr_1] <= wdata_1; From 80fb57d3623c75126fd84fe88240252bd6805cf4 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Tue, 3 May 2022 12:33:20 +0800 Subject: [PATCH 048/114] feat: add vscode txe rec & config --- .gitignore | 4 +++- .vscode/extensions.json | 12 ++++++++++++ .vscode/settings.json | 20 ++++++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 .vscode/extensions.json create mode 100644 .vscode/settings.json diff --git a/.gitignore b/.gitignore index 9021cef..c3c6d00 100644 --- a/.gitignore +++ b/.gitignore @@ -10,7 +10,9 @@ vivado* # VSCode configuration files -.vscode/ +.vscode/* +!.vscode/extensions.json +!.vscode/settings.json # Verilator output files obj_dir/ diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..02e52dc --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,12 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations. + // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp + // List of extensions which should be recommended for users of this workspace. + "recommendations": [ + "bmpenuelas.systemverilog-formatter-vscode", + "Gruntfuggly.todo-tree", + "mshr-h.veriloghdl" + ], + // List of extensions recommended by VS Code that should not be recommended for users of this workspace. + "unwantedRecommendations": [] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..f2c0753 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,20 @@ +{ + "verilog.linting.linter": "verilator", + "verilog.linting.iverilog.arguments": "", + "verilog.logging.enabled": true, + "verilog.linting.verilator.arguments": "-Isrc -Isrc/vsrc -Isrc/vsrc/pipeline/1_fetch", + "todo-tree.filtering.includeGlobs": [ + "**/*.sv", + "**/*.v" + ], + "todo-tree.regex.regex": "((\\s|^)($TAGS):)", + "todo-tree.regex.enableMultiLine": false, + "todo-tree.regex.regexCaseSensitive": true, + "todo-tree.general.debug": false, + "todo-tree.general.enableFileWatcher": true, + "todo-tree.filtering.includeHiddenFiles": true, + "todo-tree.filtering.includedWorkspaces": [ + "**/*" + ], + "todo-tree.filtering.useBuiltInExcludes": "file and search excludes" +} \ No newline at end of file From 8f63f8c2757a254035331905a8926fc56dfcd22c Mon Sep 17 00:00:00 2001 From: Easton Man Date: Tue, 3 May 2022 12:35:17 +0800 Subject: [PATCH 049/114] feat: add more rec --- .vscode/extensions.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 02e52dc..def9de5 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -5,7 +5,8 @@ "recommendations": [ "bmpenuelas.systemverilog-formatter-vscode", "Gruntfuggly.todo-tree", - "mshr-h.veriloghdl" + "mshr-h.veriloghdl", + "mhutchie.git-graph" ], // List of extensions recommended by VS Code that should not be recommended for users of this workspace. "unwantedRecommendations": [] From 50217a37594bd7d9c2d1569d3e2205b66e4c34eb Mon Sep 17 00:00:00 2001 From: Easton Man Date: Wed, 4 May 2022 13:28:26 +0800 Subject: [PATCH 050/114] feat(UNTESTED): implement dummy icache --- .vscode/settings.json | 4 +- src/vsrc/cpu_top.v | 31 ++++++++- src/vsrc/dummy_icache.sv | 146 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 177 insertions(+), 4 deletions(-) create mode 100644 src/vsrc/dummy_icache.sv diff --git a/.vscode/settings.json b/.vscode/settings.json index f2c0753..8f6f9d4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -16,5 +16,7 @@ "todo-tree.filtering.includedWorkspaces": [ "**/*" ], - "todo-tree.filtering.useBuiltInExcludes": "file and search excludes" + "todo-tree.filtering.useBuiltInExcludes": "file and search excludes", + "systemverilogFormatter.veribleBuild": "Ubuntu-20.04-focal-x86_64", + "systemverilogFormatter.commandLineArguments": "--indentation_spaces 4" } \ No newline at end of file diff --git a/src/vsrc/cpu_top.v b/src/vsrc/cpu_top.v index def1354..9c2ac6c 100644 --- a/src/vsrc/cpu_top.v +++ b/src/vsrc/cpu_top.v @@ -87,19 +87,44 @@ module cpu_top ( wire Instram_branch_flag; assign Instram_branch_flag = branch_flag_1 | branch_flag_2; + wire axi_busy; + wire [`RegBus] axi_data; + wire [`RegBus] axi_addr; + + dummy_icache #( + .ADDR_WIDTH(`RegWidth), + .DATA_WIDTH(`RegWidth) + ) u_dummy_icache ( + .clk (clk), + .rst (rst), + .raddr_1_i (pc_buffer_1), + .raddr_2_i (pc_buffer_2), + .stallreq_o(stallreq_from_id_1), + .rvalid_1_o(), + .rvalid_2_o(), + .raddr_1_o (), + .raddr_2_o (), + .rdata_1_o (), + .rdata_2_o (), + .axi_addr_o(axi_addr), + .axi_data_i(axi_data), + .axi_busy_i(axi_busy) + ); + + axi_master u_axi_master ( .aclk (aclk), .aresetn(aresetn), - .cpu_addr_i(pc_buffer_1), + .cpu_addr_i(axi_addr), .cpu_ce_i(chip_enable), .cpu_data_i(0), .cpu_we_i(1'b0), .cpu_sel_i(4'b1111), .stall_i(Instram_branch_flag), .flush_i(Instram_branch_flag), - .cpu_data_o(), - .stallreq(stallreq_from_id_1), + .cpu_data_o(axi_data), + .stallreq(axi_busy), .id(4'b0000), // Read Instruction only, TODO: move this from AXI to cache .s_arid(arid), .s_araddr(araddr), diff --git a/src/vsrc/dummy_icache.sv b/src/vsrc/dummy_icache.sv new file mode 100644 index 0000000..33d675c --- /dev/null +++ b/src/vsrc/dummy_icache.sv @@ -0,0 +1,146 @@ +`include "defines.v" + +/* dummy_icache +* hold output until AXI returns value +*/ +module dummy_icache #( + parameter ADDR_WIDTH = 32, + parameter DATA_WIDTH = 32 +) ( + input logic clk, + input logic rst, + + // <-> IF + // All signals are 1 cycle valid + // all 0 means invalid + input logic [ADDR_WIDTH-1:0] raddr_1_i, + input logic [ADDR_WIDTH-1:0] raddr_2_i, + // Require IF stage not to send more instr addr + // stallreq is pull up the next clk when queue is full + // and pull down then next clk when queue can accept addr + output logic stallreq_o, + // rvalid is 1 when output is valid + output logic rvalid_1_o, + output logic rvalid_2_o, + // Must return the addr as well + output logic [ADDR_WIDTH-1:0] raddr_1_o, + output logic [ADDR_WIDTH-1:0] raddr_2_o, + output logic [DATA_WIDTH-1:0] rdata_1_o, + output logic [DATA_WIDTH-1:0] rdata_2_o, + + // <-> AXI Controller + output logic [ADDR_WIDTH-1:0] axi_addr_o, + + // Assume busy is pull down the same cycle when data is ready + input logic [DATA_WIDTH-1:0] axi_data_i, + input logic axi_busy_i +); + + // Reset signal + logic rst_n; + assign rst_n = ~rst; + + logic [ADDR_WIDTH-1:0] raddrs[2]; // Accept two addr + + // States + enum int unsigned { + ACCEPT_ADDR = 0, + IN_TRANSACTION_1 = 1, + IN_TRANSACTION_2 = 2 + } + state, next_state; + + always_ff @(posedge clk or negedge rst_n) begin : state_ff + if (!rst_n) begin + state <= ACCEPT_ADDR; + end else begin + state <= next_state; + end + end + + always_comb begin : transition_comb + case (state) + ACCEPT_ADDR: begin + if (raddr_1_i != 0 || raddr_2_i != 0) begin + next_state = IN_TRANSACTION_1; + end else begin + next_state = ACCEPT_ADDR; + end + end + IN_TRANSACTION_1: begin + if (axi_busy_i == 0) begin + next_state = IN_TRANSACTION_2; + end else begin + next_state = IN_TRANSACTION_1; + end + end + IN_TRANSACTION_2: begin + if (axi_busy_i == 0) begin + next_state = ACCEPT_ADDR; + end else begin + next_state = IN_TRANSACTION_2; + end + end + endcase + end + + always_ff @(posedge clk or negedge rst_n) begin : raddrs_ff + if (!rst_n) begin + raddrs[0] <= 0; + raddrs[1] <= 0; + end else begin + case (state) + ACCEPT_ADDR: begin + raddrs[0] <= raddr_1_i; + raddrs[1] <= raddr_2_i; + end + IN_TRANSACTION_1, IN_TRANSACTION_2: begin + // Do nothing + end + endcase + end + end + + assign stallreq_o = ~(state == ACCEPT_ADDR); + + always_ff @(posedge clk or negedge rst_n) begin : axi_ff + if (!rst_n) begin + axi_addr_o <= 0; + end else begin + case (state) + ACCEPT_ADDR: begin + if (raddr_1_i != 0) axi_addr_o <= raddr_1_i; + end + IN_TRANSACTION_1: begin + if (raddrs[1] != 0) axi_addr_o <= raddrs[1]; + end + IN_TRANSACTION_2: begin + axi_addr_o <= 0; + end + endcase + end + end + + // Output logic + always_comb begin : output_comb + rvalid_1_o = 0; + rvalid_2_o = 0; + raddr_1_o = 0; + raddr_2_o = 0; + rdata_1_o = 0; + rdata_2_o = 0; + case (state) + ACCEPT_ADDR: begin + end + IN_TRANSACTION_1: begin + rvalid_1_o = ~axi_busy_i; + rdata_1_o = axi_busy_i ? 0 : axi_data_i; + end + IN_TRANSACTION_2: begin + rvalid_2_o = ~axi_busy_i; + rdata_2_o = axi_busy_i ? 0 : axi_data_i; + end + endcase + end + +endmodule From 0ea1f546b139e24f6065cac81f8a55e659a1a7b0 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Wed, 4 May 2022 14:05:38 +0800 Subject: [PATCH 051/114] fix: minor fix --- src/vsrc/cpu_top.v | 4 ++-- src/vsrc/pipeline/4_mem/mem_wb.v | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vsrc/cpu_top.v b/src/vsrc/cpu_top.v index 9c2ac6c..0001def 100644 --- a/src/vsrc/cpu_top.v +++ b/src/vsrc/cpu_top.v @@ -117,7 +117,7 @@ module cpu_top ( .aresetn(aresetn), .cpu_addr_i(axi_addr), - .cpu_ce_i(chip_enable), + .cpu_ce_i(axi_addr != 0), .cpu_data_i(0), .cpu_we_i(1'b0), .cpu_sel_i(4'b1111), @@ -1589,7 +1589,7 @@ module cpu_top ( .csr_data () ); - DifftestCSRRegState DifftestCSRRegState ( + DifftestCSRRegState difftest_csr_state ( .clock (aclk), .coreid (0), // Only one core, so always 0 .crmd (u_cs_reg.csr_crmd), diff --git a/src/vsrc/pipeline/4_mem/mem_wb.v b/src/vsrc/pipeline/4_mem/mem_wb.v index 518c0ff..61d381f 100644 --- a/src/vsrc/pipeline/4_mem/mem_wb.v +++ b/src/vsrc/pipeline/4_mem/mem_wb.v @@ -131,11 +131,11 @@ module mem_wb ( wb_csr_data <= `ZeroWord; debug_commit_instr <= `ZeroWord; debug_commit_pc <= `ZeroWord; - debug_commit_valid <= `InstInvalid; + debug_commit_valid <= ~`InstInvalid; end else if (stall == `Stop) begin debug_commit_pc <= `ZeroWord; debug_commit_instr <= `ZeroWord; - debug_commit_valid <= ~`InstInvalid; + debug_commit_valid <= `InstInvalid; end else begin wb_wd <= mem_wd; wb_wreg <= mem_wreg; @@ -148,7 +148,7 @@ module mem_wb ( wb_csr_data <= mem_csr_data; debug_commit_pc <= mem_inst_pc; // debug_commit_pc <= debug_commit_pc_0; - debug_commit_valid <= ~mem_inst_valid; + debug_commit_valid <= mem_inst_valid; // debug_commit_valid_1 <= debug_commit_valid_0; // debug_commit_valid <= ~debug_commit_valid_1; debug_commit_instr <= mem_instr; From e52914fb6c781705c2595740d7cb7007bdd4bed6 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Wed, 4 May 2022 14:25:38 +0800 Subject: [PATCH 052/114] fix: fix dummy icache --- src/vsrc/cpu_top.v | 2 +- src/vsrc/dummy_icache.sv | 51 ++++++++++++++++++++-------------------- 2 files changed, 26 insertions(+), 27 deletions(-) diff --git a/src/vsrc/cpu_top.v b/src/vsrc/cpu_top.v index 0001def..7268a3a 100644 --- a/src/vsrc/cpu_top.v +++ b/src/vsrc/cpu_top.v @@ -99,7 +99,7 @@ module cpu_top ( .rst (rst), .raddr_1_i (pc_buffer_1), .raddr_2_i (pc_buffer_2), - .stallreq_o(stallreq_from_id_1), + .stallreq_o(), .rvalid_1_o(), .rvalid_2_o(), .raddr_1_o (), diff --git a/src/vsrc/dummy_icache.sv b/src/vsrc/dummy_icache.sv index 33d675c..27b2479 100644 --- a/src/vsrc/dummy_icache.sv +++ b/src/vsrc/dummy_icache.sv @@ -104,41 +104,40 @@ module dummy_icache #( assign stallreq_o = ~(state == ACCEPT_ADDR); always_ff @(posedge clk or negedge rst_n) begin : axi_ff - if (!rst_n) begin - axi_addr_o <= 0; - end else begin - case (state) - ACCEPT_ADDR: begin - if (raddr_1_i != 0) axi_addr_o <= raddr_1_i; - end - IN_TRANSACTION_1: begin - if (raddrs[1] != 0) axi_addr_o <= raddrs[1]; - end - IN_TRANSACTION_2: begin - axi_addr_o <= 0; - end - endcase - end + axi_addr_o <= 0; + case (state) + ACCEPT_ADDR: begin + if (raddr_1_i != 0 && axi_busy_i == 0) axi_addr_o <= raddr_1_i; + end + IN_TRANSACTION_1: begin + if (raddrs[1] != 0 && axi_busy_i == 0) axi_addr_o <= raddrs[1]; + end + IN_TRANSACTION_2: begin + axi_addr_o <= 0; + end + endcase end // Output logic - always_comb begin : output_comb - rvalid_1_o = 0; - rvalid_2_o = 0; - raddr_1_o = 0; - raddr_2_o = 0; - rdata_1_o = 0; - rdata_2_o = 0; + always_ff @(posedge clk or negedge rst_n) begin : output_ff + rvalid_1_o <= 0; + rvalid_2_o <= 0; + raddr_1_o <= 0; + raddr_2_o <= 0; + rdata_1_o <= 0; + rdata_2_o <= 0; case (state) ACCEPT_ADDR: begin end IN_TRANSACTION_1: begin - rvalid_1_o = ~axi_busy_i; - rdata_1_o = axi_busy_i ? 0 : axi_data_i; + rvalid_1_o <= ~axi_busy_i; + raddr_1_o <= axi_busy_i ? 0 : raddrs[0]; + rdata_1_o <= axi_busy_i ? 0 : axi_data_i; end IN_TRANSACTION_2: begin - rvalid_2_o = ~axi_busy_i; - rdata_2_o = axi_busy_i ? 0 : axi_data_i; + rvalid_2_o <= ~axi_busy_i; + raddr_2_o <= axi_busy_i ? 0 : raddrs[1]; + rdata_2_o <= axi_busy_i ? 0 : axi_data_i; end endcase end From a18df1049e8b182f69eaef52a55c8b5bbdb0a7e3 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Wed, 4 May 2022 14:40:15 +0800 Subject: [PATCH 053/114] docs: fix comments --- src/vsrc/cpu_top.v | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vsrc/cpu_top.v b/src/vsrc/cpu_top.v index 7268a3a..60625ba 100644 --- a/src/vsrc/cpu_top.v +++ b/src/vsrc/cpu_top.v @@ -22,7 +22,7 @@ module cpu_top ( input wire [7:0] intrpt, // External interrupt // AXI interface - // read reqest + // read request output [ 3:0] arid, output [31:0] araddr, output [ 7:0] arlen, @@ -58,12 +58,12 @@ module cpu_top ( output wlast, output wvalid, input wready, - //write back + // write back input [ 3:0] bid, input [ 1:0] bresp, input bvalid, output bready, - //debug info + // debug info output [31:0] debug0_wb_pc, output [ 3:0] debug0_wb_rf_wen, output [ 4:0] debug0_wb_rf_wnum, @@ -117,7 +117,7 @@ module cpu_top ( .aresetn(aresetn), .cpu_addr_i(axi_addr), - .cpu_ce_i(axi_addr != 0), + .cpu_ce_i(axi_addr != 0), // FIXME: ce should not be used as valid? .cpu_data_i(0), .cpu_we_i(1'b0), .cpu_sel_i(4'b1111), From 59693d416688298f91d1b9cf3a1c89ac4c2243d8 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Wed, 4 May 2022 15:04:41 +0800 Subject: [PATCH 054/114] feat: frontend & IB design --- src/vsrc/frontend/frontend.sv | 19 +++++++++++++++++++ src/vsrc/instr_buffer.sv | 21 +++++++++++++++++++++ src/vsrc/instr_info.sv | 30 ++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100644 src/vsrc/frontend/frontend.sv create mode 100644 src/vsrc/instr_buffer.sv create mode 100644 src/vsrc/instr_info.sv diff --git a/src/vsrc/frontend/frontend.sv b/src/vsrc/frontend/frontend.sv new file mode 100644 index 0000000..946f657 --- /dev/null +++ b/src/vsrc/frontend/frontend.sv @@ -0,0 +1,19 @@ +`include "instr_info.sv" +module frontend #( + parameter FETCH_WIDTH = 2 +) ( + input logic clk, + input logic rst, + + // <-> Backend + input branch_update_info_t branch_update_info_i, + input logic [`InstAddrBus] backend_next_pc_i, + input logic backend_flush_i, + + // <-> Instruction buffer + input logic instr_buffer_stallreq_i, + output instr_buffer_info_t instr_buffer_o[FETCH_WIDTH] + +); + +endmodule diff --git a/src/vsrc/instr_buffer.sv b/src/vsrc/instr_buffer.sv new file mode 100644 index 0000000..2845c5d --- /dev/null +++ b/src/vsrc/instr_buffer.sv @@ -0,0 +1,21 @@ +`include "instr_info.sv" + +module instr_buffer #( + parameter IF_WIDTH = 2, + parameter ID_WIDTH = 2 +) ( + input logic clk, + input logic rst, + + // <-> Frontend + input instr_buffer_info_t if_instr_i[IF_WIDTH], + output logic frontend_stallreq_o, // Require frontend to stop + + // <-> Backend + input logic backend_stallreq_i, // Backend is stalling + input logic flush_i, // Backend require flush, maybe branch miss + output instr_buffer_info_t id_instr_o[ID_WIDTH] + +); + +endmodule diff --git a/src/vsrc/instr_info.sv b/src/vsrc/instr_info.sv new file mode 100644 index 0000000..fef76b5 --- /dev/null +++ b/src/vsrc/instr_info.sv @@ -0,0 +1,30 @@ +// Instruction info define +`ifndef INSTR_INFO_SV +`define INSTR_INFO_SV +`include "defines.v" + +typedef struct packed { + bit valid; + bit [`InstAddrBus] pc; + bit [`InstBus] instr; + + // BPU info + bit [2:0] bpu_useful_bits; + bit [2:0] bpu_ctr_bits; + bit [2:0] bpu_provider_id; + bit [13:0] bpu_provider_query_index; +} instr_buffer_info_t; + +typedef struct packed { + bit valid; + bit [`InstAddrBus] pc; + bit taken; + + // BPU info + bit [2:0] bpu_useful_bits; + bit [2:0] bpu_ctr_bits; + bit [2:0] bpu_provider_id; + bit [13:0] bpu_provider_query_index; +} branch_update_info_t; + +`endif From 6953fb635a6ef612ebf7309c4bc9e3204554302a Mon Sep 17 00:00:00 2001 From: Easton Man Date: Wed, 4 May 2022 15:11:02 +0800 Subject: [PATCH 055/114] feat: polish frontend design --- src/vsrc/frontend/frontend.sv | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/vsrc/frontend/frontend.sv b/src/vsrc/frontend/frontend.sv index 946f657..64da9da 100644 --- a/src/vsrc/frontend/frontend.sv +++ b/src/vsrc/frontend/frontend.sv @@ -1,13 +1,23 @@ `include "instr_info.sv" module frontend #( - parameter FETCH_WIDTH = 2 + parameter FETCH_WIDTH = 2, + parameter ADDR_WIDTH = 32, + parameter DATA_WIDTH = 32 ) ( input logic clk, input logic rst, + // <-> ICache + output logic [ADDR_WIDTH-1:0] icache_read_addr_o[FETCH_WIDTH], + input logic icache_stallreq_i, // ICache cannot accept more addr input + input logic icache_read_valid_i[FETCH_WIDTH], + input logic [ADDR_WIDTH-1:0] icache_read_addr_i[FETCH_WIDTH], + input logic [DATA_WIDTH-1:0] icache_read_data_i[FETCH_WIDTH], + + // <-> Backend input branch_update_info_t branch_update_info_i, - input logic [`InstAddrBus] backend_next_pc_i, + input logic [ADDR_WIDTH-1:0] backend_next_pc_i, input logic backend_flush_i, // <-> Instruction buffer From b1491ba852d6c3206e5e6ec509e4376deaa4b06e Mon Sep 17 00:00:00 2001 From: Easton Man Date: Wed, 4 May 2022 19:05:29 +0800 Subject: [PATCH 056/114] feat: implement instr_buffer --- doc/instr_buffer.md | 46 +++++++++++++++++++ src/vsrc/instr_buffer.sv | 98 ++++++++++++++++++++++++++++++++++++++-- src/vsrc/instr_info.sv | 7 +-- 3 files changed, 143 insertions(+), 8 deletions(-) create mode 100644 doc/instr_buffer.md diff --git a/doc/instr_buffer.md b/doc/instr_buffer.md new file mode 100644 index 0000000..c71a6b3 --- /dev/null +++ b/doc/instr_buffer.md @@ -0,0 +1,46 @@ +# Instruction Buffer 设计 + +## 整体设计 + +使用类似状态机的写法,使用一个长度为`BUFFER_SIZE`的寄存器`buffer_queue`保存当前状态。 +使用`read_ptr`和`write_ptr`记录后端和前端的读写位置。 + +更新逻辑: + +根据后端当拍返回的可接受的指令,确定`read_ptr`的更新和`buffer_queue`对应位置的重置。 + +根据前端给出的指令更新`write_ptr`和对应位置的更新。 + +根据当前的两个ptr给出前端停顿的指令 + + +## 前端信号 + +```verilog + // <-> Frontend + input instr_buffer_info_t frontend_instr_i[IF_WIDTH], + output logic frontend_stallreq_o, // Require frontend to stop +``` +接受前端的两条指令,当拍给出`frontend_stallreq_o` + +要求前端停顿时完全保持输入的两条指令不变 + +如果前端给出的两条指令不是都有效,那么要求有效的必须都在低位,而且保证指令的顺序关系,即低位对应指令流中靠前的指令。 + +## 后端信号 + +```verilog + // <-> Backend + input logic [ID_WIDTH-1:0] backend_accept_i, // Backend can accept 0 or more instructions, must return in current cycle! + input logic backend_flush_i, // Backend require flush, maybe branch miss + output instr_buffer_info_t backend_instr_o[ID_WIDTH] +``` + +将`buffer_queue`的对应位置直接接到`backend_instr_o`,不保证两条指令都有效,甚至可能都无效(如初始时) + +要求当拍返回`backend_accept_i`信号,如果接受指令,意思即这条指令会进入下一级,如果接受,返回的接受信号必须都在低位。 + +下一周期接受的指令将会被重置,然后顺序移动指令,即如果接受接受指令1,拒绝指令2,下一周期指令2将变为指令1,指令2为新的指令。 + +后端或ctrl 输入`backend_flush_i`的下一周期将全部`buffer_queue`刷空,因为`backend_instr_o`是直接接在`buffer_queue`上的,因此下一周期也变为空。 + diff --git a/src/vsrc/instr_buffer.sv b/src/vsrc/instr_buffer.sv index 2845c5d..3ef01ba 100644 --- a/src/vsrc/instr_buffer.sv +++ b/src/vsrc/instr_buffer.sv @@ -2,20 +2,108 @@ module instr_buffer #( parameter IF_WIDTH = 2, - parameter ID_WIDTH = 2 + parameter ID_WIDTH = 2, + parameter BUFFER_SIZE = 8 ) ( input logic clk, input logic rst, // <-> Frontend - input instr_buffer_info_t if_instr_i[IF_WIDTH], + input instr_buffer_info_t frontend_instr_i[IF_WIDTH], output logic frontend_stallreq_o, // Require frontend to stop // <-> Backend - input logic backend_stallreq_i, // Backend is stalling - input logic flush_i, // Backend require flush, maybe branch miss - output instr_buffer_info_t id_instr_o[ID_WIDTH] + input logic [ID_WIDTH-1:0] backend_accept_i, // Backend can accept 0 or more instructions, must return in current cycle! + input logic backend_flush_i, // Backend require flush, maybe branch miss + output instr_buffer_info_t backend_instr_o[ID_WIDTH] ); + // Reset signal + logic rst_n; + assign rst_n = ~rst; + + instr_buffer_info_t buffer_queue[BUFFER_SIZE]; + instr_buffer_info_t next_buffer_queue[BUFFER_SIZE]; + logic [$clog2(BUFFER_SIZE)-1:0] read_ptr, write_ptr; + + assign frontend_stallreq_o = (write_ptr + 2 >= read_ptr); + + logic [$clog2(ID_WIDTH):0] backend_accept_num; // popcnt of backend_accept_i + always_comb begin + backend_accept_num = 0; + foreach (backend_accept_i[idx]) begin + backend_accept_num += backend_accept_i[idx]; + end + end + + + always_ff @(posedge clk or negedge rst_n) begin : buffer_queue_ff + if ((!rst_n) || backend_flush_i) begin + for (integer i = 0; i < BUFFER_SIZE; i++) begin + buffer_queue[i] <= 0; + end + end else begin + for (integer i = 0; i < BUFFER_SIZE; i++) begin + // Select next buffer_queue + buffer_queue[i] <= next_buffer_queue[i]; + end + end + end + + logic [IF_WIDTH-1:0] if_valid; + always_comb begin + for (integer i = 0; i < IF_WIDTH; i++) begin + if_valid[i] = frontend_instr_i[i].valid; + end + end + logic [$clog2(IF_WIDTH):0] frontend_accept_num; // popcnt of backend_accept_i + always_comb begin + frontend_accept_num = 0; + foreach (if_valid[idx]) begin + frontend_accept_num += if_valid[idx]; + end + end + + always_ff @(posedge clk or negedge rst_n) begin : ptr_ff + if (!rst_n) begin + read_ptr <= 0; + write_ptr <= 0; + end else begin + read_ptr <= read_ptr + backend_accept_num; + write_ptr <= write_ptr + frontend_accept_num; + end + end + + always_comb begin : next_buffer_queue_comb // Main shift logic + // Default keep all entry + foreach (buffer_queue[idx]) begin + next_buffer_queue[idx] = buffer_queue[idx]; + end + + // Backend overide + for (integer i = 0; i < ID_WIDTH; i++) begin + // Reset entry + if (i < backend_accept_num) begin + next_buffer_queue[read_ptr+i] = 0; + end + end + + // Frontend overide + for (integer i = 0; i < IF_WIDTH; i++) begin + // Reset entry + if (i < backend_accept_num) begin + next_buffer_queue[write_ptr+i] = frontend_instr_i[i]; + end + end + end + + // FIXME: may introduce large latency + always_comb begin : backend_instr_o_comb + for (integer i = 0; i < ID_WIDTH; i++) begin + backend_instr_o[i] = buffer_queue[read_ptr+i]; + end + end + + endmodule diff --git a/src/vsrc/instr_info.sv b/src/vsrc/instr_info.sv index fef76b5..a9f0f4c 100644 --- a/src/vsrc/instr_info.sv +++ b/src/vsrc/instr_info.sv @@ -9,9 +9,10 @@ typedef struct packed { bit [`InstBus] instr; // BPU info - bit [2:0] bpu_useful_bits; - bit [2:0] bpu_ctr_bits; - bit [2:0] bpu_provider_id; + bit bpu_predicted_taken; + bit [2:0] bpu_useful_bits; + bit [2:0] bpu_ctr_bits; + bit [2:0] bpu_provider_id; bit [13:0] bpu_provider_query_index; } instr_buffer_info_t; From 8e0e401fbbddc00fb8420a548d21957f23a85d2a Mon Sep 17 00:00:00 2001 From: Easton Man Date: Wed, 4 May 2022 20:45:23 +0800 Subject: [PATCH 057/114] feat: implement frontend and IB --- src/vsrc/{cpu_top.v => cpu_top.sv} | 218 +++++++++++------------------ src/vsrc/frontend/frontend.sv | 76 ++++++++++ src/vsrc/instr_buffer.sv | 5 +- 3 files changed, 160 insertions(+), 139 deletions(-) rename src/vsrc/{cpu_top.v => cpu_top.sv} (92%) diff --git a/src/vsrc/cpu_top.v b/src/vsrc/cpu_top.sv similarity index 92% rename from src/vsrc/cpu_top.v rename to src/vsrc/cpu_top.sv index 60625ba..db7d49e 100644 --- a/src/vsrc/cpu_top.v +++ b/src/vsrc/cpu_top.sv @@ -1,4 +1,5 @@ `include "defines.v" +`include "instr_info.sv" `include "pc_reg.v" `include "regfile.v" `include "csr_defines.v" @@ -6,6 +7,8 @@ `include "tlb.v" `include "tlb_entry.v" `include "AXI/axi_master.v" +`include "frontend/frontend.sv" +`include "instr_buffer.sv" `include "pipeline/1_fetch/if_buffer.v" `include "pipeline/1_fetch/if_id.v" `include "pipeline/2_decode/id.v" @@ -73,6 +76,7 @@ module cpu_top ( // Clock signal wire clk; assign clk = aclk; + // Reset signal wire rst_n; wire rst; @@ -91,27 +95,6 @@ module cpu_top ( wire [`RegBus] axi_data; wire [`RegBus] axi_addr; - dummy_icache #( - .ADDR_WIDTH(`RegWidth), - .DATA_WIDTH(`RegWidth) - ) u_dummy_icache ( - .clk (clk), - .rst (rst), - .raddr_1_i (pc_buffer_1), - .raddr_2_i (pc_buffer_2), - .stallreq_o(), - .rvalid_1_o(), - .rvalid_2_o(), - .raddr_1_o (), - .raddr_2_o (), - .rdata_1_o (), - .rdata_2_o (), - .axi_addr_o(axi_addr), - .axi_data_i(axi_data), - .axi_busy_i(axi_busy) - ); - - axi_master u_axi_master ( .aclk (aclk), .aresetn(aresetn), @@ -164,12 +147,85 @@ module cpu_top ( .s_bready(bready) ); + // FETCH_WIDTH is 2 + localparam FETCH_WIDTH = 2; + // Frontend -> ICache + logic [`InstAddrBus] frontend_icache_addr[FETCH_WIDTH]; + + // ICache -> Frontend + logic icache_frontend_stallreq; + logic icache_frontend_valid[FETCH_WIDTH]; + logic [`InstAddrBus] icache_frontend_addr[FETCH_WIDTH]; + logic [`RegBus] icache_frontend_data[FETCH_WIDTH]; + + + dummy_icache #( + .ADDR_WIDTH(`RegWidth), + .DATA_WIDTH(`RegWidth) + ) u_dummy_icache ( + .clk(clk), + .rst(rst), + + // <-> Frontend + .raddr_1_i (frontend_icache_addr[0]), + .raddr_2_i (frontend_icache_addr[1]), + .stallreq_o(icache_frontend_stallreq), + .rvalid_1_o(icache_frontend_valid[0]), + .rvalid_2_o(icache_frontend_valid[1]), + .raddr_1_o (icache_frontend_addr[0]), + .raddr_2_o (icache_frontend_addr[1]), + .rdata_1_o (icache_frontend_data[0]), + .rdata_2_o (icache_frontend_data[1]), + + // <-> AXI Controller + .axi_addr_o(axi_addr), + .axi_data_i(axi_data), + .axi_busy_i(axi_busy) + ); + + // Frontend <-> Instruction Buffer + logic ib_frontend_stallreq; + instr_buffer_info_t frontend_ib_instr_info[FETCH_WIDTH]; + + frontend u_frontend ( + .clk(clk), + .rst(rst), + + // <-> ICache + .icache_read_addr_o (frontend_icache_addr), + .icache_stallreq_i (icache_frontend_stallreq), + .icache_read_valid_i(icache_frontend_valid), + .icache_read_addr_i (icache_frontend_addr), + .icache_read_data_i (icache_frontend_data), + + // <-> Backend + .branch_update_info_i(), + .backend_next_pc_i (), + .backend_flush_i (), + + // <-> Instruction Buffer + .instr_buffer_stallreq_i(ib_frontend_stallreq), + .instr_buffer_o (frontend_ib_instr_info) + ); + + instr_buffer #( + .IF_WIDTH(FETCH_WIDTH), + .ID_WIDTH(2) // TODO: remove magic number + ) u_instr_buffer ( + .clk(clk), + .rst(rst), + + // <-> Frontend + .frontend_instr_i (frontend_ib_instr_info), + .frontend_stallreq_o(ib_frontend_stallreq), + + // <-> Backend + .backend_accept_i(2'b0), // FIXME: currently not accepting any instructions + .backend_flush_i (), + .backend_instr_o () + ); - wire [`InstAddrBus] pc_1; - wire [`InstAddrBus] pc_2; - wire [`InstAddrBus] pc_buffer_1; - wire [`InstAddrBus] pc_buffer_2; wire [`RegBus] branch_target_address_1; @@ -294,51 +350,6 @@ module cpu_top ( wire disable_cache; - pc_reg u_pc_reg ( - .clk(clk), - .rst(rst), - .pc_1(pc_1), - .pc_2(pc_2), - .ce(chip_enable), - .branch_flag_i_1(branch_flag_1), - .branch_target_address_1(branch_target_address_1), - .branch_flag_i_2(branch_flag_2), - .branch_target_address_2(branch_target_address_2), - .flush(flush), - .new_pc(new_pc), - .stall1(stall1[0]), - .stall2(stall2[0]), - .excp_flush(excp_flush), - .ertn_flush(ertn_flush), - .excp_tlbrefill(excp_tlbrefill), - .idle_flush(idle_flush), - .idle_pc(idle_pc), - - .excp_o(pc_excp_o), - .excp_num_o(pc_excp_num_o), - - .csr_pg(csr_pg), - .csr_da(csr_da), - .csr_dmw0(csr_dmw0), - .csr_dmw1(csr_dmw1), - .csr_plv(csr_plv), - .csr_datf(csr_datf), - .disable_cache(disable_cache), - .csr_eentry(csr_eentry), - .csr_era(csr_era), - .csr_tlbrentry(csr_tlbrentry), - - .inst_tlb_found(inst_tlb_found), - .inst_tlb_v(inst_tlb_v), - .inst_tlb_d(inst_tlb_d), - .inst_tlb_mat(inst_tlb_mat), - .inst_tlb_plv(inst_tlb_plv), - - .inst_addr(inst_vaddr), - .inst_addr_trans_en(inst_addr_trans_en), - .dmw0_en(inst_dmw0_en), - .dmw1_en(inst_dmw1_en) - ); wire if_inst_valid_1; wire if_inst_valid_2; @@ -347,39 +358,6 @@ module cpu_top ( wire if_excp_i_2; wire [3:0] if_excp_num_i_2; - if_buffer if_buffer_1 ( - .clk(clk), - .rst(rst), - .pc_i(pc_1), - .branch_flag_i(branch_flag_1 | branch_flag_2), - .pc_valid(if_inst_valid_1), - .pc_o(pc_buffer_1), - .flush(flush), - .stall(stall1[1]), - .excp_i(pc_excp_o), - .excp_num_i(pc_excp_num_o), - .excp_o(if_excp_i_1), - .excp_num_o(if_excp_num_i_1), - .excp_flush(excp_flush), - .ertn_flush(ertn_flush) - ); - - if_buffer if_buffer_2 ( - .clk(clk), - .rst(rst), - .pc_i(pc_2), - .branch_flag_i(branch_flag), - .pc_valid(if_inst_valid_2), - .pc_o(pc_buffer_2), - .flush(flush), - .stall(stall2[1]), - .excp_i(pc_excp_o), - .excp_num_i(pc_excp_num_o), - .excp_o(if_excp_i_2), - .excp_num_o(if_excp_num_i_2), - .excp_flush(excp_flush), - .ertn_flush(ertn_flush) - ); wire [`InstAddrBus] id_pc_1; @@ -392,40 +370,6 @@ module cpu_top ( wire if_excp_o_2; wire [3:0] if_excp_num_o_2; - // wire if_id_instr_invalid; - if_id u_if_id_1 ( - .clk(clk), - .rst(rst), - .if_pc_i(pc_buffer_1), - .if_inst_i(ram_rdata_i_1), - .id_pc_o(id_pc_1), - .id_inst_o(id_inst_1), - .if_inst_valid(if_inst_valid_1), - .branch_flag_i(branch_flag), - .flush(flush), - .stall(stall1[2]), - .excp_i(if_excp_i_1), - .excp_num_i(if_excp_num_i_1), - .excp_o(if_excp_o_1), - .excp_num_o(if_excp_num_o_1) - ); - - if_id u_if_id_2 ( - .clk(clk), - .rst(rst), - .if_pc_i(pc_buffer_2), - .if_inst_i(ram_rdata_i_2), - .id_pc_o(id_pc_2), - .id_inst_o(id_inst_2), - .if_inst_valid(if_inst_valid_2), - .branch_flag_i(branch_flag), - .flush(flush), - .stall(stall2[2]), - .excp_i(if_excp_i_2), - .excp_num_i(if_excp_num_i_2), - .excp_o(if_excp_o_2), - .excp_num_o(if_excp_num_o_2) - ); wire [`AluOpBus] id_aluop_1; wire [`AluSelBus] id_alusel_1; diff --git a/src/vsrc/frontend/frontend.sv b/src/vsrc/frontend/frontend.sv index 64da9da..90e29e0 100644 --- a/src/vsrc/frontend/frontend.sv +++ b/src/vsrc/frontend/frontend.sv @@ -26,4 +26,80 @@ module frontend #( ); + // Reset signal + logic rst_n; + assign rst_n = ~rst; + + logic [ADDR_WIDTH-1:0] pc, next_pc; + + always_ff @(posedge clk or negedge rst_n) begin : pc_ff + if (!rst_n) begin + pc <= 32'h1c000000; + end else begin + pc <= next_pc; + end + end + + always_comb begin : next_pc_comb + if (backend_flush_i) begin + next_pc = backend_next_pc_i; + end else if (instr_buffer_stallreq_i) begin + next_pc = pc; + end else if (icache_stallreq_i) begin + next_pc = pc; + end else begin + next_pc = pc + 8; + end + end + + // ICache read_addr_o + always_comb begin : icache_read_addr_o_comb + for (integer i = 0; i < FETCH_WIDTH; i++) begin + icache_read_addr_o[i] = pc + i * 4; + end + end + + typedef struct packed { + bit valid; + bit [ADDR_WIDTH-1:0] pc; + bit [DATA_WIDTH-1:0] instr; + } icache_resp_t; + icache_resp_t icache_resp_buffer[FETCH_WIDTH]; + always_ff @(posedge clk or negedge rst_n) begin : icache_resp_buffer_ff + if (!rst_n || icache_resp_ready) begin + for (integer i = 0; i < FETCH_WIDTH; i++) begin + icache_resp_buffer[i] <= 0; + end + end else begin + for (integer i = 0; i < FETCH_WIDTH; i++) begin + if (icache_read_valid_i[i]) begin + icache_resp_buffer[i].valid <= 1; + icache_resp_buffer[i].pc <= icache_read_addr_i[i]; + icache_resp_buffer[i].instr <= icache_read_data_i[i]; + end + end + end + end + logic icache_resp_ready; // 1 if all the instr in icache_resp_buffer is valid + always_comb begin : icache_resp_ready_comb + icache_resp_ready = 1; + for (integer i = 0; i < FETCH_WIDTH; i++) begin + icache_resp_ready = icache_resp_ready & icache_resp_buffer[i].valid; + end + end + + always_ff @(posedge clk or negedge rst_n) begin : instr_buffer_o_ff + // Keep 0 for most of the time + for (integer i = 0; i < FETCH_WIDTH; i++) begin + instr_buffer_o[i] <= 0; + end + if (icache_resp_ready && !instr_buffer_stallreq_i) begin + for (integer i = 0; i < FETCH_WIDTH; i++) begin + instr_buffer_o[i].valid <= 1; + instr_buffer_o[i].pc <= icache_resp_buffer[i].pc; + instr_buffer_o[i].instr <= icache_resp_buffer[i].instr; + end + end + end + endmodule diff --git a/src/vsrc/instr_buffer.sv b/src/vsrc/instr_buffer.sv index 3ef01ba..2f36260 100644 --- a/src/vsrc/instr_buffer.sv +++ b/src/vsrc/instr_buffer.sv @@ -25,9 +25,10 @@ module instr_buffer #( instr_buffer_info_t buffer_queue[BUFFER_SIZE]; instr_buffer_info_t next_buffer_queue[BUFFER_SIZE]; - logic [$clog2(BUFFER_SIZE)-1:0] read_ptr, write_ptr; + logic [$clog2(BUFFER_SIZE)-1:0] read_ptr, write_ptr, write_ptr_plus_2; - assign frontend_stallreq_o = (write_ptr + 2 >= read_ptr); + assign write_ptr_plus_2 = write_ptr + 2; + assign frontend_stallreq_o = (write_ptr_plus_2 == read_ptr); logic [$clog2(ID_WIDTH):0] backend_accept_num; // popcnt of backend_accept_i always_comb begin From 9211d2da6299c448b1af670f28da6cce7c321f4b Mon Sep 17 00:00:00 2001 From: Easton Man Date: Wed, 4 May 2022 21:39:31 +0800 Subject: [PATCH 058/114] docs: add verilog tips --- README.md | 3 +++ doc/verilog_tips.md | 8 ++++++++ 2 files changed, 11 insertions(+) create mode 100644 doc/verilog_tips.md diff --git a/README.md b/README.md index ffc27e6..97e64f3 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ src/ CPU Verilog 源代码 pipeline/ 流水线部分 AXI/ AXI 控制器 BPU/ 分支预测部件 + frontend/ 流水线前端,负责取指并塞入Instruction Buffer ... 其他模块 Makefile 用于自动化测试和Verilator仿真,无需关心 @@ -30,6 +31,8 @@ testbench.cpp 用于Verilator仿真,如果使用Vivado仿真,无需关 - [AXI控制器](src/vsrc/AXI/README.md) - [分支预测器](src/vsrc/BPU/README.md) - [Chiplab对接](doc/chiplab.md) +- [Instruction Buffer设计](doc/instr_buffer.md) +- [每日一个 Verilog 小技巧](doc/verilog_tips.md) ## 开发流程 diff --git a/doc/verilog_tips.md b/doc/verilog_tips.md new file mode 100644 index 0000000..cc4bb29 --- /dev/null +++ b/doc/verilog_tips.md @@ -0,0 +1,8 @@ +# 每日一个 Verilog 小技巧 + +## $clog2() 是可综合的 + +`$clog2()`是ceil(log2(x))的意思,2的对数的向上取整,常用于已知寻址范围,确定索引信号的位宽。 + +虽然看起来是一个系统调用,但是由于实在是过于好用,大部分的仿真和综合工具都支持处理这个函数。 + From ea32251d32ce938003793f9a6a55c18839fd26e8 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Wed, 4 May 2022 22:02:28 +0800 Subject: [PATCH 059/114] docs: add coding conventions --- README.md | 4 +++ doc/coding_conventions.md | 63 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 doc/coding_conventions.md diff --git a/README.md b/README.md index 97e64f3..348bb2f 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,10 @@ testbench.cpp 用于Verilator仿真,如果使用Vivado仿真,无需关 - [Instruction Buffer设计](doc/instr_buffer.md) - [每日一个 Verilog 小技巧](doc/verilog_tips.md) +## 代码规范 + +[代码规范](doc/coding_conventions.md) + ## 开发流程 ### Clone项目 diff --git a/doc/coding_conventions.md b/doc/coding_conventions.md new file mode 100644 index 0000000..454ec2b --- /dev/null +++ b/doc/coding_conventions.md @@ -0,0 +1,63 @@ +# 代码规范 + +## 缩进 + +统一使用 VS Code 插件 `bmpenuelas.systemverilog-formatter-vscode` 对代码进行自动格式化 + +注意使用`--indentation_spaces 4` + +还应将`.v`文件关联到`SystemVerilog`以获得自动格式化,具体方法是点击VS Code右下角的`Verilog`,然后在弹出的窗口选择`Configure File Association for '.v'` + +## 模块(module) + +### 模块命名 + +使用蛇形命名,形如`aaa_bbb_ccc` + +### 模块端口命名 + +一般来讲分为三个部分,每个部分之间通过下划线连接: +- 连接到的模块简称,如`icache` +- 信号线的含义,如`data` +- 信号的方向,`o`或`i` + +全部连起来如`icache_data_o` + +### 模块端口类型(SystemVerilog) + +如果使用了SystemVerilog,那么尽量把意义相近的信号打包成struct,定义在头文件中,然后作为端口的类型 + +## 信号 + +### 信号命名 + +使用蛇形命名,在模块内部,不添加后缀`o`或`i` + +### 状态机(SystemVerilog) + +如果使用SystemVerilog,那么状态机的状态要求使用`enum` + +如: +```verilog + enum int unsigned { + ACCEPT_ADDR = 0, + IN_TRANSACTION_1 = 1, + IN_TRANSACTION_2 = 2 + } +``` + +### 模块间连线信号命名 + +约定实例化的模块间连接用的信号使用以下三部分命名: +- 起始模块名 +- 到达模块名 +- 信号含义 + +例如`frontend_icache_addr` + +如果有多输出的信号,使用`multi`代替到达模块名 + +例如`ctrl_multi_stall` + +注意无需`o`或`i` + From 552a0d8248b353f4ef2f3ad21d1790d21f29de8c Mon Sep 17 00:00:00 2001 From: Easton Man Date: Wed, 4 May 2022 22:09:14 +0800 Subject: [PATCH 060/114] docs: update directory structure --- README.md | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 348bb2f..053d30d 100644 --- a/README.md +++ b/README.md @@ -4,22 +4,26 @@ ## 目录结构 ``` -src/ CPU Verilog 源代码 - SimTop.v 顶层Soc,用于连接核心和其他模块 - SimTop_tb.v Vivado仿真testbench - ram.v 用于在仿真时读取inst_rom.data - inst_rom.data 存放内存初始内容 - - vsrc/ CPU 核心部分源码 - pipeline/ 流水线部分 - AXI/ AXI 控制器 - BPU/ 分支预测部件 - frontend/ 流水线前端,负责取指并塞入Instruction Buffer - ... 其他模块 - -Makefile 用于自动化测试和Verilator仿真,无需关心 -README.md 本文件 -testbench.cpp 用于Verilator仿真,如果使用Vivado仿真,无需关心 +src/ CPU Verilog 源代码 + SimTop.v 顶层Soc,用于连接核心和其他模块 + SimTop_tb.v Vivado仿真testbench + ram.v 用于在仿真时读取inst_rom.data + inst_rom.data 存放内存初始内容 + + vsrc/ CPU 核心部分源码 + pipeline/ 流水线部分 + AXI/ AXI 控制器 + BPU/ 分支预测部件 + frontend/ 流水线前端,负责取指并塞入Instruction Buffer + + cpu_top.sv CPU 内核顶层模块,目前含有ICache,Frontend,IB和流水线各级 + 同时是chiplab测试的入口,仅有AXI端口和外部中断端口 + + ... 其他模块 + +Makefile 用于自动化测试和Verilator仿真,无需关心 +README.md 本文件 +testbench.cpp 用于Verilator仿真,如果使用Vivado仿真,无需关心 ``` From d695198b856b074c1e32f6639837c4a5e1f07169 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Wed, 4 May 2022 22:27:40 +0800 Subject: [PATCH 061/114] refactor: rearrange code, no functional changes --- src/vsrc/instr_buffer.sv | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/src/vsrc/instr_buffer.sv b/src/vsrc/instr_buffer.sv index 2f36260..8c4d6e6 100644 --- a/src/vsrc/instr_buffer.sv +++ b/src/vsrc/instr_buffer.sv @@ -23,22 +23,16 @@ module instr_buffer #( logic rst_n; assign rst_n = ~rst; - instr_buffer_info_t buffer_queue[BUFFER_SIZE]; - instr_buffer_info_t next_buffer_queue[BUFFER_SIZE]; + instr_buffer_info_t buffer_queue[BUFFER_SIZE], next_buffer_queue[BUFFER_SIZE]; + logic [$clog2(BUFFER_SIZE)-1:0] read_ptr, write_ptr, write_ptr_plus_2; + // Workaround, verilator seems to extend {write_ptr + 2} to more bits + // we want a loopback counter, so declare a fixed width to get around assign write_ptr_plus_2 = write_ptr + 2; assign frontend_stallreq_o = (write_ptr_plus_2 == read_ptr); - logic [$clog2(ID_WIDTH):0] backend_accept_num; // popcnt of backend_accept_i - always_comb begin - backend_accept_num = 0; - foreach (backend_accept_i[idx]) begin - backend_accept_num += backend_accept_i[idx]; - end - end - - + // State transition always_ff @(posedge clk or negedge rst_n) begin : buffer_queue_ff if ((!rst_n) || backend_flush_i) begin for (integer i = 0; i < BUFFER_SIZE; i++) begin @@ -46,26 +40,29 @@ module instr_buffer #( end end else begin for (integer i = 0; i < BUFFER_SIZE; i++) begin - // Select next buffer_queue buffer_queue[i] <= next_buffer_queue[i]; end end end - logic [IF_WIDTH-1:0] if_valid; + // Popcnt of backend_accept_i + logic [$clog2(ID_WIDTH):0] backend_accept_num; always_comb begin - for (integer i = 0; i < IF_WIDTH; i++) begin - if_valid[i] = frontend_instr_i[i].valid; + backend_accept_num = 0; + foreach (backend_accept_i[idx]) begin + backend_accept_num += backend_accept_i[idx]; end end - logic [$clog2(IF_WIDTH):0] frontend_accept_num; // popcnt of backend_accept_i + // Popcnt of frontend_instr_i.[i].valid + logic [$clog2(IF_WIDTH):0] frontend_accept_num; always_comb begin frontend_accept_num = 0; - foreach (if_valid[idx]) begin - frontend_accept_num += if_valid[idx]; + foreach (frontend_instr_i[idx]) begin + frontend_accept_num += frontend_instr_i[idx].valid; end end + // Update ptrs always_ff @(posedge clk or negedge rst_n) begin : ptr_ff if (!rst_n) begin read_ptr <= 0; @@ -99,6 +96,7 @@ module instr_buffer #( end end + // Connect backend_instr_o directly to buffer_queue // FIXME: may introduce large latency always_comb begin : backend_instr_o_comb for (integer i = 0; i < ID_WIDTH; i++) begin From d72868438ed18d26528c1bf4b769ba9aa2fbd3dd Mon Sep 17 00:00:00 2001 From: Easton Man Date: Wed, 4 May 2022 22:29:22 +0800 Subject: [PATCH 062/114] refactor: rm 1_fetch, using updated IF --- src/vsrc/pipeline/1_fetch/if_buffer.v | 53 --------------------------- src/vsrc/pipeline/1_fetch/if_id.v | 51 -------------------------- 2 files changed, 104 deletions(-) delete mode 100644 src/vsrc/pipeline/1_fetch/if_buffer.v delete mode 100644 src/vsrc/pipeline/1_fetch/if_id.v diff --git a/src/vsrc/pipeline/1_fetch/if_buffer.v b/src/vsrc/pipeline/1_fetch/if_buffer.v deleted file mode 100644 index da11203..0000000 --- a/src/vsrc/pipeline/1_fetch/if_buffer.v +++ /dev/null @@ -1,53 +0,0 @@ -//to keep PC and inst_o corresponding -`include "defines.v" -module if_buffer ( - input wire clk, - input wire rst, - input wire [`InstAddrBus] pc_i, - input wire flush, - input wire stall, - input wire excp_flush, - input wire ertn_flush, - - input wire branch_flag_i, - output reg [`InstAddrBus] pc_o, - output reg pc_valid, - - input wire excp_i, - input wire [3:0] excp_num_i, - output reg excp_o, - output reg [3:0] excp_num_o -); - - always @(posedge clk) begin - if (rst) begin - pc_o <= `ZeroWord; - pc_valid <= `InstInvalid; - excp_o <= 1'b0; - excp_num_o <= 4'b0; - end else if (branch_flag_i == `Branch) begin - pc_o <= `ZeroWord; - pc_valid <= `InstInvalid; - excp_o <= 1'b0; - excp_num_o <= 4'b0; - end else if (flush == 1'b1 || excp_flush == 1'b1 || ertn_flush == 1'b1) begin - pc_o <= `ZeroWord; - pc_valid <= `InstInvalid; - excp_o <= 1'b0; - excp_num_o <= 4'b0; - end - else if(stall == `Stop) // Stall, hold output - begin - pc_o <= pc_o; - pc_valid <= pc_valid; - excp_o <= excp_i; - excp_num_o <= excp_num_i; - end else begin - pc_o <= pc_i; - pc_valid <= `InstValid; - excp_o <= excp_i; - excp_num_o <= excp_num_i; - end - end - -endmodule diff --git a/src/vsrc/pipeline/1_fetch/if_id.v b/src/vsrc/pipeline/1_fetch/if_id.v deleted file mode 100644 index 64cf9ca..0000000 --- a/src/vsrc/pipeline/1_fetch/if_id.v +++ /dev/null @@ -1,51 +0,0 @@ -`include "defines.v" -module if_id ( - input wire clk, - input wire rst, - - input wire branch_flag_i, - input wire [`InstAddrBus] if_pc_i, - input wire [`InstAddrBus] if_inst_i, - input wire if_inst_valid, - input wire flush, - input wire stall, // current stage stall, hold output - output reg [`InstAddrBus] id_pc_o, - output reg [`InstBus] id_inst_o, - - input wire excp_i, - input wire [3:0] excp_num_i, - output reg excp_o, - output reg [3:0] excp_num_o -); - - - always @(posedge clk) begin - if (rst == `RstEnable) begin - id_pc_o <= `ZeroWord; - id_inst_o <= `ZeroWord; - excp_o <= 1'b0; - excp_num_o <= 4'b0; - end else if (flush == 1'b1) begin - id_pc_o <= `ZeroWord; - id_inst_o <= `ZeroWord; - excp_o <= 1'b0; - excp_num_o <= 4'b0; - end else if (branch_flag_i || if_inst_valid == `InstInvalid) begin - id_pc_o <= `ZeroWord; - id_inst_o <= `ZeroWord; - excp_o <= 1'b0; - excp_num_o <= 4'b0; - end else if (stall == `Stop) begin - id_inst_o <= id_inst_o; - id_pc_o <= id_pc_o; - excp_o <= excp_i; - excp_num_o <= excp_num_i; - end else begin - id_inst_o <= if_inst_i; - id_pc_o <= if_pc_i; - excp_o <= excp_i; - excp_num_o <= excp_num_i; - end - end - -endmodule From 9775e913ad9588974b506dd31b0854505eb6be5f Mon Sep 17 00:00:00 2001 From: Easton Man Date: Wed, 4 May 2022 22:36:32 +0800 Subject: [PATCH 063/114] docs: add frontend design & priority tips --- README.md | 1 + doc/frontend.md | 9 +++++++++ doc/verilog_tips.md | 5 +++++ 3 files changed, 15 insertions(+) create mode 100644 doc/frontend.md diff --git a/README.md b/README.md index 053d30d..0fc9a11 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ testbench.cpp 用于Verilator仿真,如果使用Vivado仿真,无 ## 设计文档 +- [前端设计](doc/frontend.md) - [译码器设计](doc/instr_decode.md) - [差分测试](doc/difftest.md) - [AXI控制器](src/vsrc/AXI/README.md) diff --git a/doc/frontend.md b/doc/frontend.md new file mode 100644 index 0000000..92f940c --- /dev/null +++ b/doc/frontend.md @@ -0,0 +1,9 @@ +# 流水线前端设计 + +**目前实现的跳转不正确!!!** + +## ICache 信号 + +## Instruction Buffer 信号 + +## 后端信号 \ No newline at end of file diff --git a/doc/verilog_tips.md b/doc/verilog_tips.md index cc4bb29..234b199 100644 --- a/doc/verilog_tips.md +++ b/doc/verilog_tips.md @@ -6,3 +6,8 @@ 虽然看起来是一个系统调用,但是由于实在是过于好用,大部分的仿真和综合工具都支持处理这个函数。 +## always块中最后一个赋值覆盖前面的 + +这很有用,如果想要实现带有优先级的组合逻辑,可以避免使用超级长的if-else判断,而是利用越后面的赋值优先级越高来代替if-else + +当然,这可能带来高的延迟。 \ No newline at end of file From 6ce4f3a670635cd31055f8c0b7420c65bfb2af3e Mon Sep 17 00:00:00 2001 From: Easton Man Date: Thu, 5 May 2022 09:46:02 +0800 Subject: [PATCH 064/114] fix: fix include --- src/vsrc/cpu_top.sv | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/vsrc/cpu_top.sv b/src/vsrc/cpu_top.sv index db7d49e..96bd03c 100644 --- a/src/vsrc/cpu_top.sv +++ b/src/vsrc/cpu_top.sv @@ -1,6 +1,5 @@ `include "defines.v" `include "instr_info.sv" -`include "pc_reg.v" `include "regfile.v" `include "csr_defines.v" `include "cs_reg.v" @@ -9,8 +8,6 @@ `include "AXI/axi_master.v" `include "frontend/frontend.sv" `include "instr_buffer.sv" -`include "pipeline/1_fetch/if_buffer.v" -`include "pipeline/1_fetch/if_id.v" `include "pipeline/2_decode/id.v" `include "pipeline/2_decode/id_ex.v" `include "pipeline/3_execution/ex.v" From 9263a9a11865652e20d66d33870c8b7e3227f6fb Mon Sep 17 00:00:00 2001 From: Easton Man Date: Fri, 6 May 2022 10:36:18 +0800 Subject: [PATCH 065/114] fix: fix include --- src/vsrc/cpu_top.sv | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/vsrc/cpu_top.sv b/src/vsrc/cpu_top.sv index 96bd03c..0101f92 100644 --- a/src/vsrc/cpu_top.sv +++ b/src/vsrc/cpu_top.sv @@ -8,6 +8,9 @@ `include "AXI/axi_master.v" `include "frontend/frontend.sv" `include "instr_buffer.sv" +`include "dummy_icache.sv" +`include "LLbit_reg.v" +`include "ctrl.v" `include "pipeline/2_decode/id.v" `include "pipeline/2_decode/id_ex.v" `include "pipeline/3_execution/ex.v" From 15bd9f8999cd0519afe104aa01a6232c870c1211 Mon Sep 17 00:00:00 2001 From: Rookie-rookie-rookie <292601787@qq.com> Date: Fri, 6 May 2022 10:41:40 +0800 Subject: [PATCH 066/114] connect ib and backend --- .vscode/settings.json | 3 +- src/{SimTop.v => SimTop.sv} | 4 +- src/{SimTop_tb.v => SimTop_tb.sv} | 2 +- src/{data_ram.v => data_ram.sv} | 2 +- src/{ram.v => ram.sv} | 2 +- .../AXI/{axi_defines.v => axi_defines.sv} | 0 src/vsrc/AXI/{axi_master.v => axi_master.sv} | 2 +- src/vsrc/BPU/btb.sv | 2 +- src/vsrc/{LLbit_reg.v => LLbit_reg.sv} | 2 +- src/vsrc/cpu_top.sv | 859 ++++++++---------- src/vsrc/{cs_reg.v => cs_reg.sv} | 28 +- src/vsrc/{csr_defines.v => csr_defines.sv} | 9 +- src/vsrc/{ctrl.v => ctrl.sv} | 2 +- src/vsrc/{defines.v => defines.sv} | 16 +- src/vsrc/dummy_icache.sv | 2 +- src/vsrc/instr_info.sv | 2 +- src/vsrc/{pc_reg.v => pc_reg.sv} | 4 +- src/vsrc/pipeline/2_decode/{id.v => id.sv} | 143 +-- .../pipeline/2_decode/{id_ex.v => id_ex.sv} | 23 +- src/vsrc/pipeline/3_execution/{ex.v => ex.sv} | 111 ++- .../3_execution/{ex_mem.v => ex_mem.sv} | 59 +- src/vsrc/pipeline/4_mem/{mem.v => mem.sv} | 16 +- .../pipeline/4_mem/{mem_wb.v => mem_wb.sv} | 28 +- src/vsrc/{regfile.v => regfile.sv} | 2 +- src/vsrc/{tlb.v => tlb.sv} | 209 ++--- src/vsrc/{tlb_entry.v => tlb_entry.sv} | 0 26 files changed, 732 insertions(+), 800 deletions(-) rename src/{SimTop.v => SimTop.sv} (99%) rename src/{SimTop_tb.v => SimTop_tb.sv} (97%) rename src/{data_ram.v => data_ram.sv} (99%) rename src/{ram.v => ram.sv} (97%) rename src/vsrc/AXI/{axi_defines.v => axi_defines.sv} (100%) rename src/vsrc/AXI/{axi_master.v => axi_master.sv} (99%) rename src/vsrc/{LLbit_reg.v => LLbit_reg.sv} (95%) rename src/vsrc/{cs_reg.v => cs_reg.sv} (97%) rename src/vsrc/{csr_defines.v => csr_defines.sv} (94%) rename src/vsrc/{ctrl.v => ctrl.sv} (98%) rename src/vsrc/{defines.v => defines.sv} (95%) rename src/vsrc/{pc_reg.v => pc_reg.sv} (98%) rename src/vsrc/pipeline/2_decode/{id.v => id.sv} (93%) rename src/vsrc/pipeline/2_decode/{id_ex.v => id_ex.sv} (86%) rename src/vsrc/pipeline/3_execution/{ex.v => ex.sv} (71%) rename src/vsrc/pipeline/3_execution/{ex_mem.v => ex_mem.sv} (65%) rename src/vsrc/pipeline/4_mem/{mem.v => mem.sv} (96%) rename src/vsrc/pipeline/4_mem/{mem_wb.v => mem_wb.sv} (89%) rename src/vsrc/{regfile.v => regfile.sv} (99%) rename src/vsrc/{tlb.v => tlb.sv} (54%) rename src/vsrc/{tlb_entry.v => tlb_entry.sv} (100%) diff --git a/.vscode/settings.json b/.vscode/settings.json index 8f6f9d4..333845d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -18,5 +18,6 @@ ], "todo-tree.filtering.useBuiltInExcludes": "file and search excludes", "systemverilogFormatter.veribleBuild": "Ubuntu-20.04-focal-x86_64", - "systemverilogFormatter.commandLineArguments": "--indentation_spaces 4" + "systemverilogFormatter.commandLineArguments": "--indentation_spaces 4", + "editor.formatOnSave": true } \ No newline at end of file diff --git a/src/SimTop.v b/src/SimTop.sv similarity index 99% rename from src/SimTop.v rename to src/SimTop.sv index 80ecdf1..5126c13 100644 --- a/src/SimTop.v +++ b/src/SimTop.sv @@ -1,7 +1,7 @@ `timescale 1ns / 1ns -`include "vsrc/defines.v" -`include "ram.v" +`include "vsrc/defines.sv" +`include "ram.sv" module SimTop ( input clock, diff --git a/src/SimTop_tb.v b/src/SimTop_tb.sv similarity index 97% rename from src/SimTop_tb.v rename to src/SimTop_tb.sv index eecaaac..f6d12ee 100644 --- a/src/SimTop_tb.v +++ b/src/SimTop_tb.sv @@ -1,4 +1,4 @@ -`include "vsrc/defines.v" +`include "vsrc/defines.sv" `timescale 1ns/1ps module SimTop_tb(); diff --git a/src/data_ram.v b/src/data_ram.sv similarity index 99% rename from src/data_ram.v rename to src/data_ram.sv index 2ac2074..f901c82 100644 --- a/src/data_ram.v +++ b/src/data_ram.sv @@ -1,4 +1,4 @@ -`include "vsrc/defines.v" +`include "vsrc/defines.sv" module data_ram( input wire clk, diff --git a/src/ram.v b/src/ram.sv similarity index 97% rename from src/ram.v rename to src/ram.sv index 06378f5..f35fd2e 100644 --- a/src/ram.v +++ b/src/ram.sv @@ -1,4 +1,4 @@ -`include "vsrc/defines.v" +`include "vsrc/defines.sv" module ram ( input clock, diff --git a/src/vsrc/AXI/axi_defines.v b/src/vsrc/AXI/axi_defines.sv similarity index 100% rename from src/vsrc/AXI/axi_defines.v rename to src/vsrc/AXI/axi_defines.sv diff --git a/src/vsrc/AXI/axi_master.v b/src/vsrc/AXI/axi_master.sv similarity index 99% rename from src/vsrc/AXI/axi_master.v rename to src/vsrc/AXI/axi_master.sv index 5f8b1c8..32a2b11 100644 --- a/src/vsrc/AXI/axi_master.v +++ b/src/vsrc/AXI/axi_master.sv @@ -1,4 +1,4 @@ -`include "AXI/axi_defines.v" +`include "AXI/axi_defines.sv" module axi_master ( input wire aclk, input wire aresetn, //low is valid diff --git a/src/vsrc/BPU/btb.sv b/src/vsrc/BPU/btb.sv index 32f94fa..2b9e3cf 100644 --- a/src/vsrc/BPU/btb.sv +++ b/src/vsrc/BPU/btb.sv @@ -1,6 +1,6 @@ // Branch Target Buffer `include "branch_predictor/defines.sv" -`include "../defines.v" +`include "../defines.sv" module btb ( diff --git a/src/vsrc/LLbit_reg.v b/src/vsrc/LLbit_reg.sv similarity index 95% rename from src/vsrc/LLbit_reg.v rename to src/vsrc/LLbit_reg.sv index 79c554c..1d202d6 100644 --- a/src/vsrc/LLbit_reg.v +++ b/src/vsrc/LLbit_reg.sv @@ -1,4 +1,4 @@ -`include "defines.v" +`include "defines.sv" module LLbit_reg( input wire clk, input wire rst, diff --git a/src/vsrc/cpu_top.sv b/src/vsrc/cpu_top.sv index 96bd03c..97fc058 100644 --- a/src/vsrc/cpu_top.sv +++ b/src/vsrc/cpu_top.sv @@ -1,25 +1,25 @@ -`include "defines.v" +`include "defines.sv" `include "instr_info.sv" -`include "regfile.v" -`include "csr_defines.v" -`include "cs_reg.v" -`include "tlb.v" -`include "tlb_entry.v" -`include "AXI/axi_master.v" +`include "regfile.sv" +`include "csr_defines.sv" +`include "cs_reg.sv" +`include "tlb.sv" +`include "tlb_entry.sv" +`include "AXI/axi_master.sv" `include "frontend/frontend.sv" `include "instr_buffer.sv" -`include "pipeline/2_decode/id.v" -`include "pipeline/2_decode/id_ex.v" -`include "pipeline/3_execution/ex.v" -`include "pipeline/3_execution/ex_mem.v" -`include "pipeline/4_mem/mem.v" -`include "pipeline/4_mem/mem_wb.v" +`include "pipeline/2_decode/id.sv" +`include "pipeline/2_decode/id_ex.sv" +`include "pipeline/3_execution/ex.sv" +`include "pipeline/3_execution/ex_mem.sv" +`include "pipeline/4_mem/mem.sv" +`include "pipeline/4_mem/mem_wb.sv" module cpu_top ( - input wire aclk, - input wire aresetn, + input logic aclk, + input logic aresetn, - input wire [7:0] intrpt, // External interrupt + input logic [7:0] intrpt, // External interrupt // AXI interface // read request @@ -71,26 +71,26 @@ module cpu_top ( ); // Clock signal - wire clk; + logic clk; assign clk = aclk; // Reset signal - wire rst_n; - wire rst; + logic rst_n; + logic rst; assign rst_n = aresetn; assign rst = ~rst_n; // Global enable signal - wire chip_enable; + logic chip_enable; - wire branch_flag_1; - wire branch_flag_2; - wire Instram_branch_flag; + logic branch_flag_1; + logic branch_flag_2; + logic Instram_branch_flag; assign Instram_branch_flag = branch_flag_1 | branch_flag_2; - wire axi_busy; - wire [`RegBus] axi_data; - wire [`RegBus] axi_addr; + logic axi_busy; + logic [`RegBus] axi_data; + logic [`RegBus] axi_addr; axi_master u_axi_master ( .aclk (aclk), @@ -183,6 +183,7 @@ module cpu_top ( // Frontend <-> Instruction Buffer logic ib_frontend_stallreq; instr_buffer_info_t frontend_ib_instr_info[FETCH_WIDTH]; + logic [`RegBus] next_pc; frontend u_frontend ( .clk(clk), @@ -197,14 +198,17 @@ module cpu_top ( // <-> Backend .branch_update_info_i(), - .backend_next_pc_i (), - .backend_flush_i (), + .backend_next_pc_i (next_pc), + .backend_flush_i (backend_flush), // <-> Instruction Buffer .instr_buffer_stallreq_i(ib_frontend_stallreq), .instr_buffer_o (frontend_ib_instr_info) ); + logic backend_flush ; + instr_buffer_info_t backend_ib_instr_info[2]; + instr_buffer #( .IF_WIDTH(FETCH_WIDTH), .ID_WIDTH(2) // TODO: remove magic number @@ -218,220 +222,220 @@ module cpu_top ( // <-> Backend .backend_accept_i(2'b0), // FIXME: currently not accepting any instructions - .backend_flush_i (), - .backend_instr_o () + .backend_flush_i (backend_flush), + .backend_instr_o (backend_ib_instr_info) ); - wire [`RegBus] branch_target_address_1; - wire [`RegBus] branch_target_address_2; - wire [`RegBus] link_addr; - wire flush; - wire [`RegBus] new_pc; - wire [6:0] stall1; // [pc_reg,if_buffer_1, if_id, id_ex, ex_mem, mem_wb, ctrl] - wire [6:0] stall2; + logic [`RegBus] branch_target_address_1; + logic [`RegBus] branch_target_address_2; + logic [`RegBus] link_addr; + logic flush; + logic [`RegBus] new_pc; + logic [6:0] stall1; // [pc_reg,if_buffer_1, if_id, id_ex, ex_mem, mem_wb, ctrl] + logic [6:0] stall2; //tlb - wire inst_addr_trans_en; - wire data_addr_trans_en; - wire fetch_en; - wire [31:0] inst_vaddr; - wire inst_dmw0_en; - wire inst_dmw1_en; - wire [7:0] inst_index; - wire [19:0] inst_tag; - wire [3:0] inst_offset; - wire inst_tlb_found; - wire inst_tlb_v; - wire inst_tlb_d; - wire [1:0] inst_tlb_mat; - wire [1:0] inst_tlb_plv; - wire data_fetch; - wire [31:0] data_vaddr; - wire data_dmw0_en; - wire data_dmw1_en; - wire cacop_op_mode_di; - wire [7:0] data_index; - wire [19:0] data_tag; - wire [3:0] data_offset; - wire data_tlb_found; - wire [4:0] data_tlb_index; - wire data_tlb_v; - wire data_tlb_d; - wire [1:0] data_tlb_mat; - wire [1:0] data_tlb_plv; - wire tlbfill_en; - wire tlbwr_en; - wire [4:0] rand_index; - wire [31:0] tlbw_tlbehi; - wire [31:0] tlbw_tlbelo0; - wire [31:0] tlbw_tlbelo1; - wire [31:0] tlbw_r_tlbidx; - wire [5:0] tlbw_ecode; - wire [31:0] tlbr_tlbehi; - wire [31:0] tlbr_tlbelo0; - wire [31:0] tlbr_tlbelo1; - wire [31:0] tlbr_tlbidx; - wire [9:0] tlbr_asid; - wire invtlb_en; - wire [9:0] invtlb_asid; - wire [18:0] invtlb_vpn; - wire [4:0] invtlb_op; + logic inst_addr_trans_en; + logic data_addr_trans_en; + logic fetch_en; + logic [31:0] inst_vaddr; + logic inst_dmw0_en; + logic inst_dmw1_en; + logic [7:0] inst_index; + logic [19:0] inst_tag; + logic [3:0] inst_offset; + logic inst_tlb_found; + logic inst_tlb_v; + logic inst_tlb_d; + logic [1:0] inst_tlb_mat; + logic [1:0] inst_tlb_plv; + logic data_fetch; + logic [31:0] data_vaddr; + logic data_dmw0_en; + logic data_dmw1_en; + logic cacop_op_mode_di; + logic [7:0] data_index; + logic [19:0] data_tag; + logic [3:0] data_offset; + logic data_tlb_found; + logic [4:0] data_tlb_index; + logic data_tlb_v; + logic data_tlb_d; + logic [1:0] data_tlb_mat; + logic [1:0] data_tlb_plv; + logic tlbfill_en; + logic tlbwr_en; + logic [4:0] rand_index; + logic [31:0] tlbw_tlbehi; + logic [31:0] tlbw_tlbelo0; + logic [31:0] tlbw_tlbelo1; + logic [31:0] tlbw_r_tlbidx; + logic [5:0] tlbw_ecode; + logic [31:0] tlbr_tlbehi; + logic [31:0] tlbr_tlbelo0; + logic [31:0] tlbr_tlbelo1; + logic [31:0] tlbr_tlbidx; + logic [9:0] tlbr_asid; + logic invtlb_en; + logic [9:0] invtlb_asid; + logic [18:0] invtlb_vpn; + logic [4:0] invtlb_op; //csr - wire has_int; - wire excp_flush; - wire ertn_flush; - wire wb_csr_en; - wire [13:0] wb_csr_addr; - wire [31:0] wb_csr_data; - wire [31:0] wb_csr_era; - wire [8:0] wb_csr_esubcode; - wire [5:0] wb_csr_ecode; - wire wb_va_error; - wire [31:0] wb_bad_va; - wire tlbsrch_en; - wire tlbsrch_found; - wire [4:0] tlbsrch_index; - wire excp_tlbrefill; - wire excp_tlb; - wire [18:0] excp_tlb_vppn; - wire csr_llbit_i; - wire csr_llbit_set_i; - wire csr_llbit_o; - wire csr_llbit_set_o; - wire [`RegBus] csr_eentry; - wire [31:0] csr_tlbrentry; - wire [`RegBus] csr_era; - - wire [9:0] csr_asid; - wire csr_pg; - wire csr_da; - wire [31:0] csr_dmw0; - wire [31:0] csr_dmw1; - wire [1:0] csr_datf; - wire [1:0] csr_datm; - wire [1:0] csr_plv; - - wire [13:0] id_csr_addr_1; - wire [31:0] id_csr_data_1; - wire [13:0] id_csr_addr_2; - wire [31:0] id_csr_data_2; - wire [`RegBus] id_csr_data_o_1; - wire [`RegBus] id_csr_data_o_2; - wire id_csr_we_1; - wire id_csr_we_2; - wire [13:0] id_csr_addr_o_1; - wire [13:0] id_csr_addr_o_2; - wire [13:0] id_csr_read_addr_o_1; - wire [13:0] id_csr_read_addr_o_2; - - wire pc_excp_o; - wire [3:0] pc_excp_num_o; - - wire idle_flush; - wire [`InstAddrBus] idle_pc; - wire excp_flush_1; - wire ertn_flush_1; - wire excp_flush_2; - wire ertn_flush_2; + logic has_int; + logic excp_flush; + logic ertn_flush; + logic [31:0] wb_csr_era; + logic [8:0] wb_csr_esubcode; + logic [5:0] wb_csr_ecode; + logic wb_va_error; + logic [31:0] wb_bad_va; + logic tlbsrch_en; + logic tlbsrch_found; + logic [4:0] tlbsrch_index; + logic excp_tlbrefill; + logic excp_tlb; + logic [18:0] excp_tlb_vppn; + logic csr_llbit_i; + logic csr_llbit_set_i; + logic csr_llbit_o; + logic csr_llbit_set_o; + logic [`RegBus] csr_eentry; + logic [31:0] csr_tlbrentry; + logic [`RegBus] csr_era; + + logic [9:0] csr_asid; + logic csr_pg; + logic csr_da; + logic [31:0] csr_dmw0; + logic [31:0] csr_dmw1; + logic [1:0] csr_datf; + logic [1:0] csr_datm; + logic [1:0] csr_plv; + + logic [13:0] id_csr_addr_1; + logic [31:0] id_csr_data_1; + logic [13:0] id_csr_addr_2; + logic [31:0] id_csr_data_2; + logic [13:0] id_csr_read_addr_o_1; + logic [13:0] id_csr_read_addr_o_2; + + logic pc_excp_o; + logic [3:0] pc_excp_num_o; + + logic idle_flush; + logic [`InstAddrBus] idle_pc; + logic excp_flush_1; + logic ertn_flush_1; + logic excp_flush_2; + logic ertn_flush_2; assign excp_flush = excp_flush_1 | excp_flush_2; assign ertn_flush = ertn_flush_1 | ertn_flush_2; - wire [`RegBus] id_csr_data_i_1; - wire [`RegBus] id_csr_data_i_2; + logic [`RegBus] id_csr_data_i_1; + logic [`RegBus] id_csr_data_i_2; + + logic disable_cache; - wire disable_cache; + assign backend_flush = excp_flush | ertn_flush | branch_flag_1 | branch_flag_2; + assign next_pc = branch_flag_1 ? branch_target_address_1 : + branch_flag_2 ? branch_target_address_2 : + (excp_flush && !excp_tlbrefill) ? csr_eentry : + (excp_flush && excp_tlbrefill) ? csr_tlbrentry : + ertn_flush ? csr_era : `ZeroWord; - wire if_inst_valid_1; - wire if_inst_valid_2; - wire if_excp_i_1; - wire [3:0] if_excp_num_i_1; - wire if_excp_i_2; - wire [3:0] if_excp_num_i_2; + logic if_inst_valid_1; + logic if_inst_valid_2; + logic if_excp_i_1; + logic [3:0] if_excp_num_i_1; + logic if_excp_i_2; + logic [3:0] if_excp_num_i_2; - wire [`InstAddrBus] id_pc_1; - wire [`InstBus] id_inst_1; - wire [`InstAddrBus] id_pc_2; - wire [`InstBus] id_inst_2; + logic [`InstAddrBus] id_pc_1; + logic [`InstBus] id_inst_1; + logic [`InstAddrBus] id_pc_2; + logic [`InstBus] id_inst_2; - wire if_excp_o_1; - wire [3:0] if_excp_num_o_1; - wire if_excp_o_2; - wire [3:0] if_excp_num_o_2; + logic if_excp_o_1; + logic [3:0] if_excp_num_o_1; + logic if_excp_o_2; + logic [3:0] if_excp_num_o_2; - wire [`AluOpBus] id_aluop_1; - wire [`AluSelBus] id_alusel_1; - wire [`RegBus] id_reg1_1; - wire [`RegBus] id_reg2_1; - wire [`RegAddrBus] id_reg_waddr_1; - wire id_wreg_1; - wire id_inst_valid_1; - wire [`InstAddrBus] id_inst_pc_1; - wire [`RegBus] id_inst_o_1; + logic [`AluOpBus] id_aluop_1; + logic [`AluSelBus] id_alusel_1; + logic [`RegBus] id_reg1_1; + logic [`RegBus] id_reg2_1; + logic [`RegAddrBus] id_reg_waddr_1; + logic id_wreg_1; + logic id_inst_valid_1; + logic [`InstAddrBus] id_inst_pc_1; + logic [`RegBus] id_inst_o_1; - wire reg1_read_1; - wire reg2_read_1; - wire [`RegAddrBus] reg1_addr_1; - wire [`RegAddrBus] reg2_addr_1; - wire [`RegBus] reg1_data_1; - wire [`RegBus] reg2_data_1; + logic reg1_read_1; + logic reg2_read_1; + logic [`RegAddrBus] reg1_addr_1; + logic [`RegAddrBus] reg2_addr_1; + logic [`RegBus] reg1_data_1; + logic [`RegBus] reg2_data_1; - wire ex_wreg_o_1; - wire [`RegAddrBus] ex_reg_waddr_o_1; - wire [`RegBus] ex_reg_wdata_1; - wire [`AluOpBus] ex_aluop_o_1; + logic ex_wreg_o_1; + logic [`RegAddrBus] ex_reg_waddr_o_1; + logic [`RegBus] ex_reg_wdata_1; + logic [`AluOpBus] ex_aluop_o_1; - wire mem_wreg_o_1; - wire [`RegAddrBus] mem_reg_waddr_o_1; - wire [`RegBus] mem_reg_wdata_o_1; + logic mem_wreg_o_1; + logic [`RegAddrBus] mem_reg_waddr_o_1; + logic [`RegBus] mem_reg_wdata_o_1; - wire stallreq_from_id_1; - wire stallreq_from_ex_1; + logic stallreq_from_id_1; + logic stallreq_from_ex_1; - wire [1:0] id_excepttype_o_1; - wire [`RegBus] id_current_inst_address_o_1; + logic [1:0] id_excepttype_o_1; + logic [`RegBus] id_current_inst_address_o_1; - wire ex_wreg_o_2; - wire [`RegAddrBus] ex_reg_waddr_o_2; - wire [`RegBus] ex_reg_wdata_2; - wire [`AluOpBus] ex_aluop_o_2; + logic ex_wreg_o_2; + logic [`RegAddrBus] ex_reg_waddr_o_2; + logic [`RegBus] ex_reg_wdata_2; + logic [`AluOpBus] ex_aluop_o_2; - wire mem_wreg_o_2; - wire [`RegAddrBus] mem_reg_waddr_o_2; - wire [`RegBus] mem_reg_wdata_o_2; + logic mem_wreg_o_2; + logic [`RegAddrBus] mem_reg_waddr_o_2; + logic [`RegBus] mem_reg_wdata_o_2; - wire [`RegAddrBus] reg1_addr_2; - wire [`RegAddrBus] reg2_addr_2; + logic [`RegAddrBus] reg1_addr_2; + logic [`RegAddrBus] reg2_addr_2; - wire [`RegBus] link_addr_1; - wire [`RegBus] link_addr_2; + logic [`RegBus] link_addr_1; + logic [`RegBus] link_addr_2; - wire [`RegAddrBus] id_reg_waddr_2; + logic [`RegAddrBus] id_reg_waddr_2; - wire stallreq_to_next_1; - wire stallreq_to_next_2; + logic stallreq_to_next_1; + logic stallreq_to_next_2; - wire id_excp_o_1; - wire [8:0] id_excp_num_o_1; - wire id_excp_o_2; - wire [8:0] id_excp_num_o_2; + logic id_excp_o_1; + logic [8:0] id_excp_num_o_1; + logic id_excp_o_2; + logic [8:0] id_excp_num_o_2; + + csr_write_signal id_csr_signal_o_1; + csr_write_signal id_csr_signal_o_2; id u_id_1 ( .rst(rst), - .pc_i(id_pc_1), - .inst_i(id_inst_1), + .instr_buffer_i(backend_ib_instr_info[0]), - .pc_i_other(pc_buffer_2), + .instr_buffer_i_other(backend_ib_instr_info[1]), .reg1_data_i(reg1_data_1), .reg2_data_i(reg2_data_1), @@ -469,9 +473,7 @@ module cpu_top ( .inst_valid (id_inst_valid_1), .inst_pc (id_inst_pc_1), .inst_o (id_inst_o_1), - .csr_we (id_csr_we_1), - .csr_addr_o (id_csr_addr_o_1), - .csr_data_o (id_csr_data_o_1), + .csr_signal_o(id_csr_signal_o_1), .csr_read_addr_o(id_csr_read_addr_o_1), .csr_data_i(id_csr_data_1), @@ -490,41 +492,39 @@ module cpu_top ( .stallreq(stallreq_to_next_1), .idle_stallreq(), - .excepttype_o(id_excepttype_o_1), .current_inst_address_o(id_current_inst_address_o_1) ); - wire [`AluOpBus] id_aluop_2; - wire [`AluSelBus] id_alusel_2; - wire [`RegBus] id_reg1_2; - wire [`RegBus] id_reg2_2; + logic [`AluOpBus] id_aluop_2; + logic [`AluSelBus] id_alusel_2; + logic [`RegBus] id_reg1_2; + logic [`RegBus] id_reg2_2; - wire id_wreg_2; - wire id_inst_valid_2; - wire [`InstAddrBus] id_inst_pc_2; - wire [`RegBus] id_inst_o_2; + logic id_wreg_2; + logic id_inst_valid_2; + logic [`InstAddrBus] id_inst_pc_2; + logic [`RegBus] id_inst_o_2; - wire reg1_read_2; - wire reg2_read_2; - wire [`RegBus] reg1_data_2; - wire [`RegBus] reg2_data_2; + logic reg1_read_2; + logic reg2_read_2; + logic [`RegBus] reg1_data_2; + logic [`RegBus] reg2_data_2; - wire stallreq_from_id_2; - wire stallreq_from_ex_2; + logic stallreq_from_id_2; + logic stallreq_from_ex_2; - wire [1:0] id_excepttype_o_2; - wire [`RegBus] id_current_inst_address_o_2; + logic [1:0] id_excepttype_o_2; + logic [`RegBus] id_current_inst_address_o_2; id u_id_2 ( .rst(rst), - .pc_i(id_pc_2), - .inst_i(id_inst_2), + .instr_buffer_i(backend_ib_instr_info[1]), - .pc_i_other(pc_buffer_1), + .instr_buffer_i_other(backend_ib_instr_info[0]), .reg1_data_i(reg1_data_2), .reg2_data_i(reg2_data_2), @@ -563,12 +563,10 @@ module cpu_top ( .inst_pc (id_inst_pc_2), .inst_o (id_inst_o_2), - .csr_we(id_csr_we_2), - .csr_addr_o(id_csr_addr_o_2), + .csr_signal_o(id_csr_signal_o_2), .csr_data_i(id_csr_data_2), .csr_read_addr_o(id_csr_read_addr_o_2), - .csr_data_o(id_csr_data_o_2), .has_int(has_int), .csr_plv(csr_plv), @@ -584,31 +582,29 @@ module cpu_top ( .stallreq(stallreq_to_next_2), .idle_stallreq(), - .excepttype_o(id_excepttype_o_2), .current_inst_address_o(id_current_inst_address_o_2) ); - wire [`AluOpBus] ex_aluop_1; - wire [`AluSelBus] ex_alusel_1; - wire [`RegBus] ex_reg1_1; - wire [`RegBus] ex_reg2_1; - wire [`RegAddrBus] ex_reg_waddr_i_1; - wire ex_wreg_i_1; - wire ex_inst_valid_i_1; - wire [`InstAddrBus] ex_inst_pc_i_1; - wire [`RegBus] ex_link_address_1; - wire [`RegBus] ex_inst_i_1; - wire [1:0] ex_excepttype_i_1; - wire [`RegBus] ex_current_inst_address_i_1; - wire ex_csr_we_i_1; - wire [13:0] ex_csr_addr_i_1; - wire [31:0] ex_csr_data_i_1; - - wire ex_excp_i_1; - wire [8:0] ex_excp_num_i_1; - wire ex_excp_o_1; - wire [8:0] ex_excp_num_i_2; + logic [`AluOpBus] ex_aluop_1; + logic [`AluSelBus] ex_alusel_1; + logic [`RegBus] ex_reg1_1; + logic [`RegBus] ex_reg2_1; + logic [`RegAddrBus] ex_reg_waddr_i_1; + logic ex_wreg_i_1; + logic ex_inst_valid_i_1; + logic [`InstAddrBus] ex_inst_pc_i_1; + logic [`RegBus] ex_link_address_1; + logic [`RegBus] ex_inst_i_1; + logic [1:0] ex_excepttype_i_1; + logic [`RegBus] ex_current_inst_address_i_1; + csr_write_signal ex_csr_signal_i_1; + csr_write_signal ex_csr_signal_i_2; + + logic ex_excp_i_1; + logic [8:0] ex_excp_num_i_1; + logic ex_excp_o_1; + logic [8:0] ex_excp_num_i_2; id_ex id_ex_1 ( .clk (clk), @@ -628,9 +624,7 @@ module cpu_top ( .flush(flush), .id_excepttype(id_excepttype_o_1), .id_current_inst_address(id_current_inst_address_o_1), - .id_csr_we(id_csr_we_1), - .id_csr_addr(id_csr_addr_o_1), - .id_csr_data(id_csr_data_o_1), + .id_csr_signal_o(id_csr_signal_o_1), .ex_aluop(ex_aluop_1), .ex_alusel(ex_alusel_1), @@ -644,9 +638,7 @@ module cpu_top ( .ex_inst(ex_inst_i_1), .ex_excepttype(ex_excepttype_i_1), .ex_current_inst_address(ex_current_inst_address_i_1), - .ex_csr_we(ex_csr_we_i_1), - .ex_csr_addr(ex_csr_addr_i_1), - .ex_csr_data(ex_csr_data_i_1), + .ex_csr_signal_i(ex_csr_signal_i_1), .reg1_addr_i(reg1_addr_1), .reg2_addr_i(reg2_addr_1), @@ -667,26 +659,26 @@ module cpu_top ( .ertn_flush(ertn_flush) ); - wire [`AluOpBus] ex_aluop_2; - wire [`AluSelBus] ex_alusel_2; - wire [`RegBus] ex_reg1_2; - wire [`RegBus] ex_reg2_2; - wire [`RegAddrBus] ex_reg_waddr_i_2; - wire ex_wreg_i_2; - wire ex_inst_valid_i_2; - wire [`InstAddrBus] ex_inst_pc_i_2; - wire [`RegBus] ex_link_address_2; - wire [`RegBus] ex_inst_i_2; - wire [1:0] ex_excepttype_i_2; - wire [`RegBus] ex_current_inst_address_i_2; - wire ex_csr_we_i_2; - wire [13:0] ex_csr_addr_i_2; - wire [31:0] ex_csr_data_i_2; - - wire ex_excp_i_2; - wire [9:0] ex_excp_num_o_1; - wire ex_excp_o_2; - wire [9:0] ex_excp_num_o_2; + logic [`AluOpBus] ex_aluop_2; + logic [`AluSelBus] ex_alusel_2; + logic [`RegBus] ex_reg1_2; + logic [`RegBus] ex_reg2_2; + logic [`RegAddrBus] ex_reg_waddr_i_2; + logic ex_wreg_i_2; + logic ex_inst_valid_i_2; + logic [`InstAddrBus] ex_inst_pc_i_2; + logic [`RegBus] ex_link_address_2; + logic [`RegBus] ex_inst_i_2; + logic [1:0] ex_excepttype_i_2; + logic [`RegBus] ex_current_inst_address_i_2; + logic ex_csr_we_i_2; + logic [13:0] ex_csr_addr_i_2; + logic [31:0] ex_csr_data_i_2; + + logic ex_excp_i_2; + logic [9:0] ex_excp_num_o_1; + logic ex_excp_o_2; + logic [9:0] ex_excp_num_o_2; id_ex id_ex_2 ( .clk (clk), @@ -706,9 +698,7 @@ module cpu_top ( .flush(flush), .id_excepttype(id_excepttype_o_2), .id_current_inst_address(id_current_inst_address_o_2), - .id_csr_we(id_csr_we_2), - .id_csr_addr(id_csr_addr_o_2), - .id_csr_data(id_csr_data_o_2), + .id_csr_signal_o(id_csr_signal_o_2), .ex_aluop(ex_aluop_2), .ex_alusel(ex_alusel_2), @@ -722,9 +712,7 @@ module cpu_top ( .ex_inst(ex_inst_i_2), .ex_excepttype(ex_excepttype_i_2), .ex_current_inst_address(ex_current_inst_address_i_2), - .ex_csr_we(ex_csr_we_i_2), - .ex_csr_addr(ex_csr_addr_i_2), - .ex_csr_data(ex_csr_data_i_2), + .ex_csr_signal_i(ex_csr_signal_i_2), .reg1_addr_i(reg1_addr_2), .reg2_addr_i(reg2_addr_2), @@ -746,15 +734,14 @@ module cpu_top ( ); - wire ex_inst_valid_o_1; - wire [`InstAddrBus] ex_inst_pc_o_1; - wire [`RegBus] ex_addr_o_1; - wire [`RegBus] ex_reg2_o_1; - wire [1:0] ex_excepttype_o_1; - wire [`RegBus] ex_current_inst_address_o_1; - wire ex_csr_we_o_1; - wire [13:0] ex_csr_addr_o_1; - wire [31:0] ex_csr_data_o_1; + logic ex_inst_valid_o_1; + logic [`InstAddrBus] ex_inst_pc_o_1; + logic [`RegBus] ex_addr_o_1; + logic [`RegBus] ex_reg2_o_1; + logic [1:0] ex_excepttype_o_1; + logic [`RegBus] ex_current_inst_address_o_1; + csr_write_signal ex_csr_signal_o_1; + csr_write_signal ex_csr_signal_o_2; @@ -773,13 +760,9 @@ module cpu_top ( .link_addr_i(ex_link_address_1), .excepttype_i(ex_excepttype_i_1), .current_inst_address_i(ex_current_inst_address_i_1), - .ex_csr_we_i(ex_csr_we_i_1), - .ex_csr_addr_i(ex_csr_addr_i_1), - .ex_csr_data_i(ex_csr_data_i_1), + .csr_signal_i(ex_csr_signal_i_1), - .wd_o(ex_reg_waddr_o_1), - .wreg_o(ex_wreg_o_1), - .wdata_o(ex_reg_wdata_1), + .write_signal_o(), .inst_valid_o(ex_inst_valid_o_1), .inst_pc_o(ex_inst_pc_o_1), .aluop_o(ex_aluop_o_1), @@ -787,9 +770,7 @@ module cpu_top ( .reg2_o(ex_reg2_o_1), .excepttype_o(ex_excepttype_o_1), .current_inst_address_o(ex_current_inst_address_o_1), - .ex_csr_we_o(ex_csr_we_o_1), - .ex_csr_addr_o(ex_csr_addr_o_1), - .ex_csr_data_o(ex_csr_data_o_1), + .csr_signal_o(ex_csr_signal_o_1), .stallreq(stallreq_from_ex_1), @@ -799,15 +780,15 @@ module cpu_top ( .excp_num_o(ex_excp_num_o_1) ); - wire ex_inst_valid_o_2; - wire [`InstAddrBus] ex_inst_pc_o_2; - wire [`RegBus] ex_addr_o_2; - wire [`RegBus] ex_reg2_o_2; - wire [1:0] ex_excepttype_o_2; - wire [`RegBus] ex_current_inst_address_o_2; - wire ex_csr_we_o_2; - wire [13:0] ex_csr_addr_o_2; - wire [31:0] ex_csr_data_o_2; + logic ex_inst_valid_o_2; + logic [`InstAddrBus] ex_inst_pc_o_2; + logic [`RegBus] ex_addr_o_2; + logic [`RegBus] ex_reg2_o_2; + logic [1:0] ex_excepttype_o_2; + logic [`RegBus] ex_current_inst_address_o_2; + logic ex_csr_we_o_2; + logic [13:0] ex_csr_addr_o_2; + logic [31:0] ex_csr_data_o_2; ex u_ex_2 ( @@ -825,13 +806,9 @@ module cpu_top ( .link_addr_i(ex_link_address_2), .excepttype_i(ex_excepttype_i_2), .current_inst_address_i(ex_current_inst_address_i_2), - .ex_csr_we_i(ex_csr_we_i_2), - .ex_csr_addr_i(ex_csr_addr_i_2), - .ex_csr_data_i(ex_csr_data_i_2), + .csr_signal_i(ex_csr_signal_i_2), - .wd_o(ex_reg_waddr_o_2), - .wreg_o(ex_wreg_o_2), - .wdata_o(ex_reg_wdata_2), + .write_signal_o(), .inst_valid_o(ex_inst_valid_o_2), .inst_pc_o(ex_inst_pc_o_2), .aluop_o(ex_aluop_o_2), @@ -839,9 +816,7 @@ module cpu_top ( .reg2_o(ex_reg2_o_2), .excepttype_o(ex_excepttype_o_2), .current_inst_address_o(ex_current_inst_address_o_2), - .ex_csr_we_o(ex_csr_we_o_2), - .ex_csr_addr_o(ex_csr_addr_o_2), - .ex_csr_data_o(ex_csr_data_o_2), + .csr_signal_o(ex_csr_signal_o_2), .stallreq(stallreq_from_ex_2), @@ -852,27 +827,26 @@ module cpu_top ( ); - wire mem_wreg_i_1; - wire [`RegAddrBus] mem_reg_waddr_i_1; - wire [`RegBus] mem_reg_wdata_i_1; + logic mem_wreg_i_1; + logic [`RegAddrBus] mem_reg_waddr_i_1; + logic [`RegBus] mem_reg_wdata_i_1; - wire mem_inst_valid_1; - wire [`InstAddrBus] mem_inst_pc_1; + logic mem_inst_valid_1; + logic [`InstAddrBus] mem_inst_pc_1; - wire [`AluOpBus] mem_aluop_i_1; - wire [`RegBus] mem_addr_i_1; - wire [`RegBus] mem_reg2_i_1; - wire [1:0] mem_excepttype_i_1; - wire [`RegBus] mem_current_inst_address_i_1; + logic [`AluOpBus] mem_aluop_i_1; + logic [`RegBus] mem_addr_i_1; + logic [`RegBus] mem_reg2_i_1; + logic [1:0] mem_excepttype_i_1; + logic [`RegBus] mem_current_inst_address_i_1; - wire mem_csr_we_i_1; - wire [13:0] mem_csr_addr_i_1; - wire [31:0] mem_csr_data_i_1; + csr_write_signal mem_csr_signal_i_1; + csr_write_signal mem_csr_signal_i_2; - wire mem_excp_i_1; - wire [9:0] mem_excp_num_i_1; - wire mem_excp_i_2; - wire [9:0] mem_excp_num_i_2; + logic mem_excp_i_1; + logic [9:0] mem_excp_num_i_1; + logic mem_excp_i_2; + logic [9:0] mem_excp_num_i_2; ex_mem u_ex_mem_1 ( .clk (clk), @@ -890,9 +864,7 @@ module cpu_top ( .flush (flush), .ex_excepttype (ex_excepttype_o_1), .ex_current_inst_address(ex_current_inst_address_o_1), - .ex_csr_we (ex_csr_we_o_1), - .ex_csr_addr (ex_csr_addr_o_1), - .ex_csr_data (ex_csr_data_o_1), + .ex_csr_signal_o(ex_csr_signal_o_1), .mem_wd (mem_reg_waddr_i_1), .mem_wreg (mem_wreg_i_1), @@ -904,9 +876,7 @@ module cpu_top ( .mem_reg2 (mem_reg2_i_1), .mem_excepttype (mem_excepttype_i_1), .mem_current_inst_address(mem_current_inst_address_i_1), - .mem_csr_we (mem_csr_we_i_1), - .mem_csr_addr (mem_csr_addr_i_1), - .mem_csr_data (mem_csr_data_i_1), + .mem_csr_signal_i(mem_csr_signal_i_1), .excp_i(ex_excp_o_1), .excp_num_i(ex_excp_num_o_1), @@ -919,21 +889,21 @@ module cpu_top ( ); - wire mem_wreg_i_2; - wire [`RegAddrBus] mem_reg_waddr_i_2; - wire [`RegBus] mem_reg_wdata_i_2; + logic mem_wreg_i_2; + logic [`RegAddrBus] mem_reg_waddr_i_2; + logic [`RegBus] mem_reg_wdata_i_2; - wire mem_inst_valid_2; - wire [`InstAddrBus] mem_inst_pc_2; + logic mem_inst_valid_2; + logic [`InstAddrBus] mem_inst_pc_2; - wire [`AluOpBus] mem_aluop_i_2; - wire [`RegBus] mem_addr_i_2; - wire [`RegBus] mem_reg2_i_2; - wire [1:0] mem_excepttype_i_2; - wire [`RegBus] mem_current_inst_address_i_2; - wire mem_csr_we_i_2; - wire [13:0] mem_csr_addr_i_2; - wire [31:0] mem_csr_data_i_2; + logic [`AluOpBus] mem_aluop_i_2; + logic [`RegBus] mem_addr_i_2; + logic [`RegBus] mem_reg2_i_2; + logic [1:0] mem_excepttype_i_2; + logic [`RegBus] mem_current_inst_address_i_2; + logic mem_csr_we_i_2; + logic [13:0] mem_csr_addr_i_2; + logic [31:0] mem_csr_data_i_2; ex_mem u_ex_mem_2 ( @@ -952,9 +922,7 @@ module cpu_top ( .flush (flush), .ex_excepttype (ex_excepttype_o_2), .ex_current_inst_address(ex_current_inst_address_o_2), - .ex_csr_we (ex_csr_we_o_1), - .ex_csr_addr (ex_csr_addr_o_1), - .ex_csr_data (ex_csr_data_o_1), + .ex_csr_signal_o(ex_csr_signal_o_2), .mem_wd (mem_reg_waddr_i_2), .mem_wreg (mem_wreg_i_2), @@ -966,9 +934,7 @@ module cpu_top ( .mem_reg2 (mem_reg2_i_2), .mem_excepttype (mem_excepttype_i_2), .mem_current_inst_address(mem_current_inst_address_i_2), - .mem_csr_we (mem_csr_we_i_2), - .mem_csr_addr (mem_csr_addr_i_2), - .mem_csr_data (mem_csr_data_i_2), + .mem_csr_signal_i(mem_csr_signal_i_2), .excp_i(ex_excp_o_2), .excp_num_i(ex_excp_num_o_2), @@ -980,34 +946,33 @@ module cpu_top ( ); - wire LLbit_o_1; - wire wb_LLbit_we_i_1; - wire wb_LLbit_value_i_1; - wire mem_LLbit_we_o_1; - wire mem_LLbit_value_o_1; - wire [1:0] mem_excepttype_o_1; - wire [1:0] mem_excepttype_o_2; - wire [`RegBus] mem_current_inst_address_o_1; - wire [`InstAddrBus] wb_inst_pc_1; - wire mem_csr_we_o_1; - wire [13:0] mem_csr_addr_o_1; - wire [31:0] mem_csr_data_o_1; + logic LLbit_o_1; + logic wb_LLbit_we_i_1; + logic wb_LLbit_value_i_1; + logic mem_LLbit_we_o_1; + logic mem_LLbit_value_o_1; + logic [1:0] mem_excepttype_o_1; + logic [1:0] mem_excepttype_o_2; + logic [`RegBus] mem_current_inst_address_o_1; + logic [`InstAddrBus] wb_inst_pc_1; + csr_write_signal mem_csr_signal_o_1; + csr_write_signal mem_csr_signal_o_2; - wire mem_excp_o_1; - wire [15:0] mem_excp_num_o_1; - wire mem_excp_o_2; - wire [15:0] mem_excp_num_o_2; + logic mem_excp_o_1; + logic [15:0] mem_excp_num_o_1; + logic mem_excp_o_2; + logic [15:0] mem_excp_num_o_2; - wire [`AluOpBus] mem_aluop_o_1; - wire [`AluOpBus] mem_aluop_o_2; + logic [`AluOpBus] mem_aluop_o_1; + logic [`AluOpBus] mem_aluop_o_2; - wire data_addr_trans_en_1; - wire data_dmw0_en_1; - wire data_dmw1_en_1; + logic data_addr_trans_en_1; + logic data_dmw0_en_1; + logic data_dmw1_en_1; - wire data_addr_trans_en_2; - wire data_dmw0_en_2; - wire data_dmw1_en_2; + logic data_addr_trans_en_2; + logic data_dmw0_en_2; + logic data_dmw1_en_2; @@ -1031,9 +996,7 @@ module cpu_top ( .excepttype_i(mem_excepttype_i_1), .current_inst_address_i(mem_current_inst_address_i_1), - .mem_csr_we_i (mem_csr_we_i_1), - .mem_csr_addr_i(mem_csr_addr_i_1), - .mem_csr_data_i(mem_csr_data_i_1), + .csr_signal_i(mem_csr_signal_i_1), .inst_pc_o(wb_inst_pc_1), .wd_o (mem_reg_waddr_o_1), @@ -1053,9 +1016,7 @@ module cpu_top ( .excepttype_o(mem_excepttype_o_1), .current_inst_address_o(mem_current_inst_address_o_1), - .mem_csr_we_o (mem_csr_we_o_1), - .mem_csr_addr_o(mem_csr_addr_o_1), - .mem_csr_data_o(mem_csr_data_o_1), + .csr_signal_o(mem_csr_signal_o_1), .excp_i(mem_excp_i_1), .excp_num_i(mem_excp_num_i_1), @@ -1084,16 +1045,16 @@ module cpu_top ( ); - wire LLbit_o_2; - wire wb_LLbit_we_i_2; - wire wb_LLbit_value_i_2; - wire mem_LLbit_we_o_2; - wire mem_LLbit_value_o_2; - wire [`RegBus] mem_current_inst_address_o_2; - wire [`InstAddrBus] wb_inst_pc_2; - wire mem_csr_we_o_2; - wire [13:0] mem_csr_addr_o_2; - wire [31:0] mem_csr_data_o_2; + logic LLbit_o_2; + logic wb_LLbit_we_i_2; + logic wb_LLbit_value_i_2; + logic mem_LLbit_we_o_2; + logic mem_LLbit_value_o_2; + logic [`RegBus] mem_current_inst_address_o_2; + logic [`InstAddrBus] wb_inst_pc_2; + logic mem_csr_we_o_2; + logic [13:0] mem_csr_addr_o_2; + logic [31:0] mem_csr_data_o_2; @@ -1117,9 +1078,7 @@ module cpu_top ( .excepttype_i(mem_excepttype_i_2), .current_inst_address_i(mem_current_inst_address_i_2), - .mem_csr_we_i (mem_csr_we_i_2), - .mem_csr_addr_i(mem_csr_addr_i_2), - .mem_csr_data_i(mem_csr_data_i_2), + .csr_signal_i(mem_csr_signal_i_2), .inst_pc_o(wb_inst_pc_2), .wd_o (mem_reg_waddr_o_2), @@ -1139,9 +1098,7 @@ module cpu_top ( .excepttype_o(mem_excepttype_o_2), .current_inst_address_o(mem_current_inst_address_o_2), - .mem_csr_we_o (mem_csr_we_o_2), - .mem_csr_addr_o(mem_csr_addr_o_2), - .mem_csr_data_o(mem_csr_data_o_2), + .csr_signal_o(mem_csr_signal_o_2), .excp_i(mem_excp_i_2), .excp_num_i(mem_excp_num_i_2), @@ -1173,32 +1130,34 @@ module cpu_top ( assign dram_pc_o_1 = wb_inst_pc_1; assign dram_pc_o_2 = wb_inst_pc_2; - wire wb_wreg_1; - wire [`RegAddrBus] wb_reg_waddr_1; - wire [`RegBus] wb_reg_wdata_1; + logic wb_wreg_1; + logic [`RegAddrBus] wb_reg_waddr_1; + logic [`RegBus] wb_reg_wdata_1; + + logic wb_csr_we_1; + logic [13:0] wb_csr_addr_1; + logic [`RegBus] wb_csr_data_1; - wire wb_csr_we_1; - wire [13:0] wb_csr_addr_1; - wire [`RegBus] wb_csr_data_1; + logic [8:0] wb_csr_esubcode_1; + logic [5:0] wb_csr_ecode_1; assign debug0_wb_rf_wen = wb_wreg_1; assign debug0_wb_rf_wnum = wb_reg_waddr_1; assign debug0_wb_rf_wdata = wb_reg_wdata_1; - wire wb_excp_o_1; - wire [15:0] wb_excp_num_o_1; - wire wb_excp_o_2; - wire [15:0] wb_excp_num_o_2; + logic wb_excp_o_1; + logic [15:0] wb_excp_num_o_1; + logic wb_excp_o_2; + logic [15:0] wb_excp_num_o_2; - wire [`RegBus] wb_csr_era_1; - wire [8:0] wb_csr_esubcode_1; - wire [5:0] wb_csr_ecode_1; + csr_write_signal wb_csr_signal_o_1; + csr_write_signal wb_csr_signal_o_2; - wire wb_va_error_1; - wire [`RegBus] wb_bad_va_1; - wire excp_tlbrefill_1; - wire [18:0] excp_tlb_vppn_1; + logic wb_va_error_1; + logic [`RegBus] wb_bad_va_1; + logic excp_tlbrefill_1; + logic [18:0] excp_tlb_vppn_1; mem_wb mem_wb_1 ( .clk (clk), @@ -1218,9 +1177,7 @@ module cpu_top ( .flush(flush), - .mem_csr_we (mem_csr_we_o_1), - .mem_csr_addr(mem_csr_addr_o_1), - .mem_csr_data(mem_csr_data_o_1), + .mem_csr_signal_o(mem_csr_signal_o_1), .wb_wd(wb_reg_waddr_1), .wb_wreg(wb_wreg_1), @@ -1229,9 +1186,6 @@ module cpu_top ( .wb_LLbit_we(wb_LLbit_we_i_1), .wb_LLbit_value(wb_LLbit_value_i_1), - .wb_csr_we (wb_csr_we_1), - .wb_csr_addr(wb_csr_addr_1), - .wb_csr_data(wb_csr_data_1), .debug_commit_pc (debug_commit_pc_1), .debug_commit_valid(debug_commit_valid_1), @@ -1242,9 +1196,7 @@ module cpu_top ( .excp_o(wb_excp_o_1), .excp_num_o(wb_excp_num_o_1), - .csr_era(wb_csr_era_1), - .csr_esubcode(wb_csr_esubcode_1), - .csr_ecode(wb_csr_ecode_1), + .wb_csr_signal_o(wb_csr_signal_o_1), .excp_flush(excp_flush_1), .ertn_flush(ertn_flush_1), .va_error(wb_va_error_1), @@ -1253,26 +1205,27 @@ module cpu_top ( .excp_tlb_vppn(excp_tlb_vppn_1) ); - wire wb_wreg_2; - wire [`RegAddrBus] wb_reg_waddr_2; - wire [`RegBus] wb_reg_wdata_2; + logic wb_wreg_2; + logic [`RegAddrBus] wb_reg_waddr_2; + logic [`RegBus] wb_reg_wdata_2; - wire wb_csr_we_2; - wire [13:0] wb_csr_addr_2; - wire [`RegBus] wb_csr_data_2; + logic wb_csr_we_2; + logic [13:0] wb_csr_addr_2; + logic [`RegBus] wb_csr_data_2; assign debug_commit_wreg_2 = wb_wreg_2; assign debug_commit_reg_waddr_2 = wb_reg_waddr_2; assign debug_commit_reg_wdata_2 = wb_reg_wdata_2; - wire [`RegBus] wb_csr_era_2; - wire [8:0] wb_csr_esubcode_2; - wire [5:0] wb_csr_ecode_2; + logic [`RegBus] wb_csr_era_2; + logic [8:0] wb_csr_esubcode_2; + logic [5:0] wb_csr_ecode_2; - wire wb_va_error_2; - wire [`RegBus] wb_bad_va_2; - wire excp_tlbrefill_2; - wire [18:0] excp_tlb_vppn_2; + logic wb_va_error_2; + logic [`RegBus] wb_bad_va_2; + logic excp_tlbrefill_2; + logic [18:0] excp_tlb_vppn_2; + logic wb_csr_era_1; mem_wb mem_wb_2 ( .clk (clk), @@ -1292,9 +1245,7 @@ module cpu_top ( .flush(flush), - .mem_csr_we (mem_csr_we_o_2), - .mem_csr_addr(mem_csr_addr_o_2), - .mem_csr_data(mem_csr_data_o_2), + .mem_csr_signal_o(mem_csr_signal_o_2), .wb_wd(wb_reg_waddr_2), .wb_wreg(wb_wreg_2), @@ -1303,9 +1254,7 @@ module cpu_top ( .wb_LLbit_we(wb_LLbit_we_i), .wb_LLbit_value(wb_LLbit_value_2), - .wb_csr_we (wb_csr_we_2), - .wb_csr_addr(wb_csr_addr_2), - .wb_csr_data(wb_csr_data_2), + .wb_csr_signal_o(wb_csr_signal_o_2), .debug_commit_pc (debug_commit_pc_2), .debug_commit_valid(debug_commit_valid_2), @@ -1395,14 +1344,10 @@ module cpu_top ( cs_reg u_cs_reg ( .clk(clk), .rst(rst), - .waddr_1(wb_csr_addr_1), - .waddr_2(wb_csr_addr_2), .excp_flush(excp_flush), .ertn_flush(ertn_flush), - .we_1(wb_csr_we_1), - .we_2(wb_csr_we_2), - .wdata_1(wb_csr_data_1), - .wdata_2(wb_csr_data_2), + .write_signal_1(wb_csr_signal_o_1), + .write_signal_2(wb_csr_signal_o_2), .raddr_1(id_csr_read_addr_o_1), .raddr_2(id_csr_read_addr_o_2), .rdata_1(id_csr_data_1), @@ -1449,7 +1394,7 @@ module cpu_top ( assign data_dmw1_en = data_dmw1_en_1 | data_dmw1_en_2; tlb u_tlb ( - .clk (clk), + .clk (), .asid (csr_asid), //trans mode .inst_addr_trans_en(inst_addr_trans_en), diff --git a/src/vsrc/cs_reg.v b/src/vsrc/cs_reg.sv similarity index 97% rename from src/vsrc/cs_reg.v rename to src/vsrc/cs_reg.sv index 06d8770..6fd0cd4 100644 --- a/src/vsrc/cs_reg.v +++ b/src/vsrc/cs_reg.sv @@ -1,17 +1,13 @@ `timescale 1ns/1ns -`include "defines.v" -`include "csr_defines.v" +`include "defines.sv" +`include "csr_defines.sv" module cs_reg ( input wire clk, input wire rst, - input wire we_1, - input wire[13:0] waddr_1, - input wire[`RegBus] wdata_1, - input wire we_2, - input wire[13:0] waddr_2, - input wire[`RegBus] wdata_2, + input csr_write_signal write_signal_1, + input csr_write_signal write_signal_2, input wire excp_flush, @@ -123,15 +119,15 @@ always @(*) begin waddr = 14'b0; wdata = `ZeroWord; end - else if(we_1 == 1'b1)begin - we = we_1; - waddr = waddr_1; - wdata = wdata_1; + else if(write_signal_1.we == 1'b1)begin + we = write_signal_1.we; + waddr = write_signal_1.addr; + wdata = write_signal_1.data; end - else if(we_2 == 1'b1)begin - we = we_2; - waddr = waddr_2; - wdata = wdata_2; + else if(write_signal_2.we == 1'b1)begin + we = write_signal_2.we; + waddr = write_signal_2.addr; + wdata = write_signal_2.data; end else begin we = 1'b0; diff --git a/src/vsrc/csr_defines.v b/src/vsrc/csr_defines.sv similarity index 94% rename from src/vsrc/csr_defines.v rename to src/vsrc/csr_defines.sv index e46151d..adf2077 100644 --- a/src/vsrc/csr_defines.v +++ b/src/vsrc/csr_defines.sv @@ -126,4 +126,11 @@ `define ECODE_TLBR 6'h3f `define ESUBCODE_ADEF 9'h0 -`define ESUBCODE_ADEM 9'h1 \ No newline at end of file +`define ESUBCODE_ADEM 9'h1 + + +typedef struct packed { + logic we; + logic [13:0] addr; + logic [31:0] data; +}csr_write_signal; \ No newline at end of file diff --git a/src/vsrc/ctrl.v b/src/vsrc/ctrl.sv similarity index 98% rename from src/vsrc/ctrl.v rename to src/vsrc/ctrl.sv index 4f13760..79f95f1 100644 --- a/src/vsrc/ctrl.v +++ b/src/vsrc/ctrl.sv @@ -1,4 +1,4 @@ -`include "defines.v" +`include "defines.sv" module ctrl ( input wire clk, input wire rst, diff --git a/src/vsrc/defines.v b/src/vsrc/defines.sv similarity index 95% rename from src/vsrc/defines.v rename to src/vsrc/defines.sv index ddc4ef2..78d1a69 100644 --- a/src/vsrc/defines.v +++ b/src/vsrc/defines.sv @@ -57,9 +57,9 @@ `define EXE_SPECIAL 6'b000001 `define EXE_CSR_RELATED 6'b00???? `define EXE_OTHER 6'b100100 -`define EXE_CSRRD 8'b00000100 -`define EXE_CSRWR 8'b00000100 -`define EXE_CSRXCHG 8'b00000100 +`define EXE_CSRRD 5'b00000 +`define EXE_CSRWR 5'b00001 +`define EXE_CSRXCHG 5'b00011 `define EXE_TLB_RELATED 5'b10000 `define EXE_IDLE 17'b00000110010010001 `define EXE_INVTLB 17'b00000110010010011 @@ -201,3 +201,13 @@ // SRAM latency `define CacheLatency 0 + +typedef struct packed { + logic we; + logic [`RegAddrBus] addr; + logic [`RegBus] data; +} reg_write_signal; +//tlb-compare-part +//typedef struct packed { + +//} tlb_com_part; diff --git a/src/vsrc/dummy_icache.sv b/src/vsrc/dummy_icache.sv index 27b2479..deb3eb0 100644 --- a/src/vsrc/dummy_icache.sv +++ b/src/vsrc/dummy_icache.sv @@ -1,4 +1,4 @@ -`include "defines.v" +`include "defines.sv" /* dummy_icache * hold output until AXI returns value diff --git a/src/vsrc/instr_info.sv b/src/vsrc/instr_info.sv index a9f0f4c..0a2f1dd 100644 --- a/src/vsrc/instr_info.sv +++ b/src/vsrc/instr_info.sv @@ -1,7 +1,7 @@ // Instruction info define `ifndef INSTR_INFO_SV `define INSTR_INFO_SV -`include "defines.v" +`include "defines.sv" typedef struct packed { bit valid; diff --git a/src/vsrc/pc_reg.v b/src/vsrc/pc_reg.sv similarity index 98% rename from src/vsrc/pc_reg.v rename to src/vsrc/pc_reg.sv index f1d5563..0cc871c 100644 --- a/src/vsrc/pc_reg.v +++ b/src/vsrc/pc_reg.sv @@ -1,5 +1,5 @@ -`include "defines.v" -`include "csr_defines.v" +`include "defines.sv" +`include "csr_defines.sv" module pc_reg ( input wire clk, input wire rst, diff --git a/src/vsrc/pipeline/2_decode/id.v b/src/vsrc/pipeline/2_decode/id.sv similarity index 93% rename from src/vsrc/pipeline/2_decode/id.v rename to src/vsrc/pipeline/2_decode/id.sv index 668448e..3b4df71 100644 --- a/src/vsrc/pipeline/2_decode/id.v +++ b/src/vsrc/pipeline/2_decode/id.sv @@ -1,43 +1,44 @@ `timescale 1ns / 1ns -`include "defines.v" +`include "defines.sv" +`include "instr_info.sv" +`include "csr_defines.sv" module id ( - input wire rst, + input logic rst, // <- IF - input wire [`InstAddrBus] pc_i, - input wire [`InstBus] inst_i, - input wire excp_i, - input wire [3:0] excp_num_i, + input instr_buffer_info_t instr_buffer_i, + input logic excp_i, + input logic [3:0] excp_num_i, // <- Regfile - input wire [`RegBus] reg1_data_i, - input wire [`RegBus] reg2_data_i, + input logic [`RegBus] reg1_data_i, + input logic [`RegBus] reg2_data_i, - input wire [`InstAddrBus] pc_i_other, + input instr_buffer_info_t instr_buffer_i_other, // <- EXE - input wire ex_wreg_i_1, - input wire [`RegAddrBus] ex_waddr_i_1, - input wire [`RegBus] ex_wdata_i_1, - input wire [`AluOpBus] ex_aluop_i_1, + input logic ex_wreg_i_1, + input logic [`RegAddrBus] ex_waddr_i_1, + input logic [`RegBus] ex_wdata_i_1, + input logic [`AluOpBus] ex_aluop_i_1, // <- ANOTHER_EXE - input wire ex_wreg_i_2, - input wire [`RegAddrBus] ex_waddr_i_2, - input wire [`RegBus] ex_wdata_i_2, - input wire [`AluOpBus] ex_aluop_i_2, + input logic ex_wreg_i_2, + input logic [`RegAddrBus] ex_waddr_i_2, + input logic [`RegBus] ex_wdata_i_2, + input logic [`AluOpBus] ex_aluop_i_2, // <- Mem - input wire mem_wreg_i_1, - input wire [`RegAddrBus] mem_waddr_i_1, - input wire [`RegBus] mem_wdata_i_1, + input logic mem_wreg_i_1, + input logic [`RegAddrBus] mem_waddr_i_1, + input logic [`RegBus] mem_wdata_i_1, // <- ANOTHER_Mem - input wire mem_wreg_i_2, - input wire [`RegAddrBus] mem_waddr_i_2, - input wire [`RegBus] mem_wdata_i_2, + input logic mem_wreg_i_2, + input logic [`RegAddrBus] mem_waddr_i_2, + input logic [`RegBus] mem_wdata_i_2, // -> Regfile output reg reg1_read_o, @@ -54,20 +55,17 @@ module id ( output reg wreg_o, output reg inst_valid, output reg [`InstAddrBus] inst_pc, - output wire [`RegBus] inst_o, - output wire [`RegBus] current_inst_address_o, + output logic [`RegBus] inst_o, + output logic [`RegBus] current_inst_address_o, output reg csr_we, - output reg [13:0] csr_addr_o, - output reg [`RegBus] csr_data_o, - output wire [1:0] excepttype_o, - - output wire excp_o, - output wire [8:0] excp_num_o, + output csr_write_signal csr_signal_o, + output logic excp_o, + output logic [8:0] excp_num_o, // <- CSR - input wire has_int, - input wire [`RegBus] csr_data_i, - input wire [1:0] csr_plv, + input logic has_int, + input logic [`RegBus] csr_data_i, + input logic [1:0] csr_plv, // -> CSR output reg [13:0] csr_read_addr_o, @@ -79,35 +77,39 @@ module id ( output reg [`InstAddrBus] idle_pc, // ->Ctrl - output wire stallreq, + output logic stallreq, output reg idle_stallreq ); - wire [5:0] opcode_6 = inst_i[31:26]; - wire [6:0] opcode_7 = inst_i[31:25]; - wire [7:0] opcode_8 = inst_i[31:24]; - wire [9:0] opcode_10 = inst_i[31:22]; - wire [13:0] opcode_14 = inst_i[31:18]; - wire [16:0] opcode_17 = inst_i[31:15]; - wire [21:0] opcode_22 = inst_i[31:10]; - wire [4:0] imm_5 = inst_i[14:10]; - wire [9:0] imm_10 = inst_i[9:0]; - wire [13:0] imm_14 = inst_i[23:10]; - wire [15:0] imm_16 = inst_i[25:10]; - wire [11:0] imm_12 = inst_i[21:10]; - wire [19:0] imm_20 = inst_i[24:5]; - wire [4:0] op1; + logic [`InstAddrBus] pc_i = instr_buffer_i.valid ? instr_buffer_i.pc : `ZeroWord; + logic [`InstBus] inst_i = instr_buffer_i.valid ? instr_buffer_i.instr : `ZeroWord; + + + logic [5:0] opcode_6 = inst_i[31:26]; + logic [6:0] opcode_7 = inst_i[31:25]; + logic [7:0] opcode_8 = inst_i[31:24]; + logic [9:0] opcode_10 = inst_i[31:22]; + logic [13:0] opcode_14 = inst_i[31:18]; + logic [16:0] opcode_17 = inst_i[31:15]; + logic [21:0] opcode_22 = inst_i[31:10]; + logic [4:0] imm_5 = inst_i[14:10]; + logic [9:0] imm_10 = inst_i[9:0]; + logic [13:0] imm_14 = inst_i[23:10]; + logic [15:0] imm_16 = inst_i[25:10]; + logic [11:0] imm_12 = inst_i[21:10]; + logic [19:0] imm_20 = inst_i[24:5]; + logic [4:0] op1; assign op1 = inst_i[4:0]; - wire [4:0] op2 = inst_i[9:5]; - wire [4:0] op3 = inst_i[14:10]; - wire [4:0] op4 = inst_i[19:15]; + logic [4:0] op2 = inst_i[9:5]; + logic [4:0] op3 = inst_i[14:10]; + logic [4:0] op4 = inst_i[19:15]; - wire [5:0] opcode_1 = inst_i[31:26]; - wire [5:0] opcode_2 = inst_i[25:20]; - wire [4:0] opcode_3 = inst_i[19:15]; - wire [4:0] opcode_4 = inst_i[14:10]; + logic [5:0] opcode_1 = inst_i[31:26]; + logic [5:0] opcode_2 = inst_i[25:20]; + logic [4:0] opcode_3 = inst_i[19:15]; + logic [4:0] opcode_4 = inst_i[14:10]; - wire [`RegBus] pc_plus_4; + logic [`RegBus] pc_plus_4; assign pc_plus_4 = pc_i + 4; assign inst_o = inst_i; @@ -116,10 +118,12 @@ module id ( reg stallreq_for_reg1_loadrelate; reg stallreq_for_reg2_loadrelate; - wire pre_inst_is_load; + logic pre_inst_is_load; - reg res_from_csr; + logic res_from_csr; + logic excp_ine; + logic excp_ipe; assign pre_inst_is_load = (((ex_aluop_i_1 == `EXE_LD_B_OP) || (ex_aluop_i_1 == `EXE_LD_H_OP) || @@ -136,13 +140,14 @@ module id ( (ex_aluop_i_2 == `EXE_LD_HU_OP) || (ex_aluop_i_2 == `EXE_ST_B_OP) || (ex_aluop_i_2 == `EXE_ST_H_OP) || - (ex_aluop_i_2 == `EXE_ST_W_OP)) && (pc_i == pc_i_other + 4)) ? 1'b1 : 1'b0; + (ex_aluop_i_2 == `EXE_ST_W_OP)) && (pc_i == instr_buffer_i_other.pc + 4)) ? 1'b1 : 1'b0; reg inst_syscall; reg inst_break; reg kernel_inst; - assign excepttype_o = {inst_syscall, inst_break}; + + assign current_inst_address_o = pc_i; @@ -458,7 +463,9 @@ module id ( reg1_read_o = 1'b1; reg2_read_o = 1'b0; imm = {18'b0, imm_14}; - csr_addr_o = imm_14; + csr_signal_o.we = 1'b1; + csr_signal_o.addr = imm_14; + csr_signal_o.data = `ZeroWord; reg_waddr_o = op1; inst_valid = `InstValid; res_from_csr = 1'b1; @@ -470,8 +477,9 @@ module id ( reg1_read_o = 1'b1; reg2_read_o = 1'b0; imm = {18'b0, imm_14}; - csr_addr_o = imm_14; - csr_data_o = reg1_data_i; + csr_signal_o.we = 1'b1; + csr_signal_o.addr = imm_14; + csr_signal_o.data = reg1_data_i; reg1_addr_o = op1; reg_waddr_o = op1; inst_valid = `InstValid; @@ -484,8 +492,9 @@ module id ( reg1_read_o = 1'b0; reg2_read_o = 1'b0; imm = {18'b0, imm_14}; - csr_addr_o = imm_14; - csr_data_o = reg1_data_i; + csr_signal_o.we = 1'b1; + csr_signal_o.addr = imm_14; + csr_signal_o.data = reg1_data_i; reg_waddr_o = op1; inst_valid = `InstValid; res_from_csr = 1'b1; @@ -549,7 +558,7 @@ module id ( reg1_read_o = 1'b0; reg2_read_o = 1'b0; idle_stallreq = 1; - idle_pc = pc_i + 4'h4; + idle_pc = pc_i + 32'h4; inst_valid = `InstValid; kernel_inst = 1'b1; end diff --git a/src/vsrc/pipeline/2_decode/id_ex.v b/src/vsrc/pipeline/2_decode/id_ex.sv similarity index 86% rename from src/vsrc/pipeline/2_decode/id_ex.v rename to src/vsrc/pipeline/2_decode/id_ex.sv index 0178341..9154d67 100644 --- a/src/vsrc/pipeline/2_decode/id_ex.v +++ b/src/vsrc/pipeline/2_decode/id_ex.sv @@ -1,4 +1,5 @@ -`include "defines.v" +`include "defines.sv" +`include "csr_defines.sv" module id_ex ( input wire clk, input wire rst, @@ -19,9 +20,7 @@ module id_ex ( input wire flush, input wire [1:0] id_excepttype, input wire [`RegBus] id_current_inst_address, - input wire id_csr_we, - input wire [13:0] id_csr_addr, - input wire [`RegBus] id_csr_data, + input csr_write_signal id_csr_signal_o, output reg [`AluOpBus] ex_aluop, output reg [`AluSelBus] ex_alusel, @@ -35,9 +34,7 @@ module id_ex ( output reg [`RegBus] ex_inst, output reg [1:0] ex_excepttype, output reg [`RegBus] ex_current_inst_address, - output reg ex_csr_we, - output reg [13:0] ex_csr_addr, - output reg [`RegBus] ex_csr_data, + output csr_write_signal ex_csr_signal_i, input wire [ `RegAddrBus] reg1_addr_i, input wire [ `RegAddrBus] reg2_addr_i, @@ -79,9 +76,7 @@ module id_ex ( ex_inst <= `ZeroWord; ex_excepttype <= 2'b00; ex_current_inst_address <= `ZeroWord; - ex_csr_we <= 1'b0; - ex_csr_addr <= 14'b0; - ex_csr_data <= `ZeroWord; + ex_csr_signal_i <= 47'b0; excp_o <= 1'b0; excp_num_o <= 9'b0; end else if (flush == 1'b1 || excp_flush == 1'b1 || ertn_flush == 1'b1) begin @@ -97,9 +92,7 @@ module id_ex ( ex_inst <= `ZeroWord; ex_excepttype <= 2'b00; ex_current_inst_address <= `ZeroWord; - ex_csr_we <= 1'b0; - ex_csr_addr <= 14'b0; - ex_csr_data <= `ZeroWord; + ex_csr_signal_i <= 47'b0; excp_o <= 1'b0; excp_num_o <= 9'b0; end else @@ -118,9 +111,7 @@ module id_ex ( ex_inst <= id_inst; ex_excepttype <= id_excepttype; ex_current_inst_address <= id_current_inst_address; - ex_csr_we <= id_csr_we; - ex_csr_addr <= id_csr_addr; - ex_csr_data <= id_csr_data; + ex_csr_signal_i <= id_csr_signal_o; excp_o <= excp_i; excp_num_o <= excp_num_i; end diff --git a/src/vsrc/pipeline/3_execution/ex.v b/src/vsrc/pipeline/3_execution/ex.sv similarity index 71% rename from src/vsrc/pipeline/3_execution/ex.v rename to src/vsrc/pipeline/3_execution/ex.sv index d7050aa..7a0cbb1 100644 --- a/src/vsrc/pipeline/3_execution/ex.v +++ b/src/vsrc/pipeline/3_execution/ex.sv @@ -1,46 +1,41 @@ -`include "defines.v" +`include "defines.sv" +`include "csr_defines.sv" module ex ( - input wire rst, - - input wire [`AluOpBus] aluop_i, - input wire [`AluSelBus] alusel_i, - input wire [`RegBus] reg1_i, - input wire [`RegBus] reg2_i, - input wire [`RegAddrBus] wd_i, - input wire wreg_i, - input wire inst_valid_i, - input wire [`InstAddrBus] inst_pc_i, - input wire [`RegBus] inst_i, - input wire [`RegBus] link_addr_i, - input wire [1:0] excepttype_i, - input wire [`RegBus] current_inst_address_i, - input wire ex_csr_we_i, - input wire [13:0] ex_csr_addr_i, - input wire [`RegBus] ex_csr_data_i, - - input wire [18:0] csr_vppn, - - output reg [`RegAddrBus] wd_o, - output reg wreg_o, - output reg [`RegBus] wdata_o, + input logic rst, + + input logic [`AluOpBus] aluop_i, + input logic [`AluSelBus] alusel_i, + input logic [`RegBus] reg1_i, + input logic [`RegBus] reg2_i, + input logic [`RegAddrBus] wd_i, + input logic wreg_i, + input logic inst_valid_i, + input logic [`InstAddrBus] inst_pc_i, + input logic [`RegBus] inst_i, + input logic [`RegBus] link_addr_i, + input logic [1:0] excepttype_i, + input logic [`RegBus] current_inst_address_i, + input csr_write_signal csr_signal_i, + + input logic [18:0] csr_vppn, + + output reg_write_signal write_signal_o, output reg inst_valid_o, output reg [`InstAddrBus] inst_pc_o, - output wire [`AluOpBus] aluop_o, - output wire [`RegBus] mem_addr_o, - output wire [`RegBus] reg2_o, - output wire [1:0] excepttype_o, - output wire [`RegBus] current_inst_address_o, - output wire ex_csr_we_o, - output wire [13:0] ex_csr_addr_o, - output wire [`RegBus] ex_csr_data_o, - - output wire stallreq, - - input wire excp_i, - input wire [8:0] excp_num_i, - output wire excp_o, - output wire [9:0] excp_num_o + output logic [`AluOpBus] aluop_o, + output logic [`RegBus] mem_addr_o, + output logic [`RegBus] reg2_o, + output logic [1:0] excepttype_o, + output logic [`RegBus] current_inst_address_o, + output csr_write_signal csr_signal_o, + + output logic stallreq, + + input logic excp_i, + input logic [8:0] excp_num_i, + output logic excp_o, + output logic [9:0] excp_num_o ); reg [`RegBus] logicout; @@ -55,9 +50,11 @@ module ex ( assign excepttype_o = excepttype_i; assign current_inst_address_o = current_inst_address_i; - assign ex_csr_we_o = ex_csr_we_i; - assign ex_csr_addr_o = ex_csr_addr_i; - assign ex_csr_data_o = ex_csr_data_i; + + //写入csr的数据,对csrxchg指令进行掩码处理 + assign csr_signal_o.we = csr_signal_i.we; + assign csr_signal_o.addr = csr_signal_i.addr; + assign csr_signal_o.data = (aluop_i ==`EXE_CSRXCHG_OP) ?((reg1_i & reg2_i) | (~reg1_i & csr_signal_i.data)) : csr_signal_i.data; assign excp_o = excp_i || 1'b0; assign excp_num_o = {1'b0, excp_num_i}; @@ -110,10 +107,10 @@ module ex ( end //比较模块 - wire reg1_lt_reg2; - wire [`RegBus] reg2_i_mux; - wire [`RegBus] reg1_i_mux; - wire [`RegBus] result_compare; + logic reg1_lt_reg2; + logic [`RegBus] reg2_i_mux; + logic [`RegBus] reg1_i_mux; + logic [`RegBus] result_compare; assign reg2_i_mux = (aluop_i == `EXE_SLT_OP) ? {~reg2_i[`RegWidth-1], reg2_i[`RegWidth-2:0]} : reg2_i; // shifted encoding when signed comparison assign reg1_i_mux = (aluop_i == `EXE_SLT_OP) ? {~reg1_i[`RegWidth-1], reg1_i[`RegWidth-2:0]} : reg1_i; @@ -122,9 +119,9 @@ module ex ( //乘法模块 - wire [`RegBus] opdata1_mul; - wire [`RegBus] opdata2_mul; - wire [`DoubleRegBus] hilo_temp; + logic [`RegBus] opdata1_mul; + logic [`RegBus] opdata2_mul; + logic [`DoubleRegBus] hilo_temp; reg [`DoubleRegBus] mulres; assign opdata1_mul = (((aluop_i == `EXE_MUL_OP) || (aluop_i == `EXE_MULH_OP)) @@ -186,26 +183,26 @@ module ex ( end always @(*) begin - wd_o = wd_i; - wreg_o = wreg_i; + write_signal_o.addr = wd_i; + write_signal_o.we = wreg_i; case (alusel_i) `EXE_RES_LOGIC: begin - wdata_o = logicout; + write_signal_o.data = logicout; end `EXE_RES_SHIFT: begin - wdata_o = shiftout; + write_signal_o.data = shiftout; end `EXE_RES_MOVE: begin - wdata_o = moveout; + write_signal_o.data = moveout; end `EXE_RES_ARITH: begin - wdata_o = arithout; + write_signal_o.data = arithout; end `EXE_RES_JUMP: begin - wdata_o = link_addr_i; + write_signal_o.data = link_addr_i; end default: begin - wdata_o = `ZeroWord; + write_signal_o.data = `ZeroWord; end endcase end diff --git a/src/vsrc/pipeline/3_execution/ex_mem.v b/src/vsrc/pipeline/3_execution/ex_mem.sv similarity index 65% rename from src/vsrc/pipeline/3_execution/ex_mem.v rename to src/vsrc/pipeline/3_execution/ex_mem.sv index 6ce919d..7a645c4 100644 --- a/src/vsrc/pipeline/3_execution/ex_mem.v +++ b/src/vsrc/pipeline/3_execution/ex_mem.sv @@ -1,28 +1,27 @@ -`include "defines.v" +`include "defines.sv" +`include "csr_defines.sv" module ex_mem ( - input wire clk, - input wire rst, - input wire stall, - input wire excp_flush, - input wire ertn_flush, + input logic clk, + input logic rst, + input logic stall, + input logic excp_flush, + input logic ertn_flush, - input wire [`RegAddrBus] ex_wd, - input wire ex_wreg, - input wire [`RegBus] ex_wdata, - input wire ex_inst_valid, - input wire [`InstAddrBus] ex_inst_pc, - input wire [`AluOpBus] ex_aluop, - input wire [`RegBus] ex_mem_addr, - input wire [`RegBus] ex_reg2, - input wire flush, - input wire [1:0] ex_excepttype, - input wire [`RegBus] ex_current_inst_address, - input wire ex_csr_we, - input wire [13:0] ex_csr_addr, - input wire [`RegBus] ex_csr_data, - input wire excp_i, - input wire [9:0] excp_num_i, + input logic [`RegAddrBus] ex_wd, + input logic ex_wreg, + input logic [`RegBus] ex_wdata, + input logic ex_inst_valid, + input logic [`InstAddrBus] ex_inst_pc, + input logic [`AluOpBus] ex_aluop, + input logic [`RegBus] ex_mem_addr, + input logic [`RegBus] ex_reg2, + input logic flush, + input logic [1:0] ex_excepttype, + input logic [`RegBus] ex_current_inst_address, + input csr_write_signal ex_csr_signal_o, + input logic excp_i, + input logic [9:0] excp_num_i, output reg [`RegAddrBus] mem_wd, output reg mem_wreg, @@ -34,9 +33,7 @@ module ex_mem ( output reg [`RegBus] mem_reg2, output reg [1:0] mem_excepttype, output reg [`RegBus] mem_current_inst_address, - output reg mem_csr_we, - output reg [13:0] mem_csr_addr, - output reg [`RegBus] mem_csr_data, + output csr_write_signal mem_csr_signal_i, output reg excp_o, output reg [9:0] excp_num_o ); @@ -53,9 +50,7 @@ module ex_mem ( mem_reg2 <= `ZeroWord; mem_excepttype <= 2'b00; mem_current_inst_address <= `ZeroWord; - mem_csr_we <= 1'b1; - mem_csr_addr <= 14'b0; - mem_csr_data <= `ZeroWord; + mem_csr_signal_i <= 47'b0; excp_o <= 1'b0; excp_num_o <= 10'b0; end else if (flush == 1'b1 || excp_flush == 1'b1 || ertn_flush == 1'b1) begin @@ -69,9 +64,7 @@ module ex_mem ( mem_reg2 <= `ZeroWord; mem_excepttype <= 2'b00; mem_current_inst_address <= `ZeroWord; - mem_csr_we <= 1'b1; - mem_csr_addr <= 14'b0; - mem_csr_data <= `ZeroWord; + mem_csr_signal_i <= 47'b0; excp_o <= 1'b0; excp_num_o <= 10'b0; end else @@ -87,9 +80,7 @@ module ex_mem ( mem_reg2 <= ex_reg2; mem_excepttype <= ex_excepttype; mem_current_inst_address <= ex_current_inst_address; - mem_csr_we <= ex_csr_we; - mem_csr_addr <= ex_csr_addr; - mem_csr_data <= ex_csr_data; + mem_csr_signal_i <= ex_csr_signal_o; excp_o <= excp_i; excp_num_o <= excp_num_i; end diff --git a/src/vsrc/pipeline/4_mem/mem.v b/src/vsrc/pipeline/4_mem/mem.sv similarity index 96% rename from src/vsrc/pipeline/4_mem/mem.v rename to src/vsrc/pipeline/4_mem/mem.sv index 534aa1b..b63a9db 100644 --- a/src/vsrc/pipeline/4_mem/mem.v +++ b/src/vsrc/pipeline/4_mem/mem.sv @@ -1,7 +1,7 @@ `timescale 1ns / 1ns -`include "defines.v" -`include "csr_defines.v" +`include "defines.sv" +`include "csr_defines.sv" module mem ( input wire rst, @@ -23,9 +23,7 @@ module mem ( input wire [1:0] excepttype_i, input wire [`RegBus] current_inst_address_i, - input wire mem_csr_we_i, - input wire [13:0] mem_csr_addr_i, - input wire [`RegBus] mem_csr_data_i, + input csr_write_signal csr_signal_i, input wire excp_i, input wire [9:0] excp_num_i, @@ -71,9 +69,7 @@ module mem ( output wire [1:0] excepttype_o, output wire [`RegBus] current_inst_address_o, - output wire mem_csr_we_o, - output wire [13:0] mem_csr_addr_o, - output wire [`RegBus] mem_csr_data_o, + output csr_write_signal csr_signal_o, output wire excp_o, output wire [15:0] excp_num_o @@ -105,9 +101,7 @@ module mem ( assign excepttype_o = excepttype_i; assign current_inst_address_o = current_inst_address_i; - assign mem_csr_we_o = mem_csr_we_i; - assign mem_csr_addr_o = mem_csr_we_o; - assign mem_csr_data_o = mem_csr_data_i; + assign csr_signal_o = csr_signal_i; //addr dmw trans assign dmw0_en = ((csr_dmw0[`PLV0] && csr_plv == 2'd0) || (csr_dmw0[`PLV3] && csr_plv == 2'd3)) && (wdata_i[31:29] == csr_dmw0[`VSEG]); diff --git a/src/vsrc/pipeline/4_mem/mem_wb.v b/src/vsrc/pipeline/4_mem/mem_wb.sv similarity index 89% rename from src/vsrc/pipeline/4_mem/mem_wb.v rename to src/vsrc/pipeline/4_mem/mem_wb.sv index 61d381f..7199f0f 100644 --- a/src/vsrc/pipeline/4_mem/mem_wb.v +++ b/src/vsrc/pipeline/4_mem/mem_wb.sv @@ -1,5 +1,5 @@ -`include "csr_defines.v" -`include "defines.v" +`include "csr_defines.sv" +`include "defines.sv" module mem_wb ( input wire clk, @@ -21,17 +21,13 @@ module mem_wb ( input wire [15:0] excp_num, - input wire mem_csr_we, - input wire [13:0] mem_csr_addr, - input wire [`RegBus] mem_csr_data, + input csr_write_signal mem_csr_signal_o, output reg [`RegAddrBus] wb_wd, output reg wb_wreg, output reg [`RegBus] wb_wdata, - output reg wb_csr_we, - output reg [13:0] wb_csr_addr, - output reg [`RegBus] wb_csr_data, + output csr_write_signal wb_csr_signal_o, output reg [`InstAddrBus] debug_commit_pc, output reg debug_commit_valid, @@ -66,7 +62,7 @@ module mem_wb ( assign csr_era = mem_inst_pc; assign excp_flush = excp_i; - assign ertn_flush = mem_instr == `EXE_ERTN_OP; + assign ertn_flush = mem_aluop == `EXE_ERTN_OP; assign csr_ecode = excp_num[0] ? `ECODE_INT : excp_num[1] ? `ECODE_ADEF : excp_num[2] ? `ECODE_TLBR : excp_num[3] ? `ECODE_PIF : @@ -113,22 +109,18 @@ module mem_wb ( wb_valid <= 1'b0; wb_LLbit_we <= 1'b0; wb_LLbit_value <= 1'b0; - wb_csr_we <= 1'b0; - wb_csr_addr <= 14'b0; - wb_csr_data <= `ZeroWord; + wb_csr_signal_o <= 47'b0; debug_commit_instr <= `ZeroWord; debug_commit_pc <= `ZeroWord; debug_commit_valid <= `InstInvalid; - end else if (flush == 1'b1 || excp_i == 1'b1 || mem_instr == `EXE_ERTN_OP) begin + end else if (flush == 1'b1 || excp_i == 1'b1 || mem_aluop == `EXE_ERTN_OP) begin wb_wd <= `NOPRegAddr; wb_wreg <= `WriteDisable; wb_wdata <= `ZeroWord; wb_valid <= 1'b0; wb_LLbit_we <= 1'b0; wb_LLbit_value <= 1'b0; - wb_csr_we <= 1'b0; - wb_csr_addr <= 14'b0; - wb_csr_data <= `ZeroWord; + wb_csr_signal_o <= 47'b0; debug_commit_instr <= `ZeroWord; debug_commit_pc <= `ZeroWord; debug_commit_valid <= ~`InstInvalid; @@ -143,9 +135,7 @@ module mem_wb ( wb_valid <= 1'b1; wb_LLbit_we <= mem_LLbit_we; wb_LLbit_value <= mem_LLbit_value; - wb_csr_we <= mem_csr_we; - wb_csr_addr <= mem_csr_addr; - wb_csr_data <= mem_csr_data; + wb_csr_signal_o <= mem_csr_signal_o; debug_commit_pc <= mem_inst_pc; // debug_commit_pc <= debug_commit_pc_0; debug_commit_valid <= mem_inst_valid; diff --git a/src/vsrc/regfile.v b/src/vsrc/regfile.sv similarity index 99% rename from src/vsrc/regfile.v rename to src/vsrc/regfile.sv index 5e1a43f..85804bc 100644 --- a/src/vsrc/regfile.v +++ b/src/vsrc/regfile.sv @@ -1,4 +1,4 @@ -`include "defines.v" +`include "defines.sv" module regfile ( input wire clk, input wire rst, diff --git a/src/vsrc/tlb.v b/src/vsrc/tlb.sv similarity index 54% rename from src/vsrc/tlb.v rename to src/vsrc/tlb.sv index 1607935..1f339db 100644 --- a/src/vsrc/tlb.v +++ b/src/vsrc/tlb.sv @@ -1,121 +1,122 @@ -`include "defines.v" -`include "csr_defines.v" +`include "defines.sv" +`include "csr_defines.sv" module tlb #( parameter TLBNUM = 32 + ) ( - input wire clk , - input wire [ 9:0] asid , + input logic clk , + input logic [ 9:0] asid , //trans mode - input wire inst_addr_trans_en , - input wire data_addr_trans_en , + input logic inst_addr_trans_en , + input logic data_addr_trans_en , //inst addr trans - input wire inst_fetch , - input wire [31:0] inst_vaddr , - input wire inst_dmw0_en , - input wire inst_dmw1_en , - output wire [ 7:0] inst_index , - output wire [19:0] inst_tag , - output wire [ 3:0] inst_offset , - output wire inst_tlb_found , - output wire inst_tlb_v , - output wire inst_tlb_d , - output wire [ 1:0] inst_tlb_mat , - output wire [ 1:0] inst_tlb_plv , + input logic inst_fetch , + input logic [31:0] inst_vaddr , + input logic inst_dmw0_en , + input logic inst_dmw1_en , + output logic [ 7:0] inst_index , + output logic [19:0] inst_tag , + output logic [ 3:0] inst_offset , + output logic inst_tlb_found , + output logic inst_tlb_v , + output logic inst_tlb_d , + output logic [ 1:0] inst_tlb_mat , + output logic [ 1:0] inst_tlb_plv , //data addr trans - input wire data_fetch , - input wire [31:0] data_vaddr , - input wire data_dmw0_en , - input wire data_dmw1_en , - input wire cacop_op_mode_di , - output wire [ 7:0] data_index , - output wire [19:0] data_tag , - output wire [ 3:0] data_offset , - output wire data_tlb_found , - output wire [ 4:0] data_tlb_index , - output wire data_tlb_v , - output wire data_tlb_d , - output wire [ 1:0] data_tlb_mat , - output wire [ 1:0] data_tlb_plv , + input logic data_fetch , + input logic [31:0] data_vaddr , + input logic data_dmw0_en , + input logic data_dmw1_en , + input logic cacop_op_mode_di , + output logic [ 7:0] data_index , + output logic [19:0] data_tag , + output logic [ 3:0] data_offset , + output logic data_tlb_found , + output logic [ 4:0] data_tlb_index , + output logic data_tlb_v , + output logic data_tlb_d , + output logic [ 1:0] data_tlb_mat , + output logic [ 1:0] data_tlb_plv , //tlbwi tlbwr tlb write - input wire tlbfill_en , - input wire tlbwr_en , - input wire [ 4:0] rand_index , - input wire [31:0] tlbehi_in , - input wire [31:0] tlbelo0_in , - input wire [31:0] tlbelo1_in , - input wire [31:0] tlbidx_in , - input wire [ 5:0] ecode_in , + input logic tlbfill_en , + input logic tlbwr_en , + input logic [ 4:0] rand_index , + input logic [31:0] tlbehi_in , + input logic [31:0] tlbelo0_in , + input logic [31:0] tlbelo1_in , + input logic [31:0] tlbidx_in , + input logic [ 5:0] ecode_in , //tlbr tlb read - output wire [31:0] tlbehi_out , - output wire [31:0] tlbelo0_out , - output wire [31:0] tlbelo1_out , - output wire [31:0] tlbidx_out , - output wire [ 9:0] asid_out , + output logic [31:0] tlbehi_out , + output logic [31:0] tlbelo0_out , + output logic [31:0] tlbelo1_out , + output logic [31:0] tlbidx_out , + output logic [ 9:0] asid_out , //invtlb - input wire invtlb_en , - input wire [ 9:0] invtlb_asid , - input wire [18:0] invtlb_vpn , - input wire [ 4:0] invtlb_op , + input logic invtlb_en , + input logic [ 9:0] invtlb_asid , + input logic [18:0] invtlb_vpn , + input logic [ 4:0] invtlb_op , //from csr - input wire [31:0] csr_dmw0 , - input wire [31:0] csr_dmw1 , - input wire csr_da , - input wire csr_pg + input logic [31:0] csr_dmw0 , + input logic [31:0] csr_dmw1 , + input logic csr_da , + input logic csr_pg ); -wire [18:0] s0_vppn ; -wire s0_odd_page ; -wire [ 5:0] s0_ps ; -wire [19:0] s0_ppn ; - -wire [18:0] s1_vppn ; -wire s1_odd_page ; -wire [ 5:0] s1_ps ; -wire [19:0] s1_ppn ; - -wire we ; -wire [ 4:0] w_index ; -wire [18:0] w_vppn ; -wire w_g ; -wire [ 5:0] w_ps ; -wire w_e ; -wire w_v0 ; -wire w_d0 ; -wire [ 1:0] w_mat0 ; -wire [ 1:0] w_plv0 ; -wire [19:0] w_ppn0 ; -wire w_v1 ; -wire w_d1 ; -wire [ 1:0] w_mat1 ; -wire [ 1:0] w_plv1 ; -wire [19:0] w_ppn1 ; - -wire [ 4:0] r_index ; -wire [18:0] r_vppn ; -wire [ 9:0] r_asid ; -wire r_g ; -wire [ 5:0] r_ps ; -wire r_e ; -wire r_v0 ; -wire r_d0 ; -wire [ 1:0] r_mat0 ; -wire [ 1:0] r_plv0 ; -wire [19:0] r_ppn0 ; -wire r_v1 ; -wire r_d1 ; -wire [ 1:0] r_mat1 ; -wire [ 1:0] r_plv1 ; -wire [19:0] r_ppn1 ; - -reg [31:0] inst_vaddr_buffer ; -reg [31:0] data_vaddr_buffer ; -wire [31:0] inst_paddr; -wire [31:0] data_paddr; - -wire pg_mode; -wire da_mode; +logic [18:0] s0_vppn ; +logic s0_odd_page ; +logic [ 5:0] s0_ps ; +logic [19:0] s0_ppn ; + +logic [18:0] s1_vppn ; +logic s1_odd_page ; +logic [ 5:0] s1_ps ; +logic [19:0] s1_ppn ; + +logic we ; +logic [ 4:0] w_index ; +logic [18:0] w_vppn ; +logic w_g ; +logic [ 5:0] w_ps ; +logic w_e ; +logic w_v0 ; +logic w_d0 ; +logic [ 1:0] w_mat0 ; +logic [ 1:0] w_plv0 ; +logic [19:0] w_ppn0 ; +logic w_v1 ; +logic w_d1 ; +logic [ 1:0] w_mat1 ; +logic [ 1:0] w_plv1 ; +logic [19:0] w_ppn1 ; + +logic [ 4:0] r_index ; +logic [18:0] r_vppn ; +logic [ 9:0] r_asid ; +logic r_g ; +logic [ 5:0] r_ps ; +logic r_e ; +logic r_v0 ; +logic r_d0 ; +logic [ 1:0] r_mat0 ; +logic [ 1:0] r_plv0 ; +logic [19:0] r_ppn0 ; +logic r_v1 ; +logic r_d1 ; +logic [ 1:0] r_mat1 ; +logic [ 1:0] r_plv1 ; +logic [19:0] r_ppn1 ; + +logic [31:0] inst_vaddr_buffer ; +logic [31:0] data_vaddr_buffer ; +logic [31:0] inst_paddr; +logic [31:0] data_paddr; + +logic pg_mode; +logic da_mode; always @(posedge clk) begin inst_vaddr_buffer <= inst_vaddr; diff --git a/src/vsrc/tlb_entry.v b/src/vsrc/tlb_entry.sv similarity index 100% rename from src/vsrc/tlb_entry.v rename to src/vsrc/tlb_entry.sv From ddaf55bb77a6cfefa3a6545a49e769a1b9aa189d Mon Sep 17 00:00:00 2001 From: Easton Man Date: Fri, 6 May 2022 10:59:45 +0800 Subject: [PATCH 067/114] fix: fix ff without rst --- src/vsrc/dummy_icache.sv | 79 +++++++++++++++++++++++----------------- 1 file changed, 46 insertions(+), 33 deletions(-) diff --git a/src/vsrc/dummy_icache.sv b/src/vsrc/dummy_icache.sv index 27b2479..57bf3d9 100644 --- a/src/vsrc/dummy_icache.sv +++ b/src/vsrc/dummy_icache.sv @@ -11,6 +11,7 @@ module dummy_icache #( input logic rst, // <-> IF + input logic frontend_flush_i, // All signals are 1 cycle valid // all 0 means invalid input logic [ADDR_WIDTH-1:0] raddr_1_i, @@ -104,42 +105,54 @@ module dummy_icache #( assign stallreq_o = ~(state == ACCEPT_ADDR); always_ff @(posedge clk or negedge rst_n) begin : axi_ff - axi_addr_o <= 0; - case (state) - ACCEPT_ADDR: begin - if (raddr_1_i != 0 && axi_busy_i == 0) axi_addr_o <= raddr_1_i; - end - IN_TRANSACTION_1: begin - if (raddrs[1] != 0 && axi_busy_i == 0) axi_addr_o <= raddrs[1]; - end - IN_TRANSACTION_2: begin - axi_addr_o <= 0; - end - endcase + if (!rst_n) begin + axi_addr_o <= 0; + end else begin + axi_addr_o <= 0; + case (state) + ACCEPT_ADDR: begin + if (raddr_1_i != 0 && axi_busy_i == 0) axi_addr_o <= raddr_1_i; + end + IN_TRANSACTION_1: begin + if (raddrs[1] != 0 && axi_busy_i == 0) axi_addr_o <= raddrs[1]; + end + IN_TRANSACTION_2: begin + axi_addr_o <= 0; + end + endcase + end end // Output logic always_ff @(posedge clk or negedge rst_n) begin : output_ff - rvalid_1_o <= 0; - rvalid_2_o <= 0; - raddr_1_o <= 0; - raddr_2_o <= 0; - rdata_1_o <= 0; - rdata_2_o <= 0; - case (state) - ACCEPT_ADDR: begin - end - IN_TRANSACTION_1: begin - rvalid_1_o <= ~axi_busy_i; - raddr_1_o <= axi_busy_i ? 0 : raddrs[0]; - rdata_1_o <= axi_busy_i ? 0 : axi_data_i; - end - IN_TRANSACTION_2: begin - rvalid_2_o <= ~axi_busy_i; - raddr_2_o <= axi_busy_i ? 0 : raddrs[1]; - rdata_2_o <= axi_busy_i ? 0 : axi_data_i; - end - endcase + if (!rst_n) begin + rvalid_1_o <= 0; + rvalid_2_o <= 0; + raddr_1_o <= 0; + raddr_2_o <= 0; + rdata_1_o <= 0; + rdata_2_o <= 0; + end else begin + rvalid_1_o <= 0; + rvalid_2_o <= 0; + raddr_1_o <= 0; + raddr_2_o <= 0; + rdata_1_o <= 0; + rdata_2_o <= 0; + case (state) + ACCEPT_ADDR: begin + end + IN_TRANSACTION_1: begin + rvalid_1_o <= ~axi_busy_i; + raddr_1_o <= axi_busy_i ? 0 : raddrs[0]; + rdata_1_o <= axi_busy_i ? 0 : axi_data_i; + end + IN_TRANSACTION_2: begin + rvalid_2_o <= ~axi_busy_i; + raddr_2_o <= axi_busy_i ? 0 : raddrs[1]; + rdata_2_o <= axi_busy_i ? 0 : axi_data_i; + end + endcase + end end - endmodule From 074c4b93d28b02772baa47d3ba578ba735437c66 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Fri, 6 May 2022 11:03:12 +0800 Subject: [PATCH 068/114] fix: fix frontend ff block rst --- src/vsrc/frontend/frontend.sv | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/vsrc/frontend/frontend.sv b/src/vsrc/frontend/frontend.sv index 90e29e0..ef75a08 100644 --- a/src/vsrc/frontend/frontend.sv +++ b/src/vsrc/frontend/frontend.sv @@ -89,15 +89,21 @@ module frontend #( end always_ff @(posedge clk or negedge rst_n) begin : instr_buffer_o_ff - // Keep 0 for most of the time - for (integer i = 0; i < FETCH_WIDTH; i++) begin - instr_buffer_o[i] <= 0; - end - if (icache_resp_ready && !instr_buffer_stallreq_i) begin + if (!rst_n) begin + for (integer i = 0; i < FETCH_WIDTH; i++) begin + instr_buffer_o[i] <= 0; + end + end else begin + // Keep 0 for most of the time for (integer i = 0; i < FETCH_WIDTH; i++) begin - instr_buffer_o[i].valid <= 1; - instr_buffer_o[i].pc <= icache_resp_buffer[i].pc; - instr_buffer_o[i].instr <= icache_resp_buffer[i].instr; + instr_buffer_o[i] <= 0; + end + if (icache_resp_ready && !instr_buffer_stallreq_i) begin + for (integer i = 0; i < FETCH_WIDTH; i++) begin + instr_buffer_o[i].valid <= 1; + instr_buffer_o[i].pc <= icache_resp_buffer[i].pc; + instr_buffer_o[i].instr <= icache_resp_buffer[i].instr; + end end end end From 00509d3350f17077d5b28802c3c461239c70ddd6 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Fri, 6 May 2022 11:27:03 +0800 Subject: [PATCH 069/114] fix: fix header re-define --- src/vsrc/cpu_top.sv | 4 +- src/vsrc/csr_defines.sv | 168 ++++++++++++++++++++-------------------- src/vsrc/defines.sv | 109 +++++++++++++------------- 3 files changed, 146 insertions(+), 135 deletions(-) diff --git a/src/vsrc/cpu_top.sv b/src/vsrc/cpu_top.sv index 328ccdd..a87d938 100644 --- a/src/vsrc/cpu_top.sv +++ b/src/vsrc/cpu_top.sv @@ -224,7 +224,9 @@ module cpu_top ( .frontend_stallreq_o(ib_frontend_stallreq), // <-> Backend - .backend_accept_i(2'b0), // FIXME: currently not accepting any instructions + .backend_accept_i({ + id_inst_valid_2, id_inst_valid_1 + }), // FIXME: currently not accepting any instructions .backend_flush_i(backend_flush), .backend_instr_o(backend_ib_instr_info) ); diff --git a/src/vsrc/csr_defines.sv b/src/vsrc/csr_defines.sv index adf2077..679b7a9 100644 --- a/src/vsrc/csr_defines.sv +++ b/src/vsrc/csr_defines.sv @@ -1,136 +1,140 @@ +`ifndef CSR_DEFINES_SV +`define CSR_DEFINES_SV //CRMD -`define PLV 1:0 -`define IE 2 -`define DA 3 -`define PG 4 -`define DATF 6:5 -`define DATM 8:7 +`define PLV 1:0 +`define IE 2 +`define DA 3 +`define PG 4 +`define DATF 6:5 +`define DATM 8:7 //PRMD -`define PPLV 1:0 -`define PIE 2 +`define PPLV 1:0 +`define PIE 2 //ECTL -`define LIE 12:0 +`define LIE 12:0 //ESTAT -`define IS 12:0 -`define ECODE 21:16 -`define ESUBCODE 30:22 +`define IS 12:0 +`define ECODE 21:16 +`define ESUBCODE 30:22 //TLBIDX -`define INDEX 4:0 -`define PS 29:24 -`define NE 31 +`define INDEX 4:0 +`define PS 29:24 +`define NE 31 //TLBEHI -`define VPPN 31:13 +`define VPPN 31:13 //TLBELO -`define TLB_V 0 -`define TLB_D 1 -`define TLB_PLV 3:2 -`define TLB_MAT 5:4 -`define TLB_G 6 -`define TLB_PPN 31:8 +`define TLB_V 0 +`define TLB_D 1 +`define TLB_PLV 3:2 +`define TLB_MAT 5:4 +`define TLB_G 6 +`define TLB_PPN 31:8 `define TLB_PPN_EN 27:8 //ASID -`define TLB_ASID 9:0 +`define TLB_ASID 9:0 //CPUID -`define COREID 8:0 +`define COREID 8:0 //LLBCTL -`define ROLLB 0 -`define WCLLB 1 -`define KLO 2 +`define ROLLB 0 +`define WCLLB 1 +`define KLO 2 //TCFG -`define EN 0 -`define PERIODIC 1 -`define INITVAL 31:2 +`define EN 0 +`define PERIODIC 1 +`define INITVAL 31:2 //TICLR -`define CLR 0 +`define CLR 0 //TLBRENTRY `define TLBRENTRY_PA 31:6 //DMW -`define PLV0 0 -`define PLV3 3 -`define DMW_MAT 5:4 -`define PSEG 27:25 -`define VSEG 31:29 +`define PLV0 0 +`define PLV3 3 +`define DMW_MAT 5:4 +`define PSEG 27:25 +`define VSEG 31:29 //PGDL PGDH PGD -`define BASE 31:12 - -`define CRMD 14'h0 -`define PRMD 14'h1 -`define ECTL 14'h4 -`define ESTAT 14'h5 -`define ERA 14'h6 -`define BADV 14'h7 -`define EENTRY 14'hc +`define BASE 31:12 + +`define CRMD 14'h0 +`define PRMD 14'h1 +`define ECTL 14'h4 +`define ESTAT 14'h5 +`define ERA 14'h6 +`define BADV 14'h7 +`define EENTRY 14'hc `define TLBIDX 14'h10 `define TLBEHI 14'h11 `define TLBELO0 14'h12 `define TLBELO1 14'h13 -`define ASID 14'h18 -`define PGDL 14'h19 -`define PGDH 14'h1a -`define PGD 14'h1b -`define CPUID 14'h20 -`define SAVE0 14'h30 -`define SAVE1 14'h31 -`define SAVE2 14'h32 -`define SAVE3 14'h33 -`define TID 14'h40 -`define TCFG 14'h41 -`define TVAL 14'h42 -`define CNTC 14'h43 -`define TICLR 14'h44 +`define ASID 14'h18 +`define PGDL 14'h19 +`define PGDH 14'h1a +`define PGD 14'h1b +`define CPUID 14'h20 +`define SAVE0 14'h30 +`define SAVE1 14'h31 +`define SAVE2 14'h32 +`define SAVE3 14'h33 +`define TID 14'h40 +`define TCFG 14'h41 +`define TVAL 14'h42 +`define CNTC 14'h43 +`define TICLR 14'h44 `define LLBCTL 14'h60 -`define TLBRENTRY 14'h88 +`define TLBRENTRY 14'h88 `define TLBRBADV 14'h89 `define TLBRERA 14'h8a -`define TLBRSAVE 14'h8bb +`define TLBRSAVE 14'h8bb `define TLBRLO0 14'h8c `define TLBRLO1 14'h8d `define TLBREHI 14'h8e `define TLBRPRMD 14'h8f -`define DMW0 14'h180 -`define DMW1 14'h181 -`define DMW2 14'h182 -`define DMW3 14'h183 -`define BRK 14'h100 -`define DISABLE_CACHE 14'h101 +`define DMW0 14'h180 +`define DMW1 14'h181 +`define DMW2 14'h182 +`define DMW3 14'h183 +`define BRK 14'h100 +`define DISABLE_CACHE 14'h101 //error code -`define ECODE_INT 6'h0 -`define ECODE_PIL 6'h1 -`define ECODE_PIS 6'h2 -`define ECODE_PIF 6'h3 -`define ECODE_PME 6'h4 -`define ECODE_PPI 6'h7 +`define ECODE_INT 6'h0 +`define ECODE_PIL 6'h1 +`define ECODE_PIS 6'h2 +`define ECODE_PIF 6'h3 +`define ECODE_PME 6'h4 +`define ECODE_PPI 6'h7 `define ECODE_ADEF 6'h8 `define ECODE_ADEM 6'h8 -`define ECODE_ALE 6'h9 -`define ECODE_SYS 6'hb -`define ECODE_BRK 6'hc -`define ECODE_INE 6'hd -`define ECODE_IPE 6'he -`define ECODE_FPD 6'hf +`define ECODE_ALE 6'h9 +`define ECODE_SYS 6'hb +`define ECODE_BRK 6'hc +`define ECODE_INE 6'hd +`define ECODE_IPE 6'he +`define ECODE_FPD 6'hf `define ECODE_TLBR 6'h3f -`define ESUBCODE_ADEF 9'h0 -`define ESUBCODE_ADEM 9'h1 +`define ESUBCODE_ADEF 9'h0 +`define ESUBCODE_ADEM 9'h1 typedef struct packed { logic we; logic [13:0] addr; logic [31:0] data; -}csr_write_signal; \ No newline at end of file +} csr_write_signal; + +`endif diff --git a/src/vsrc/defines.sv b/src/vsrc/defines.sv index 78d1a69..13c2441 100644 --- a/src/vsrc/defines.sv +++ b/src/vsrc/defines.sv @@ -1,3 +1,6 @@ +`ifndef DEFINES_SV +`define DEFINES_SV + // Global define `define RstEnable 1'b1 `define RstDisable 1'b0 @@ -74,7 +77,7 @@ `define EXE_SLTUI 6'b1001?? `define EXE_ADDI_W 6'b1010?? `define EXE_ANDI 6'b1101?? -`define EXE_ORI 6'b1110?? +`define EXE_ORI 6'b1110?? `define EXE_XORI 6'b1111?? `define EXE_LONG_ARITH 6'b000001 `define EXE_DIV_ARITH 6'b000010 @@ -83,18 +86,18 @@ `define EXE_SUB_W 5'b00010 `define EXE_SLT 5'b00100 `define EXE_SLTU 5'b00101 -`define EXE_NOR 5'b01000 -`define EXE_AND 5'b01001 -`define EXE_OR 5'b01010 -`define EXE_XOR 5'b01011 -`define EXE_SLL_W 5'b01110 -`define EXE_SRL_W 5'b01111 -`define EXE_SRA_W 5'b10000 -`define EXE_MUL_W 5'b11000 -`define EXE_MULH_W 5'b11001 -`define EXE_MULH_WU 5'b11010 - -`define EXE_DIV_W 5'b00000 // EXE_DIV_ARITH +`define EXE_NOR 5'b01000 +`define EXE_AND 5'b01001 +`define EXE_OR 5'b01010 +`define EXE_XOR 5'b01011 +`define EXE_SLL_W 5'b01110 +`define EXE_SRL_W 5'b01111 +`define EXE_SRA_W 5'b10000 +`define EXE_MUL_W 5'b11000 +`define EXE_MULH_W 5'b11001 +`define EXE_MULH_WU 5'b11010 + +`define EXE_DIV_W 5'b00000 // EXE_DIV_ARITH `define EXE_MOD_W 5'b00001 `define EXE_DIV_WU 5'b00010 `define EXE_MOD_WU 5'b00011 @@ -114,43 +117,43 @@ // AluOp -`define EXE_NOP_OP 8'b00000000 -`define EXE_OR_OP 8'b00000001 -`define EXE_AND_OP 8'b00000010 -`define EXE_XOR_OP 8'b00000011 -`define EXE_NOR_OP 8'b00000100 -`define EXE_LUI_OP 8'b00000101 -`define EXE_SLL_OP 8'b00000101 -`define EXE_SRL_OP 8'b00000110 -`define EXE_SRA_OP 8'b00000111 -`define EXE_ADD_OP 8'b00001000 -`define EXE_SUB_OP 8'b00001001 -`define EXE_MUL_OP 8'b00001010 -`define EXE_MULH_OP 8'b00001011 +`define EXE_NOP_OP 8'b00000000 +`define EXE_OR_OP 8'b00000001 +`define EXE_AND_OP 8'b00000010 +`define EXE_XOR_OP 8'b00000011 +`define EXE_NOR_OP 8'b00000100 +`define EXE_LUI_OP 8'b00000101 +`define EXE_SLL_OP 8'b00000101 +`define EXE_SRL_OP 8'b00000110 +`define EXE_SRA_OP 8'b00000111 +`define EXE_ADD_OP 8'b00001000 +`define EXE_SUB_OP 8'b00001001 +`define EXE_MUL_OP 8'b00001010 +`define EXE_MULH_OP 8'b00001011 `define EXE_MULHU_OP 8'b00001100 -`define EXE_DIV_OP 8'b00001101 -`define EXE_MOD_OP 8'b00001110 -`define EXE_SLT_OP 8'b00001111 -`define EXE_SLTU_OP 8'b00010000 -`define EXE_B_OP 8'b00010001 -`define EXE_BL_OP 8'b00010010 -`define EXE_BEQ_OP 8'b00010011 -`define EXE_BNE_OP 8'b00010100 -`define EXE_BLT_OP 8'b00010101 -`define EXE_BGE_OP 8'b00010110 -`define EXE_BLTU_OP 8'b00010111 -`define EXE_BGEU_OP 8'b00011000 -`define EXE_JIRL_OP 8'b00011001 -`define EXE_LD_B_OP 8'b00011010 -`define EXE_LD_H_OP 8'b00011011 -`define EXE_LD_W_OP 8'b00011100 -`define EXE_ST_B_OP 8'b00011101 -`define EXE_ST_H_OP 8'b00011110 -`define EXE_ST_W_OP 8'b00011111 +`define EXE_DIV_OP 8'b00001101 +`define EXE_MOD_OP 8'b00001110 +`define EXE_SLT_OP 8'b00001111 +`define EXE_SLTU_OP 8'b00010000 +`define EXE_B_OP 8'b00010001 +`define EXE_BL_OP 8'b00010010 +`define EXE_BEQ_OP 8'b00010011 +`define EXE_BNE_OP 8'b00010100 +`define EXE_BLT_OP 8'b00010101 +`define EXE_BGE_OP 8'b00010110 +`define EXE_BLTU_OP 8'b00010111 +`define EXE_BGEU_OP 8'b00011000 +`define EXE_JIRL_OP 8'b00011001 +`define EXE_LD_B_OP 8'b00011010 +`define EXE_LD_H_OP 8'b00011011 +`define EXE_LD_W_OP 8'b00011100 +`define EXE_ST_B_OP 8'b00011101 +`define EXE_ST_H_OP 8'b00011110 +`define EXE_ST_W_OP 8'b00011111 `define EXE_LD_BU_OP 8'b00100000 `define EXE_LD_HU_OP 8'b00100001 -`define EXE_LL_OP 8'b00100010 -`define EXE_SC_OP 8'b00100011 +`define EXE_LL_OP 8'b00100010 +`define EXE_SC_OP 8'b00100011 `define EXE_PCADD_OP 8'b00100100 `define EXE_SYSCALL_OP 8'b00100101 `define EXE_BREAK_OP 8'b00100110 @@ -161,8 +164,8 @@ `define EXE_TLBRD_OP 8'b00101011 `define EXE_TLBWR_OP 8'b00101100 `define EXE_TLBSRCH_OP 8'b00101101 -`define EXE_ERTN_OP 8'b00101110 -`define EXE_IDLE_OP 8'b00101111 +`define EXE_ERTN_OP 8'b00101110 +`define EXE_IDLE_OP 8'b00101111 `define EXE_INVTLB_OP 8'b00110000 @@ -170,9 +173,9 @@ `define EXE_RES_NOP 3'b000 `define EXE_RES_LOGIC 3'b001 `define EXE_RES_SHIFT 3'b010 -`define EXE_RES_MOVE 3'b011 +`define EXE_RES_MOVE 3'b011 `define EXE_RES_ARITH 3'b100 -`define EXE_RES_JUMP 3'b101 +`define EXE_RES_JUMP 3'b101 `define EXE_RES_LOAD_STORE 3'b110 @@ -209,5 +212,7 @@ typedef struct packed { } reg_write_signal; //tlb-compare-part //typedef struct packed { - + //} tlb_com_part; + +`endif From 16305bb447dfae59fcdb69c38158d8da201bc697 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Fri, 6 May 2022 11:43:28 +0800 Subject: [PATCH 070/114] fix: flip valid signal --- src/vsrc/cpu_top.sv | 10 ++++------ src/vsrc/defines.sv | 4 ++-- src/vsrc/pipeline/4_mem/mem_wb.sv | 2 +- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/vsrc/cpu_top.sv b/src/vsrc/cpu_top.sv index a87d938..55226d2 100644 --- a/src/vsrc/cpu_top.sv +++ b/src/vsrc/cpu_top.sv @@ -224,11 +224,9 @@ module cpu_top ( .frontend_stallreq_o(ib_frontend_stallreq), // <-> Backend - .backend_accept_i({ - id_inst_valid_2, id_inst_valid_1 - }), // FIXME: currently not accepting any instructions - .backend_flush_i(backend_flush), - .backend_instr_o(backend_ib_instr_info) + .backend_accept_i({id_inst_valid_2, id_inst_valid_1}), // 1 means valid + .backend_flush_i (backend_flush), + .backend_instr_o (backend_ib_instr_info) ); @@ -1465,7 +1463,7 @@ module cpu_top ( .clock (aclk), .coreid (0), // Only one core, so always 0 .index (0), // Commit channel index - .valid (~debug_commit_valid_1), // TODO: flip valid definition in CPU + .valid (debug_commit_valid_1), // 1 means valid .pc (debug_commit_pc_1), .instr (debug_commit_instr_1), .skip (0), // Not sure meaning, but keep 0 for now diff --git a/src/vsrc/defines.sv b/src/vsrc/defines.sv index 13c2441..87edeb8 100644 --- a/src/vsrc/defines.sv +++ b/src/vsrc/defines.sv @@ -11,8 +11,8 @@ `define ReadDisable 1'b0 `define AluOpBus 7:0 `define AluSelBus 2:0 -`define InstValid 1'b0 -`define InstInvalid 1'b1 +`define InstValid 1'b1 +`define InstInvalid 1'b0 `define Stop 1'b1 `define NoStop 1'b0 `define Branch 1'b1 diff --git a/src/vsrc/pipeline/4_mem/mem_wb.sv b/src/vsrc/pipeline/4_mem/mem_wb.sv index 7199f0f..bfd4631 100644 --- a/src/vsrc/pipeline/4_mem/mem_wb.sv +++ b/src/vsrc/pipeline/4_mem/mem_wb.sv @@ -123,7 +123,7 @@ module mem_wb ( wb_csr_signal_o <= 47'b0; debug_commit_instr <= `ZeroWord; debug_commit_pc <= `ZeroWord; - debug_commit_valid <= ~`InstInvalid; + debug_commit_valid <= `InstInvalid; end else if (stall == `Stop) begin debug_commit_pc <= `ZeroWord; debug_commit_instr <= `ZeroWord; From 0a2d49e726c0040f6b5b34d296f2c6d32c6e3ed9 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Fri, 6 May 2022 12:11:09 +0800 Subject: [PATCH 071/114] fix: fix IB typo --- src/vsrc/instr_buffer.sv | 2 +- src/vsrc/pipeline/2_decode/id.sv | 88 ++++++++++++++++---------------- 2 files changed, 46 insertions(+), 44 deletions(-) diff --git a/src/vsrc/instr_buffer.sv b/src/vsrc/instr_buffer.sv index 8c4d6e6..59e1792 100644 --- a/src/vsrc/instr_buffer.sv +++ b/src/vsrc/instr_buffer.sv @@ -90,7 +90,7 @@ module instr_buffer #( // Frontend overide for (integer i = 0; i < IF_WIDTH; i++) begin // Reset entry - if (i < backend_accept_num) begin + if (i < frontend_accept_num) begin next_buffer_queue[write_ptr+i] = frontend_instr_i[i]; end end diff --git a/src/vsrc/pipeline/2_decode/id.sv b/src/vsrc/pipeline/2_decode/id.sv index 3b4df71..09e8b1b 100644 --- a/src/vsrc/pipeline/2_decode/id.sv +++ b/src/vsrc/pipeline/2_decode/id.sv @@ -78,27 +78,29 @@ module id ( // ->Ctrl output logic stallreq, - output reg idle_stallreq + output reg idle_stallreq ); - logic [`InstAddrBus] pc_i = instr_buffer_i.valid ? instr_buffer_i.pc : `ZeroWord; - logic [`InstBus] inst_i = instr_buffer_i.valid ? instr_buffer_i.instr : `ZeroWord; + logic [`InstAddrBus] pc_i; + assign pc_i = instr_buffer_i.valid ? instr_buffer_i.pc : `ZeroWord; + logic [`InstBus] inst_i; + assign inst_i = instr_buffer_i.valid ? instr_buffer_i.instr : `ZeroWord; - logic [5:0] opcode_6 = inst_i[31:26]; - logic [6:0] opcode_7 = inst_i[31:25]; - logic [7:0] opcode_8 = inst_i[31:24]; - logic [9:0] opcode_10 = inst_i[31:22]; + logic [ 5:0] opcode_6 = inst_i[31:26]; + logic [ 6:0] opcode_7 = inst_i[31:25]; + logic [ 7:0] opcode_8 = inst_i[31:24]; + logic [ 9:0] opcode_10 = inst_i[31:22]; logic [13:0] opcode_14 = inst_i[31:18]; logic [16:0] opcode_17 = inst_i[31:15]; logic [21:0] opcode_22 = inst_i[31:10]; - logic [4:0] imm_5 = inst_i[14:10]; - logic [9:0] imm_10 = inst_i[9:0]; + logic [ 4:0] imm_5 = inst_i[14:10]; + logic [ 9:0] imm_10 = inst_i[9:0]; logic [13:0] imm_14 = inst_i[23:10]; logic [15:0] imm_16 = inst_i[25:10]; logic [11:0] imm_12 = inst_i[21:10]; logic [19:0] imm_20 = inst_i[24:5]; - logic [4:0] op1; + logic [ 4:0] op1; assign op1 = inst_i[4:0]; logic [4:0] op2 = inst_i[9:5]; logic [4:0] op3 = inst_i[14:10]; @@ -146,12 +148,12 @@ module id ( reg inst_break; reg kernel_inst; - + assign current_inst_address_o = pc_i; - assign excp_ine = ~inst_valid; + assign excp_ine = (inst_valid == `InstInvalid) && instr_buffer_i.valid; assign excp_ipe = kernel_inst && (csr_plv == 2'b11); assign excp_o = excp_ipe | inst_syscall | inst_break | excp_i | excp_ine | has_int; @@ -458,47 +460,47 @@ module id ( `EXE_CSR_RELATED: begin case (op2) `EXE_CSRRD: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_CSRRD_OP; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - imm = {18'b0, imm_14}; - csr_signal_o.we = 1'b1; + wreg_o = `WriteEnable; + aluop_o = `EXE_CSRRD_OP; + reg1_read_o = 1'b1; + reg2_read_o = 1'b0; + imm = {18'b0, imm_14}; + csr_signal_o.we = 1'b1; csr_signal_o.addr = imm_14; csr_signal_o.data = `ZeroWord; - reg_waddr_o = op1; - inst_valid = `InstValid; - res_from_csr = 1'b1; - kernel_inst = 1'b1; + reg_waddr_o = op1; + inst_valid = `InstValid; + res_from_csr = 1'b1; + kernel_inst = 1'b1; end `EXE_CSRWR: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_CSRWR_OP; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - imm = {18'b0, imm_14}; - csr_signal_o.we = 1'b1; + wreg_o = `WriteEnable; + aluop_o = `EXE_CSRWR_OP; + reg1_read_o = 1'b1; + reg2_read_o = 1'b0; + imm = {18'b0, imm_14}; + csr_signal_o.we = 1'b1; csr_signal_o.addr = imm_14; csr_signal_o.data = reg1_data_i; - reg1_addr_o = op1; - reg_waddr_o = op1; - inst_valid = `InstValid; - res_from_csr = 1'b1; - kernel_inst = 1'b1; + reg1_addr_o = op1; + reg_waddr_o = op1; + inst_valid = `InstValid; + res_from_csr = 1'b1; + kernel_inst = 1'b1; end default: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_CSRXCHG_OP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - imm = {18'b0, imm_14}; - csr_signal_o.we = 1'b1; + wreg_o = `WriteEnable; + aluop_o = `EXE_CSRXCHG_OP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + imm = {18'b0, imm_14}; + csr_signal_o.we = 1'b1; csr_signal_o.addr = imm_14; csr_signal_o.data = reg1_data_i; - reg_waddr_o = op1; - inst_valid = `InstValid; - res_from_csr = 1'b1; - kernel_inst = 1'b1; + reg_waddr_o = op1; + inst_valid = `InstValid; + res_from_csr = 1'b1; + kernel_inst = 1'b1; end endcase end From 1a39867c3a207dd2fdf5419b71d98b88e2a1a746 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Fri, 6 May 2022 12:16:19 +0800 Subject: [PATCH 072/114] fix: fix difftest pc --- src/vsrc/cpu_top.sv | 2 ++ src/vsrc/pipeline/4_mem/mem_wb.sv | 7 ------- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/vsrc/cpu_top.sv b/src/vsrc/cpu_top.sv index 55226d2..275f278 100644 --- a/src/vsrc/cpu_top.sv +++ b/src/vsrc/cpu_top.sv @@ -1162,6 +1162,8 @@ module cpu_top ( logic excp_tlbrefill_1; logic [18:0] excp_tlb_vppn_1; + logic [`InstAddrBus] debug_commit_pc_1; + mem_wb mem_wb_1 ( .clk (clk), .rst (rst), diff --git a/src/vsrc/pipeline/4_mem/mem_wb.sv b/src/vsrc/pipeline/4_mem/mem_wb.sv index bfd4631..72e8d55 100644 --- a/src/vsrc/pipeline/4_mem/mem_wb.sv +++ b/src/vsrc/pipeline/4_mem/mem_wb.sv @@ -54,10 +54,6 @@ module mem_wb ( output wire [18:0] excp_tlb_vppn ); - reg debug_commit_valid_0; - reg debug_commit_valid_1; - reg [`InstBus] debug_commit_pc_0; - reg wb_valid; assign csr_era = mem_inst_pc; @@ -137,10 +133,7 @@ module mem_wb ( wb_LLbit_value <= mem_LLbit_value; wb_csr_signal_o <= mem_csr_signal_o; debug_commit_pc <= mem_inst_pc; - // debug_commit_pc <= debug_commit_pc_0; debug_commit_valid <= mem_inst_valid; - // debug_commit_valid_1 <= debug_commit_valid_0; - // debug_commit_valid <= ~debug_commit_valid_1; debug_commit_instr <= mem_instr; end end From 32a132d05e5d8cbae1929ffb24744ae630f92a2e Mon Sep 17 00:00:00 2001 From: Rookie-rookie-rookie <292601787@qq.com> Date: Fri, 6 May 2022 15:17:27 +0800 Subject: [PATCH 073/114] fix connect typo --- src/vsrc/cpu_top.sv | 8 ++++++-- src/vsrc/pipeline/3_execution/ex.sv | 20 +++++++++++--------- src/vsrc/pipeline/4_mem/mem_wb.sv | 4 ++-- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/vsrc/cpu_top.sv b/src/vsrc/cpu_top.sv index 275f278..3962e8a 100644 --- a/src/vsrc/cpu_top.sv +++ b/src/vsrc/cpu_top.sv @@ -765,7 +765,9 @@ module cpu_top ( .current_inst_address_i(ex_current_inst_address_i_1), .csr_signal_i(ex_csr_signal_i_1), - .write_signal_o(), + .wreg_o(ex_wreg_o_1), + .wd_o(ex_reg_waddr_o_1), + .wdata_o(ex_reg_wdata_1), .inst_valid_o(ex_inst_valid_o_1), .inst_pc_o(ex_inst_pc_o_1), .aluop_o(ex_aluop_o_1), @@ -811,7 +813,9 @@ module cpu_top ( .current_inst_address_i(ex_current_inst_address_i_2), .csr_signal_i(ex_csr_signal_i_2), - .write_signal_o(), + .wreg_o(ex_wreg_o_2), + .wd_o(ex_reg_waddr_o_2), + .wdata_o(ex_reg_wdata_2), .inst_valid_o(ex_inst_valid_o_2), .inst_pc_o(ex_inst_pc_o_2), .aluop_o(ex_aluop_o_2), diff --git a/src/vsrc/pipeline/3_execution/ex.sv b/src/vsrc/pipeline/3_execution/ex.sv index 7a0cbb1..ded777d 100644 --- a/src/vsrc/pipeline/3_execution/ex.sv +++ b/src/vsrc/pipeline/3_execution/ex.sv @@ -20,7 +20,9 @@ module ex ( input logic [18:0] csr_vppn, - output reg_write_signal write_signal_o, + output logic wreg_o, + output logic [`RegAddrBus] wd_o, + output logic [`RegBus] wdata_o, output reg inst_valid_o, output reg [`InstAddrBus] inst_pc_o, output logic [`AluOpBus] aluop_o, @@ -183,26 +185,26 @@ module ex ( end always @(*) begin - write_signal_o.addr = wd_i; - write_signal_o.we = wreg_i; + wd_o = wd_i; + wreg_o = wreg_i; case (alusel_i) `EXE_RES_LOGIC: begin - write_signal_o.data = logicout; + wdata_o = logicout; end `EXE_RES_SHIFT: begin - write_signal_o.data = shiftout; + wdata_o = shiftout; end `EXE_RES_MOVE: begin - write_signal_o.data = moveout; + wdata_o = moveout; end `EXE_RES_ARITH: begin - write_signal_o.data = arithout; + wdata_o = arithout; end `EXE_RES_JUMP: begin - write_signal_o.data = link_addr_i; + wdata_o = link_addr_i; end default: begin - write_signal_o.data = `ZeroWord; + wdata_o = `ZeroWord; end endcase end diff --git a/src/vsrc/pipeline/4_mem/mem_wb.sv b/src/vsrc/pipeline/4_mem/mem_wb.sv index 72e8d55..a58af24 100644 --- a/src/vsrc/pipeline/4_mem/mem_wb.sv +++ b/src/vsrc/pipeline/4_mem/mem_wb.sv @@ -81,7 +81,7 @@ module mem_wb ( excp_num[8] ? 9'b0 :excp_num[9] ? 9'b0 : excp_num[10] ? `ESUBCODE_ADEM : excp_num[11] ? 9'b0 : excp_num[12] ? 9'b0 :excp_num[13] ? 9'b0 : excp_num[14] ? 9'b0 :excp_num[15] ? 9'b0 : 9'b0 ; - assign csr_esubcode = excp_num[0] ? 1'b0 : excp_num[1] ? 1'b0 : excp_num[2] ? wb_valid : excp_num[3] ? 1'b0 : + assign excp_tlbrefill = excp_num[0] ? 1'b0 : excp_num[1] ? 1'b0 : excp_num[2] ? wb_valid : excp_num[3] ? 1'b0 : excp_num[4] ? 1'b0 : excp_num[5] ? 1'b0 :excp_num[6] ? 1'b0 : excp_num[7] ? 1'b0 : excp_num[8] ? 1'b0 :excp_num[9] ? 1'b0 : excp_num[10] ? 1'b0 : excp_num[11] ? wb_valid : excp_num[12] ? 1'b0 :excp_num[13] ? 1'b0 : excp_num[14] ? 1'b0 :excp_num[15] ? 1'b0 : 1'b0 ; @@ -94,7 +94,7 @@ module mem_wb ( assign excp_tlb_vppn = excp_num[0] ? 19'b0 : excp_num[1] ? 19'b0 : excp_num[2] ? mem_inst_pc[31:13] : excp_num[3] ? mem_inst_pc[31:13] : excp_num[4] ? mem_inst_pc[31:13] : excp_num[5] ? 19'b0 :excp_num[6] ? 19'b0 : excp_num[7] ? 19'b0 : excp_num[8] ? 19'b0 :excp_num[9] ? 19'b0 : excp_num[10] ? 19'b0 : excp_num[11] ? wb_wdata[31:13] : - excp_num[12] ? wb_wdata[31:13] :excp_num[13] ? wb_wdata[31:13] : excp_num[14] ? wb_wdata[31:13] :excp_num[15] ? wb_wdata[31:13] : 1'b0 ; + excp_num[12] ? wb_wdata[31:13] :excp_num[13] ? wb_wdata[31:13] : excp_num[14] ? wb_wdata[31:13] :excp_num[15] ? wb_wdata[31:13] : 19'b0 ; always @(posedge clk) begin From f24ca6d4e59868b96ea22ada682923d1fdda28fe Mon Sep 17 00:00:00 2001 From: Easton Man Date: Fri, 6 May 2022 22:32:38 +0800 Subject: [PATCH 074/114] refactor: use parallel decoder in ID --- src/vsrc/cpu_top.sv | 17 +- src/vsrc/defines.sv | 100 +- src/vsrc/pipeline/2_decode/decoder_2R.sv | 65 ++ src/vsrc/pipeline/2_decode/decoder_2RI12.sv | 144 +++ src/vsrc/pipeline/2_decode/decoder_2RI16.sv | 104 ++ src/vsrc/pipeline/2_decode/decoder_3R.sv | 157 +++ src/vsrc/pipeline/2_decode/id.sv | 1032 +++---------------- src/vsrc/pipeline/2_decode/id_bak.sv | 928 +++++++++++++++++ src/vsrc/pipeline/2_decode/id_old.sv | 427 ++++++++ src/vsrc/regfile.sv | 3 +- 10 files changed, 2041 insertions(+), 936 deletions(-) create mode 100644 src/vsrc/pipeline/2_decode/decoder_2R.sv create mode 100644 src/vsrc/pipeline/2_decode/decoder_2RI12.sv create mode 100644 src/vsrc/pipeline/2_decode/decoder_2RI16.sv create mode 100644 src/vsrc/pipeline/2_decode/decoder_3R.sv create mode 100644 src/vsrc/pipeline/2_decode/id_bak.sv create mode 100644 src/vsrc/pipeline/2_decode/id_old.sv diff --git a/src/vsrc/cpu_top.sv b/src/vsrc/cpu_top.sv index 3962e8a..6748772 100644 --- a/src/vsrc/cpu_top.sv +++ b/src/vsrc/cpu_top.sv @@ -1465,12 +1465,18 @@ module cpu_top ( // Difftest DPI-C `ifdef SIMU // SIMU is defined in chiplab run_func/Makefile + logic [`RegBus] debug_commit_pc_1_delay_1; + log debug_commit_valid_1_delay_1; + always_ff @( posedge clk) begin : + debug_commit_pc_1_delay_1 <= debug_commit_valid_1; + debug_commit_pc_1_delay_1 <= debug_commit_pc_1; + end DifftestInstrCommit difftest_instr_commit_0 ( // TODO: not finished yet, blank signal is needed .clock (aclk), - .coreid (0), // Only one core, so always 0 - .index (0), // Commit channel index - .valid (debug_commit_valid_1), // 1 means valid - .pc (debug_commit_pc_1), + .coreid (0), // Only one core, so always 0 + .index (0), // Commit channel index + .valid (debug_commit_valid_1_delay_1), // 1 means valid + .pc (debug_commit_pc_1_delay_1), .instr (debug_commit_instr_1), .skip (0), // Not sure meaning, but keep 0 for now .is_TLBFILL (), @@ -1516,7 +1522,8 @@ module cpu_top ( .dmw1 (u_cs_reg.csr_dmw1) ); - + // Assume regilfe instance name is u_regfile + // and architectural register are under regs[] array DifftestGRegState difftest_gpr_state ( .clock (aclk), .coreid(0), diff --git a/src/vsrc/defines.sv b/src/vsrc/defines.sv index 87edeb8..d27003d 100644 --- a/src/vsrc/defines.sv +++ b/src/vsrc/defines.sv @@ -28,10 +28,9 @@ // Instruction Encode -// 6 bit opcode, decoded within opcode_1 + +// 2RI16-type `define EXE_JIRL 6'b010011 -`define EXE_B 6'b010100 -`define EXE_BL 6'b010101 `define EXE_BEQ 6'b010110 `define EXE_BNE 6'b010111 `define EXE_BLT 6'b011000 @@ -41,21 +40,14 @@ `define EXE_LU12I_W 6'b000101 // 7'b0001010 `define EXE_PCADDU12I 6'b000111 // 7'b0001110 +`define EXE_B 6'b010100 +`define EXE_BL 6'b010101 + // 6-12 bit opcode, decoded in opcode_2 `define EXE_ATOMIC_MEM 6'b001000 `define EXE_LL_W 6'b00???? `define EXE_SC_W 6'b01???? -`define EXE_MEM_RELATED 6'b001010 -`define EXE_LD_B 6'b0000?? -`define EXE_LD_H 6'b0001?? -`define EXE_LD_W 6'b0010?? -`define EXE_ST_B 6'b0100?? -`define EXE_ST_H 6'b0101?? -`define EXE_ST_W 6'b0110?? -`define EXE_LD_BU 6'b1000?? -`define EXE_LD_HU 6'b1001?? -`define EXE_PRELD 6'b1011?? `define EXE_SPECIAL 6'b000001 `define EXE_CSR_RELATED 6'b00???? @@ -64,55 +56,63 @@ `define EXE_CSRWR 5'b00001 `define EXE_CSRXCHG 5'b00011 `define EXE_TLB_RELATED 5'b10000 -`define EXE_IDLE 17'b00000110010010001 -`define EXE_INVTLB 17'b00000110010010011 `define EXE_TLBSRCH 22'b0000011001001000001010 `define EXE_TLBRD 22'b0000011001001000001011 `define EXE_TLBWR 22'b0000011001001000001100 `define EXE_TLBFILL 22'b0000011001001000001101 `define EXE_ERTN 22'b0000011001001000001110 -`define EXE_ARITHMETIC 6'b000000 // opcode_1 -`define EXE_SLTI 6'b1000?? // opcode_2 -`define EXE_SLTUI 6'b1001?? -`define EXE_ADDI_W 6'b1010?? -`define EXE_ANDI 6'b1101?? -`define EXE_ORI 6'b1110?? -`define EXE_XORI 6'b1111?? -`define EXE_LONG_ARITH 6'b000001 -`define EXE_DIV_ARITH 6'b000010 -`define EXE_SHIFT_ARITH 6'b000100 -`define EXE_ADD_W 5'b00000 // opcode_3, EXE_LONG_ARITH -`define EXE_SUB_W 5'b00010 -`define EXE_SLT 5'b00100 -`define EXE_SLTU 5'b00101 -`define EXE_NOR 5'b01000 -`define EXE_AND 5'b01001 -`define EXE_OR 5'b01010 -`define EXE_XOR 5'b01011 -`define EXE_SLL_W 5'b01110 -`define EXE_SRL_W 5'b01111 -`define EXE_SRA_W 5'b10000 -`define EXE_MUL_W 5'b11000 -`define EXE_MULH_W 5'b11001 -`define EXE_MULH_WU 5'b11010 - -`define EXE_DIV_W 5'b00000 // EXE_DIV_ARITH -`define EXE_MOD_W 5'b00001 -`define EXE_DIV_WU 5'b00010 -`define EXE_MOD_WU 5'b00011 -`define EXE_BREAK 5'b10100 -`define EXE_SYSCALL 5'b10110 +// 2RI12-type +`define EXE_SLTI 10'b0000001000 +`define EXE_SLTUI 10'b0000001001 +`define EXE_ADDI_W 10'b0000001010 +`define EXE_ANDI 10'b0000001101 +`define EXE_ORI 10'b0000001110 +`define EXE_XORI 10'b0000001111 +`define EXE_LD_B 10'b0010100000 +`define EXE_LD_H 10'b0010100001 +`define EXE_LD_W 10'b0010100010 +`define EXE_ST_B 10'b0010100100 +`define EXE_ST_H 10'b0010100101 +`define EXE_ST_W 10'b0010100110 +`define EXE_LD_BU 10'b0010101000 +`define EXE_LD_HU 10'b0010101001 +`define EXE_PRELD 10'b0010101011 + +// 3R-type +`define EXE_ADD_W 17'b00000000000100000 +`define EXE_SUB_W 17'b00000000000100010 +`define EXE_SLT 17'b00000000000100101 +`define EXE_SLTU 17'b00000000000100101 +`define EXE_NOR 17'b00000000000101000 +`define EXE_AND 17'b00000000000101001 +`define EXE_OR 17'b00000000000101010 +`define EXE_XOR 17'b00000000000101011 +`define EXE_SLL_W 17'b00000000000101110 +`define EXE_SRL_W 17'b00000000000101111 +`define EXE_SRA_W 17'b00000000000110000 +`define EXE_MUL_W 17'b00000000000111000 +`define EXE_MULH_W 17'b00000000000110001 +`define EXE_MULH_WU 17'b00000000000110010 +`define EXE_DIV_W 17'b00000000001000000 +`define EXE_MOD_W 17'b00000000001000001 +`define EXE_DIV_WU 17'b00000000001000010 +`define EXE_MOD_WU 17'b00000000001000011 +`define EXE_BREAK 17'b00000000001010100 +`define EXE_SYSCALL 17'b00000000001010110 +// +`define EXE_IDLE 17'b00000110010010001 +`define EXE_INVTLB 17'b00000110010010011 +// 顺序核无需实现 +`define EXE_DBAR 17'b00111000011100100 +`define EXE_IBAR 17'b00111000011100101 `define EXE_SLLI_W 5'b00??? // EXE_SHIFT_ARITH `define EXE_SRLI_W 5'b01??? `define EXE_SRAI_W 5'b10??? -// 顺序核无需实现 -`define EXE_DBAR 17'b00111000011100100 -`define EXE_IBAR 17'b00111000011100101 -`define EXE_NOP 22'b000000 +`define EXE_NOP 22'b0 diff --git a/src/vsrc/pipeline/2_decode/decoder_2R.sv b/src/vsrc/pipeline/2_decode/decoder_2R.sv new file mode 100644 index 0000000..ef03b86 --- /dev/null +++ b/src/vsrc/pipeline/2_decode/decoder_2R.sv @@ -0,0 +1,65 @@ +`include "defines.sv" +`include "instr_info.sv" + +// decoder_2R is the decoder for 2R-type instructions +// 2R-type {opcode[22], rj[5], rd[5]} +// mainly TLB instructions +// all combinational circuit +module decoder_2R #( + parameter ADDR_WIDTH = 32, + parameter DATA_WIDTH = 32, + parameter GPR_NUM = 32, + parameter ALU_OP_WIDTH = 8, + parameter ALU_SEL_WIDTH = 3 +) ( + input instr_buffer_info_t instr_info_i, + + // indicates current decoder module result is valid or not + // 1 means valid + output logic decode_result_valid_o, + + // TLB instructions do not read GPR + + // TLB instructions do not modify GPR + + // TLB instructions do not use ALU + output logic [ALU_OP_WIDTH-1:0] aluop_o + +); + + logic [DATA_WIDTH-1:0] instr; + assign instr = instr_info_i.instr; + + always_comb begin + case (instr[31:10]) + `EXE_TLBWR: begin + decode_result_valid_o = 1; + aluop_o = `EXE_TLBFILL_OP; + end + `EXE_TLBFILL: begin + decode_result_valid_o = 1; + aluop_o = `EXE_TLBFILL_OP; + + end + `EXE_TLBRD: begin + decode_result_valid_o = 1; + aluop_o = `EXE_TLBRD_OP; + + end + `EXE_TLBSRCH: begin + decode_result_valid_o = 1; + aluop_o = `EXE_TLBSRCH_OP; + end + + `EXE_ERTN: begin + decode_result_valid_o = 1; + aluop_o = `EXE_ERTN_OP; + end + default: begin + decode_result_valid_o = 0; + aluop_o = 0; + end + endcase + end + +endmodule diff --git a/src/vsrc/pipeline/2_decode/decoder_2RI12.sv b/src/vsrc/pipeline/2_decode/decoder_2RI12.sv new file mode 100644 index 0000000..a50de9b --- /dev/null +++ b/src/vsrc/pipeline/2_decode/decoder_2RI12.sv @@ -0,0 +1,144 @@ +`include "defines.sv" +`include "instr_info.sv" + +// decoder_2RI12 is the decoder for 2RI12-type instructions +// 2RI12-type {opcode[10], imm[12] ,rj[5], rd[5]} +// arithmetic instructions & memory instructions +// all combinational circuit +module decoder_2RI12 #( + parameter ADDR_WIDTH = 32, + parameter DATA_WIDTH = 32, + parameter GPR_NUM = 32, + parameter ALU_OP_WIDTH = 8, + parameter ALU_SEL_WIDTH = 3 +) ( + input instr_buffer_info_t instr_info_i, + + // indicates current decoder module result is valid or not + // 1 means valid + output logic decode_result_valid_o, + + // GPR read + // 1 means valid, {rj, rk} + output logic [1:0] reg_read_valid_o, + output logic [$clog2(GPR_NUM)*2-1:0] reg_read_addr_o, + + // Generate imm + output logic [DATA_WIDTH-1:0] imm_o, + + // GPR write + // 1 means valid, {rd} + output logic reg_write_valid_o, + output logic [$clog2(GPR_NUM)-1:0] reg_write_addr_o, + + + // ALU info + output logic [ ALU_OP_WIDTH-1:0] aluop_o, + output logic [ALU_SEL_WIDTH-1:0] alusel_o + +); + + logic [DATA_WIDTH-1:0] instr; + assign instr = instr_info_i.instr; + + // 3 Registers + logic [4:0] rd, rj; + assign rd = instr[4:0]; + assign rj = instr[9:5]; + + // imm12 + logic [11:0] imm_12; + assign imm_12 = instr[21:10]; + + always_comb begin + // Default decode + decode_result_valid_o = 1; + reg_write_valid_o = 1; + reg_write_addr_o = rd; + reg_read_valid_o = 2'b01; + reg_read_addr_o = {5'b0, rj}; + imm_o = 0; + case (instr[31:22]) + `EXE_SLTI: begin + aluop_o = `EXE_SLT_OP; + alusel_o = `EXE_RES_ARITH; + imm_o = {{20{imm_12[11]}}, imm_12}; // Signed Extension + end + `EXE_SLTUI: begin + aluop_o = `EXE_SLTU_OP; + alusel_o = `EXE_RES_ARITH; + imm_o = {{20{imm_12[11]}}, imm_12}; // Signed Extension + end + `EXE_ADDI_W: begin + aluop_o = `EXE_ADD_OP; + alusel_o = `EXE_RES_ARITH; + imm_o = {{20{imm_12[11]}}, imm_12}; // Signed Extension + end + `EXE_ANDI: begin + aluop_o = `EXE_AND_OP; + alusel_o = `EXE_RES_LOGIC; + imm_o = {20'b0, imm_12}; // Zero Extension + end + `EXE_ORI: begin + aluop_o = `EXE_OR_OP; + alusel_o = `EXE_RES_LOGIC; + imm_o = {20'b0, imm_12}; // Zero Extension + end + `EXE_XORI: begin + aluop_o = `EXE_XOR_OP; + alusel_o = `EXE_RES_LOGIC; + imm_o = {20'b0, imm_12}; // Zero Extension + end + `EXE_LD_B: begin + aluop_o = `EXE_LD_B_OP; + alusel_o = `EXE_RES_LOAD_STORE; + imm_o = {{20{imm_12[11]}}, imm_12}; // Signed Extension + end + `EXE_LD_H: begin + aluop_o = `EXE_LD_H_OP; + alusel_o = `EXE_RES_LOAD_STORE; + imm_o = {{20{imm_12[11]}}, imm_12}; // Signed Extension + end + `EXE_LD_W: begin + aluop_o = `EXE_LD_W_OP; + alusel_o = `EXE_RES_LOAD_STORE; + imm_o = {{20{imm_12[11]}}, imm_12}; // Signed Extension + end + `EXE_ST_B: begin + aluop_o = `EXE_ST_B_OP; + alusel_o = `EXE_RES_LOAD_STORE; + imm_o = {{20{imm_12[11]}}, imm_12}; // Signed Extension + end + `EXE_ST_H: begin + aluop_o = `EXE_ST_H_OP; + alusel_o = `EXE_RES_LOAD_STORE; + imm_o = {{20{imm_12[11]}}, imm_12}; // Signed Extension + end + `EXE_ST_W: begin + aluop_o = `EXE_ST_W_OP; + alusel_o = `EXE_RES_LOAD_STORE; + imm_o = {{20{imm_12[11]}}, imm_12}; // Signed Extension + end + `EXE_LD_BU: begin + aluop_o = `EXE_LD_BU_OP; + alusel_o = `EXE_RES_LOAD_STORE; + imm_o = {{20{imm_12[11]}}, imm_12}; // Signed Extension + end + `EXE_LD_HU: begin + aluop_o = `EXE_LD_HU_OP; + alusel_o = `EXE_RES_LOAD_STORE; + imm_o = {{20{imm_12[11]}}, imm_12}; // Signed Extension + end + `EXE_PRELD: begin + aluop_o = `EXE_NOP_OP; + alusel_o = `EXE_RES_NOP; + end + default: begin + decode_result_valid_o = 0; + aluop_o = 0; + alusel_o = 0; + end + endcase + end + +endmodule diff --git a/src/vsrc/pipeline/2_decode/decoder_2RI16.sv b/src/vsrc/pipeline/2_decode/decoder_2RI16.sv new file mode 100644 index 0000000..60d2b66 --- /dev/null +++ b/src/vsrc/pipeline/2_decode/decoder_2RI16.sv @@ -0,0 +1,104 @@ +`include "defines.sv" +`include "instr_info.sv" + +// decoder_2RI16 is the decoder for 2RI16-type instructions +// 2RI16-type {opcode[6], imm[16] ,rj[5], rd[5]} +// branch instructions +// all combinational circuit +module decoder_2RI16 #( + parameter ADDR_WIDTH = 32, + parameter DATA_WIDTH = 32, + parameter GPR_NUM = 32, + parameter ALU_OP_WIDTH = 8, + parameter ALU_SEL_WIDTH = 3 +) ( + input instr_buffer_info_t instr_info_i, + + // indicates current decoder module result is valid or not + // 1 means valid + output logic decode_result_valid_o, + + // GPR read + // 1 means valid, {rj, rk} + output logic [1:0] reg_read_valid_o, + output logic [$clog2(GPR_NUM)*2-1:0] reg_read_addr_o, + + // Generate imm + // sext.w(imm_16) << 2 + output logic [DATA_WIDTH-1:0] imm_o, + + // GPR write + // 1 means valid, {rd} + output logic reg_write_valid_o, + output logic [$clog2(GPR_NUM)-1:0] reg_write_addr_o, + + + // ALU info + output logic [ ALU_OP_WIDTH-1:0] aluop_o, + output logic [ALU_SEL_WIDTH-1:0] alusel_o + +); + + logic [DATA_WIDTH-1:0] instr; + assign instr = instr_info_i.instr; + + // 3 Registers + logic [4:0] rd, rj; + assign rd = instr[4:0]; + assign rj = instr[9:5]; + + // imm12 + logic [15:0] imm_16; + assign imm_16 = instr[25:10]; + + always_comb begin + // Default decode + decode_result_valid_o = 1; + reg_write_valid_o = 0; + reg_write_addr_o = 0; + reg_read_valid_o = 2'b11; + reg_read_addr_o = {rd, rj}; + imm_o = {{14{imm_16[15]}}, imm_16, 2'b0}; + case (instr[31:26]) + `EXE_JIRL: begin + aluop_o = `EXE_JIRL_OP; + alusel_o = `EXE_RES_JUMP; + reg_write_valid_o = 1; + reg_write_addr_o = rd; + reg_read_valid_o = 2'b01; + reg_read_addr_o = {5'b0, rj}; + end + `EXE_BEQ: begin + aluop_o = `EXE_BEQ_OP; + alusel_o = `EXE_RES_JUMP; + end + `EXE_BNE: begin + aluop_o = `EXE_BNE_OP; + alusel_o = `EXE_RES_JUMP; + end + `EXE_BLT: begin + aluop_o = `EXE_BLT_OP; + alusel_o = `EXE_RES_JUMP; + end + `EXE_BGE: begin + aluop_o = `EXE_BGE_OP; + alusel_o = `EXE_RES_JUMP; + end + `EXE_BLTU: begin + aluop_o = `EXE_BLTU_OP; + alusel_o = `EXE_RES_JUMP; + end + `EXE_BGEU: begin + aluop_o = `EXE_BGEU_OP; + alusel_o = `EXE_RES_JUMP; + end + default: begin + decode_result_valid_o = 0; + aluop_o = 0; + alusel_o = 0; + imm_o = 0; + end + endcase + end + +endmodule diff --git a/src/vsrc/pipeline/2_decode/decoder_3R.sv b/src/vsrc/pipeline/2_decode/decoder_3R.sv new file mode 100644 index 0000000..96359ef --- /dev/null +++ b/src/vsrc/pipeline/2_decode/decoder_3R.sv @@ -0,0 +1,157 @@ +`include "defines.sv" +`include "instr_info.sv" + +// decoder_3R is the decoder for 3R-type instructions +// 3R-type {opcode[17], rk[5] ,rj[5], rd[5]} +// arithmetic instructions and break and syscall +// See also "defines.sv" +// all combinational circuit +module decoder_3R #( + parameter ADDR_WIDTH = 32, + parameter DATA_WIDTH = 32, + parameter GPR_NUM = 32, + parameter ALU_OP_WIDTH = 8, + parameter ALU_SEL_WIDTH = 3 +) ( + input instr_buffer_info_t instr_info_i, + + // indicates current decoder module result is valid or not + // 1 means valid + output logic decode_result_valid_o, + + // GPR read + // 1 means valid, {rj, rk} + output logic [1:0] reg_read_valid_o, + output logic [$clog2(GPR_NUM)*2-1:0] reg_read_addr_o, + + // GPR write + // 1 means valid, {rd} + output logic reg_write_valid_o, + output logic [$clog2(GPR_NUM)-1:0] reg_write_addr_o, + + + // ALU info + output logic [ ALU_OP_WIDTH-1:0] aluop_o, + output logic [ALU_SEL_WIDTH-1:0] alusel_o, + + // Special, 1 means valid + output logic instr_break, + output logic instr_syscall +); + + logic [DATA_WIDTH-1:0] instr; + assign instr = instr_info_i.instr; + + // 3 Registers + logic [4:0] rd, rk, rj; + assign rd = instr[4:0]; + assign rj = instr[9:5]; + assign rk = instr[14:10]; + + always_comb begin + // Default decode + decode_result_valid_o = 1; + reg_write_valid_o = 1; + reg_write_addr_o = rd; + reg_read_valid_o = 2'b11; + reg_read_addr_o = {rj, rk}; + instr_break = 0; + instr_syscall = 0; + case (instr[31:15]) + // These two do not need GPR + `EXE_BREAK: begin + reg_write_valid_o = 0; + reg_write_addr_o = 0; + reg_read_valid_o = 2'b00; + reg_read_addr_o = 0; + instr_break = 1; + end + `EXE_BREAK: begin + reg_write_valid_o = 0; + reg_write_addr_o = 0; + reg_read_valid_o = 2'b00; + reg_read_addr_o = 0; + instr_syscall = 1; + end + `EXE_ADD_W: begin + aluop_o = `EXE_ADD_OP; + alusel_o = `EXE_RES_ARITH; + end + `EXE_SUB_W: begin + aluop_o = `EXE_SUB_OP; + alusel_o = `EXE_RES_ARITH; + end + `EXE_SLT: begin + aluop_o = `EXE_SLT_OP; + alusel_o = `EXE_RES_ARITH; + end + `EXE_SLTU: begin + aluop_o = `EXE_SLTU_OP; + alusel_o = `EXE_RES_ARITH; + end + `EXE_NOR: begin + aluop_o = `EXE_NOR_OP; + alusel_o = `EXE_RES_LOGIC; + end + `EXE_AND: begin + aluop_o = `EXE_AND_OP; + alusel_o = `EXE_RES_LOGIC; + end + `EXE_OR: begin + aluop_o = `EXE_OR_OP; + alusel_o = `EXE_RES_LOGIC; + end + `EXE_XOR: begin + aluop_o = `EXE_XOR_OP; + alusel_o = `EXE_RES_LOGIC; + end + `EXE_SLL_W: begin + aluop_o = `EXE_SLL_OP; + alusel_o = `EXE_RES_SHIFT; + end + `EXE_SRL_W: begin + aluop_o = `EXE_SRL_OP; + alusel_o = `EXE_RES_SHIFT; + end + `EXE_SRA_W: begin + aluop_o = `EXE_SRA_OP; + alusel_o = `EXE_RES_SHIFT; + end + `EXE_MUL_W: begin + aluop_o = `EXE_MUL_OP; + alusel_o = `EXE_RES_ARITH; + end + `EXE_MULH_W: begin + aluop_o = `EXE_MULH_OP; + alusel_o = `EXE_RES_ARITH; + end + `EXE_MULH_WU: begin + aluop_o = `EXE_MULHU_OP; + alusel_o = `EXE_RES_ARITH; + end + `EXE_DIV_W, `EXE_DIV_WU: begin + aluop_o = `EXE_DIV_OP; + alusel_o = `EXE_RES_ARITH; + end + `EXE_MOD_W, `EXE_MOD_WU: begin + aluop_o = `EXE_MOD_OP; + alusel_o = `EXE_RES_ARITH; + end + `EXE_IDLE, `EXE_DBAR, `EXE_IBAR: begin + // FIXME: not implemented now + aluop_o = `EXE_NOP_OP; + alusel_o = `EXE_RES_NOP; + end + `EXE_INVTLB: begin + // FIXME: not implemented now, TLB related + aluop_o = `EXE_INVTLB_OP; + alusel_o = `EXE_RES_NOP; + end + default: begin + decode_result_valid_o = 0; + aluop_o = 0; + end + endcase + end + +endmodule diff --git a/src/vsrc/pipeline/2_decode/id.sv b/src/vsrc/pipeline/2_decode/id.sv index 09e8b1b..87d582e 100644 --- a/src/vsrc/pipeline/2_decode/id.sv +++ b/src/vsrc/pipeline/2_decode/id.sv @@ -1,66 +1,60 @@ -`timescale 1ns / 1ns - `include "defines.sv" `include "instr_info.sv" `include "csr_defines.sv" -module id ( - input logic rst, - // <- IF + +// ID stage +// Should be totally cominational circuit +// What ID DO: +// 1. Extract information from the instruction +// 2. Do GPR and CSR read +// 3. Determine oprands for EXE +// What ID NOT DO: +// 1. Determine whether a instruction dispatch in EXE or not +// 2. Calculate anything, such as branch target +// +module id #( + parameter EXE_STAGE_WIDTH = 2, + parameter MEM_STAGE_WIDTH = 2 +) ( + // <- Instruction Buffer input instr_buffer_info_t instr_buffer_i, + input logic excp_i, input logic [3:0] excp_num_i, - // <- Regfile - input logic [`RegBus] reg1_data_i, - input logic [`RegBus] reg2_data_i, - - input instr_buffer_info_t instr_buffer_i_other, + // <-> Regfile + output logic [1:0] regfile_reg_read_valid_o, // Read valid for 2 regs + output logic [`RegNumLog2*2-1:0] regfile_reg_read_addr_o, // Read addr, {reg2, reg1} + input logic [`RegBus] regfile_reg_read_data_o, // Read result // <- EXE - input logic ex_wreg_i_1, - input logic [`RegAddrBus] ex_waddr_i_1, - input logic [`RegBus] ex_wdata_i_1, - input logic [`AluOpBus] ex_aluop_i_1, - - - // <- ANOTHER_EXE - input logic ex_wreg_i_2, - input logic [`RegAddrBus] ex_waddr_i_2, - input logic [`RegBus] ex_wdata_i_2, - input logic [`AluOpBus] ex_aluop_i_2, + // Data forwarding + input logic ex_write_reg_valid_i[EXE_STAGE_WIDTH], + input logic [`RegAddrBus] ex_write_reg_addr_i[EXE_STAGE_WIDTH], + input logic [`RegBus] ex_write_reg_data_i[EXE_STAGE_WIDTH], + input logic [`AluOpBus] ex_aluop_i[EXE_STAGE_WIDTH], // <- Mem - input logic mem_wreg_i_1, - input logic [`RegAddrBus] mem_waddr_i_1, - input logic [`RegBus] mem_wdata_i_1, + // Data forwarding + input logic mem_write_reg_valid_i[MEM_STAGE_WIDTH], + input logic [`RegAddrBus] mem_write_reg_addr_i[MEM_STAGE_WIDTH], + input logic [`RegBus] mem_write_reg_data_i[MEM_STAGE_WIDTH], - // <- ANOTHER_Mem - input logic mem_wreg_i_2, - input logic [`RegAddrBus] mem_waddr_i_2, - input logic [`RegBus] mem_wdata_i_2, - - // -> Regfile - output reg reg1_read_o, - output reg reg2_read_o, // -> EXE - output reg [`RegAddrBus] reg1_addr_o, - output reg [`RegAddrBus] reg2_addr_o, - output reg [`AluOpBus] aluop_o, - output reg [`AluSelBus] alusel_o, - output reg [`RegBus] reg1_o, - output reg [`RegBus] reg2_o, - output reg [`RegAddrBus] reg_waddr_o, - output reg wreg_o, - output reg inst_valid, - output reg [`InstAddrBus] inst_pc, - output logic [`RegBus] inst_o, - output logic [`RegBus] current_inst_address_o, - output reg csr_we, - output csr_write_signal csr_signal_o, - output logic excp_o, - output logic [8:0] excp_num_o, + output reg [`AluOpBus] ex_aluop_o, + output reg [`AluSelBus] ex_alusel_o, + output reg [`RegBus] ex_op1_o, + output reg [`RegBus] ex_op2_o, + output reg ex_reg_write_valid_o, + output reg [`RegAddrBus] ex_reg_write_addr_o, + output instr_buffer_info_t ex_instr_info_o, // Instruction info passed to EXE + output reg ex_csr_we_o, + output csr_write_signal ex_csr_signal_o, + + output logic broadcast_excp_o, + output logic [8:0] broadcast_excp_num_o, // <- CSR input logic has_int, @@ -68,17 +62,7 @@ module id ( input logic [1:0] csr_plv, // -> CSR - output reg [13:0] csr_read_addr_o, - - // -> PC - output reg branch_flag_o, - output reg [`RegBus] branch_target_address_o, - output reg [`RegBus] link_addr_o, - output reg [`InstAddrBus] idle_pc, - - // ->Ctrl - output logic stallreq, - output reg idle_stallreq + output reg [13:0] csr_read_addr_o ); logic [`InstAddrBus] pc_i; @@ -86,838 +70,126 @@ module id ( logic [`InstBus] inst_i; assign inst_i = instr_buffer_i.valid ? instr_buffer_i.instr : `ZeroWord; + logic instr_break, instr_syscall, kernel_instr; + + // Sub-decoder section + localparam SUB_DECODER_NUM = 7; + logic sub_decoder_valid[SUB_DECODER_NUM]; + logic [`AluOpBus] sub_decoder_aluop[SUB_DECODER_NUM]; + logic [`AluSelBus] sub_decoder_alusel[SUB_DECODER_NUM]; + logic [1:0] sub_decoder_reg_read_valid[SUB_DECODER_NUM]; + logic [`RegNumLog2*2-1:0] sub_decoder_reg_read_addr[SUB_DECODER_NUM]; + logic sub_decoder_reg_write_valid[SUB_DECODER_NUM]; + logic [`RegAddrBus] sub_decoder_reg_write_addr[SUB_DECODER_NUM]; + logic [`RegBus] sub_decoder_imm[SUB_DECODER_NUM]; + + // Sub-decoders in following order: + // 2R, 3R, 2RI8, 2RI12, 2RI16, I26, Special + decoder_2R u_decoder_2R ( + .instr_info_i (instr_buffer_i), + .decode_result_valid_o(sub_decoder_valid[0]), + .aluop_o (sub_decoder_aluop[0]) + ); + decoder_3R u_decoder_3R ( + .instr_info_i (instr_buffer_i), + .decode_result_valid_o(sub_decoder_valid[1]), + .reg_read_valid_o (sub_decoder_reg_read_valid[1]), + .reg_read_addr_o (sub_decoder_reg_read_addr[1]), + .reg_write_valid_o (sub_decoder_reg_write_valid[1]), + .reg_write_addr_o (sub_decoder_reg_write_addr[1]), + .aluop_o (sub_decoder_aluop[1]), + .alusel_o (sub_decoder_alusel[1]), + .instr_break (instr_break), + .instr_syscall (instr_syscall) + ); + // FIXME: 2RI8 not implemented + decoder_2RI12 u_decoder_2RI12 ( + .instr_info_i (instr_buffer_i), + .decode_result_valid_o(sub_decoder_valid[3]), + .reg_read_valid_o (sub_decoder_reg_read_valid[3]), + .reg_read_addr_o (sub_decoder_reg_read_addr[3]), + .imm_o (sub_decoder_imm[3]), + .reg_write_valid_o (sub_decoder_reg_write_valid[3]), + .reg_write_addr_o (sub_decoder_reg_write_addr[3]), + .aluop_o (sub_decoder_aluop[3]), + .alusel_o (sub_decoder_alusel[3]) + ); + decoder_2RI16 u_decoder_2RI16 ( + .instr_info_i (instr_buffer_i), + .decode_result_valid_o(sub_decoder_valid[4]), + .reg_read_valid_o (sub_decoder_reg_read_valid[4]), + .reg_read_addr_o (sub_decoder_reg_read_addr[4]), + .imm_o (sub_decoder_imm[4]), + .reg_write_valid_o (sub_decoder_reg_write_valid[4]), + .reg_write_addr_o (sub_decoder_reg_write_addr[4]), + .aluop_o (sub_decoder_aluop[4]), + .alusel_o (sub_decoder_alusel[4]) + ); + // FIXME: I16 and Special not implemented + + // Sub-decoder END + + // Generate imm, using OR + logic [`RegBus] imm; + always_comb begin + imm = 0; + for (integer i = 0; i < SUB_DECODER_NUM; i++) begin + imm = imm | sub_decoder_imm[i]; + end + end + // Generate instr_valid, using OR + logic instr_valid; + always_comb begin + instr_valid = 0; + for (integer i = 0; i < SUB_DECODER_NUM; i++) begin + instr_valid = instr_valid | sub_decoder_valid[i]; + end + end + // Generate output to EXE + always_comb begin + ex_aluop_o = 0; + ex_alusel_o = 0; + ex_reg_write_valid_o = 0; + ex_reg_write_addr_o = 0; + for (integer i = 0; i < SUB_DECODER_NUM; i++) begin + ex_aluop_o = ex_aluop_o | sub_decoder_aluop[i]; + ex_alusel_o = ex_alusel_o | sub_decoder_alusel[i]; + ex_reg_write_valid_o = ex_reg_write_valid_o | sub_decoder_reg_write_valid[i]; + ex_reg_write_addr_o = ex_reg_write_addr_o | sub_decoder_reg_write_addr[i]; + end + end + // Generate output to Regfile + always_comb begin + regfile_reg_read_valid_o = 0; + regfile_reg_read_addr_o = 0; + for (integer i = 0; i < SUB_DECODER_NUM; i++) begin + regfile_reg_read_valid_o = regfile_reg_read_valid_o | sub_decoder_reg_read_valid[i]; + regfile_reg_read_addr_o = regfile_reg_read_addr_o | sub_decoder_reg_read_addr[i]; + end + end - logic [ 5:0] opcode_6 = inst_i[31:26]; - logic [ 6:0] opcode_7 = inst_i[31:25]; - logic [ 7:0] opcode_8 = inst_i[31:24]; - logic [ 9:0] opcode_10 = inst_i[31:22]; - logic [13:0] opcode_14 = inst_i[31:18]; - logic [16:0] opcode_17 = inst_i[31:15]; - logic [21:0] opcode_22 = inst_i[31:10]; - logic [ 4:0] imm_5 = inst_i[14:10]; - logic [ 9:0] imm_10 = inst_i[9:0]; - logic [13:0] imm_14 = inst_i[23:10]; - logic [15:0] imm_16 = inst_i[25:10]; - logic [11:0] imm_12 = inst_i[21:10]; - logic [19:0] imm_20 = inst_i[24:5]; - logic [ 4:0] op1; - assign op1 = inst_i[4:0]; - logic [4:0] op2 = inst_i[9:5]; - logic [4:0] op3 = inst_i[14:10]; - logic [4:0] op4 = inst_i[19:15]; - - logic [5:0] opcode_1 = inst_i[31:26]; - logic [5:0] opcode_2 = inst_i[25:20]; - logic [4:0] opcode_3 = inst_i[19:15]; - logic [4:0] opcode_4 = inst_i[14:10]; - - logic [`RegBus] pc_plus_4; - - assign pc_plus_4 = pc_i + 4; - assign inst_o = inst_i; - - reg [`RegBus] imm; - reg stallreq_for_reg1_loadrelate; - reg stallreq_for_reg2_loadrelate; - logic pre_inst_is_load; + // Generate output + assign ex_instr_info_o.valid = instr_valid; + assign ex_instr_info_o.pc = pc_i; + assign ex_instr_info_o.instr = inst_i; + // TODO: add explanation logic res_from_csr; logic excp_ine; logic excp_ipe; - assign pre_inst_is_load = (((ex_aluop_i_1 == `EXE_LD_B_OP) || - (ex_aluop_i_1 == `EXE_LD_H_OP) || - (ex_aluop_i_1 == `EXE_LD_W_OP) || - (ex_aluop_i_1 == `EXE_LD_BU_OP) || - (ex_aluop_i_1 == `EXE_LD_HU_OP) || - (ex_aluop_i_1 == `EXE_ST_B_OP) || - (ex_aluop_i_1 == `EXE_ST_H_OP) || - (ex_aluop_i_1 == `EXE_ST_W_OP))||( - (ex_aluop_i_2 == `EXE_LD_B_OP) || - (ex_aluop_i_2 == `EXE_LD_H_OP) || - (ex_aluop_i_2 == `EXE_LD_W_OP) || - (ex_aluop_i_2 == `EXE_LD_BU_OP) || - (ex_aluop_i_2 == `EXE_LD_HU_OP) || - (ex_aluop_i_2 == `EXE_ST_B_OP) || - (ex_aluop_i_2 == `EXE_ST_H_OP) || - (ex_aluop_i_2 == `EXE_ST_W_OP)) && (pc_i == instr_buffer_i_other.pc + 4)) ? 1'b1 : 1'b0; - - reg inst_syscall; - reg inst_break; - reg kernel_inst; + assign excp_ine = (instr_valid == `InstInvalid) && instr_buffer_i.valid; + assign excp_ipe = kernel_instr && (csr_plv == 2'b11); + assign broadcast_excp_o = excp_ipe | instr_syscall | instr_break | excp_i | excp_ine | has_int; + assign broadcast_excp_num_o = { + excp_ipe, excp_ine, instr_break, instr_syscall, excp_num_i, has_int + }; + // TODO: ex_op generate rules not implemented yet - assign current_inst_address_o = pc_i; - assign excp_ine = (inst_valid == `InstInvalid) && instr_buffer_i.valid; - assign excp_ipe = kernel_inst && (csr_plv == 2'b11); - - assign excp_o = excp_ipe | inst_syscall | inst_break | excp_i | excp_ine | has_int; - assign excp_num_o = {excp_ipe, excp_ine, inst_break, inst_syscall, excp_num_i, has_int}; - - - always @(*) begin - if (rst == `RstEnable) stallreq_for_reg1_loadrelate = `NoStop; - else if (pre_inst_is_load == 1'b1 && ex_waddr_i_1 == reg1_addr_o && reg1_read_o == 1'b1) - stallreq_for_reg1_loadrelate = `Stop; - end - - always @(*) begin - - if (rst == `RstEnable) stallreq_for_reg2_loadrelate = `NoStop; - else if (pre_inst_is_load == 1'b1 && ex_waddr_i_1 == reg2_addr_o && reg2_read_o == 1'b1) - stallreq_for_reg2_loadrelate = `Stop; - end - - //如果这条指令与另一条相邻且存在依赖就直接暂停 - assign stallreq = stallreq_for_reg1_loadrelate | stallreq_for_reg2_loadrelate; - - always @(*) begin - inst_pc = pc_i; - end - - always @(*) begin - if (rst == `RstEnable) begin - aluop_o = `EXE_NOP_OP; - alusel_o = `EXE_RES_NOP; - reg_waddr_o = `NOPRegAddr; - wreg_o = `WriteDisable; - inst_valid = `InstInvalid; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - reg1_addr_o = `NOPRegAddr; - reg2_addr_o = `NOPRegAddr; - imm = 32'h0; - branch_flag_o = `NotBranch; - branch_target_address_o = `ZeroWord; - link_addr_o = `ZeroWord; - inst_break = `False_v; - inst_syscall = `False_v; - idle_stallreq = 1'b0; - end else begin - aluop_o = `EXE_NOP_OP; - alusel_o = `EXE_RES_NOP; - reg_waddr_o = op1; - wreg_o = `WriteDisable; - inst_valid = `InstInvalid; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - reg1_addr_o = op2; - reg2_addr_o = op3; - imm = `ZeroWord; - branch_flag_o = `NotBranch; - branch_target_address_o = `ZeroWord; - link_addr_o = `ZeroWord; - idle_stallreq = 1'b0; - case (opcode_1) - `EXE_JIRL: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_JIRL_OP; - alusel_o = `EXE_RES_JUMP; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - link_addr_o = pc_plus_4; - branch_flag_o = `Branch; - branch_target_address_o = reg1_o + {{14{imm_16[15]}}, imm_16, 2'b0}; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_B: begin - wreg_o = `WriteDisable; - aluop_o = `EXE_B_OP; - alusel_o = `EXE_RES_JUMP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - branch_flag_o = `Branch; - branch_target_address_o = pc_i + {{4{imm_10[9]}}, imm_10, imm_16, 2'b0}; - inst_valid = `InstValid; - end - `EXE_BL: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_BL_OP; - alusel_o = `EXE_RES_JUMP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - branch_flag_o = `Branch; - link_addr_o = pc_plus_4; - branch_target_address_o = pc_i + {{4{imm_10[9]}}, imm_10, imm_16, 2'b0}; - reg_waddr_o = 5'b1; - inst_valid = `InstValid; - end - `EXE_BEQ: begin - wreg_o = `WriteDisable; - aluop_o = `EXE_BEQ_OP; - alusel_o = `EXE_RES_JUMP; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg1_addr_o = op2; - reg2_addr_o = op1; - if (reg1_o == reg2_o) begin - branch_flag_o = `Branch; - branch_target_address_o = pc_i + {{14{imm_16[15]}}, imm_16, 2'b0}; - end - inst_valid = `InstValid; - end - `EXE_BNE: begin - wreg_o = `WriteDisable; - aluop_o = `EXE_BNE_OP; - alusel_o = `EXE_RES_JUMP; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg1_addr_o = op2; - reg2_addr_o = op1; - if (reg1_o != reg2_o) begin - branch_flag_o = `Branch; - branch_target_address_o = pc_i + {{14{imm_16[15]}}, imm_16, 2'b0}; - end - inst_valid = `InstValid; - end - `EXE_BLT: begin - wreg_o = `WriteDisable; - aluop_o = `EXE_BLT_OP; - alusel_o = `EXE_RES_JUMP; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg1_addr_o = op2; - reg2_addr_o = op1; - if ({~reg1_o[31], reg1_o[30:0]} < {~reg2_o[31], reg2_o[30:0]}) begin - branch_flag_o = `Branch; - branch_target_address_o = pc_i + {{14{imm_16[15]}}, imm_16, 2'b0}; - end - inst_valid = `InstValid; - end - `EXE_BGE: begin - wreg_o = `WriteDisable; - aluop_o = `EXE_BGE_OP; - alusel_o = `EXE_RES_JUMP; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg1_addr_o = op2; - reg2_addr_o = op1; - if ({~reg1_o[31], reg1_o[30:0]} >= {~reg2_o[31], reg2_o[30:0]}) begin - branch_flag_o = `Branch; - branch_target_address_o = pc_i + {{14{imm_16[15]}}, imm_16, 2'b0}; - end - inst_valid = `InstValid; - end - `EXE_BLTU: begin - wreg_o = `WriteDisable; - aluop_o = `EXE_BLTU_OP; - alusel_o = `EXE_RES_JUMP; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg1_addr_o = op2; - reg2_addr_o = op1; - if (reg1_o < reg2_o) begin - branch_flag_o = `Branch; - branch_target_address_o = pc_i + {{14{imm_16[15]}}, imm_16, 2'b0}; - end - inst_valid = `InstValid; - end - `EXE_BGEU: begin - wreg_o = `WriteDisable; - aluop_o = `EXE_BGEU_OP; - alusel_o = `EXE_RES_JUMP; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg1_addr_o = op2; - reg2_addr_o = op1; - if (reg1_o >= reg2_o) begin - branch_flag_o = `Branch; - branch_target_address_o = pc_i + {{14{imm_16[15]}}, imm_16, 2'b0}; - end - inst_valid = `InstValid; - end - `EXE_LU12I_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_LUI_OP; - alusel_o = `EXE_RES_MOVE; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - imm = {imm_20, 12'b0}; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_PCADDU12I: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_PCADD_OP; - alusel_o = `EXE_RES_MOVE; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - imm = {imm_20, 12'b0}; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_ATOMIC_MEM: begin - casez (opcode_2) - `EXE_LL_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_LL_OP; - alusel_o = `EXE_RES_LOAD_STORE; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_SC_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SC_OP; - alusel_o = `EXE_RES_LOAD_STORE; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg2_addr_o = op1; - inst_valid = `InstValid; - end - default: begin - end - endcase - end - `EXE_MEM_RELATED: begin - casez (opcode_2) - `EXE_LD_B: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_LD_B_OP; - alusel_o = `EXE_RES_LOAD_STORE; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_LD_H: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_LD_H_OP; - alusel_o = `EXE_RES_LOAD_STORE; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_LD_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_LD_W_OP; - alusel_o = `EXE_RES_LOAD_STORE; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_ST_B: begin - wreg_o = `WriteDisable; - aluop_o = `EXE_ST_B_OP; - alusel_o = `EXE_RES_LOAD_STORE; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg2_addr_o = op1; - inst_valid = `InstValid; - end - `EXE_ST_H: begin - wreg_o = `WriteDisable; - aluop_o = `EXE_ST_H_OP; - alusel_o = `EXE_RES_LOAD_STORE; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg2_addr_o = op1; - inst_valid = `InstValid; - end - `EXE_ST_W: begin - wreg_o = `WriteDisable; - aluop_o = `EXE_ST_W_OP; - alusel_o = `EXE_RES_LOAD_STORE; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg2_addr_o = op1; - inst_valid = `InstValid; - end - `EXE_LD_BU: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_LD_BU_OP; - alusel_o = `EXE_RES_LOAD_STORE; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_LD_HU: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_LD_HU_OP; - alusel_o = `EXE_RES_LOAD_STORE; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - default: begin - end - endcase - end - - `EXE_SPECIAL: begin - case (opcode_2) - `EXE_CSR_RELATED: begin - case (op2) - `EXE_CSRRD: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_CSRRD_OP; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - imm = {18'b0, imm_14}; - csr_signal_o.we = 1'b1; - csr_signal_o.addr = imm_14; - csr_signal_o.data = `ZeroWord; - reg_waddr_o = op1; - inst_valid = `InstValid; - res_from_csr = 1'b1; - kernel_inst = 1'b1; - end - `EXE_CSRWR: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_CSRWR_OP; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - imm = {18'b0, imm_14}; - csr_signal_o.we = 1'b1; - csr_signal_o.addr = imm_14; - csr_signal_o.data = reg1_data_i; - reg1_addr_o = op1; - reg_waddr_o = op1; - inst_valid = `InstValid; - res_from_csr = 1'b1; - kernel_inst = 1'b1; - end - default: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_CSRXCHG_OP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - imm = {18'b0, imm_14}; - csr_signal_o.we = 1'b1; - csr_signal_o.addr = imm_14; - csr_signal_o.data = reg1_data_i; - reg_waddr_o = op1; - inst_valid = `InstValid; - res_from_csr = 1'b1; - kernel_inst = 1'b1; - end - endcase - end - `EXE_OTHER: begin - case (opcode_3) - `EXE_TLB_RELATED: begin - case (opcode_22) - `EXE_TLBFILL: begin - wreg_o = `WriteDisable; - aluop_o = `EXE_TLBFILL_OP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - inst_valid = `InstValid; - kernel_inst = 1'b1; - end - `EXE_TLBRD: begin - wreg_o = `WriteDisable; - aluop_o = `EXE_TLBRD_OP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - inst_valid = `InstValid; - kernel_inst = 1'b1; - end - `EXE_TLBSRCH: begin - wreg_o = `WriteDisable; - aluop_o = `EXE_TLBSRCH_OP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - inst_valid = `InstValid; - kernel_inst = 1'b1; - end - `EXE_TLBWR: begin - wreg_o = `WriteDisable; - aluop_o = `EXE_TLBWR_OP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - inst_valid = `InstValid; - kernel_inst = 1'b1; - end - `EXE_ERTN: begin - wreg_o = `WriteDisable; - aluop_o = `EXE_ERTN_OP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - inst_valid = `InstValid; - kernel_inst = 1'b1; - end - default: begin - end - endcase - end - default: begin - case (opcode_17) - `EXE_IDLE: begin - wreg_o = `WriteDisable; - aluop_o = `EXE_IDLE_OP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - idle_stallreq = 1; - idle_pc = pc_i + 32'h4; - inst_valid = `InstValid; - kernel_inst = 1'b1; - end - `EXE_INVTLB: begin - wreg_o = `WriteDisable; - aluop_o = `EXE_INVTLB_OP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - inst_valid = `InstValid; - kernel_inst = 1'b1; - end - default: begin - end - endcase - end - endcase - end - default: begin - end - endcase - end - - `EXE_ARITHMETIC: begin - casez (opcode_2) - `EXE_SLTI: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SLT_OP; - alusel_o = `EXE_RES_ARITH; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - imm = {{20{imm_12[11]}}, imm_12}; // Signed Extension - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_SLTUI: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SLTU_OP; - alusel_o = `EXE_RES_ARITH; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - imm = {{20{imm_12[11]}}, imm_12}; // Signed Extension - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_ADDI_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_ADD_OP; - alusel_o = `EXE_RES_ARITH; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - imm = {{20{imm_12[11]}}, imm_12}; // Signed Extension - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_ANDI: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_AND_OP; - alusel_o = `EXE_RES_LOGIC; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - imm = {20'h0, imm_12}; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_ORI: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_OR_OP; - alusel_o = `EXE_RES_LOGIC; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - imm = {20'h0, imm_12}; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_XORI: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_XOR_OP; - alusel_o = `EXE_RES_LOGIC; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - imm = {20'h0, imm_12}; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_LONG_ARITH: begin - case (opcode_3) - `EXE_ADD_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_ADD_OP; - alusel_o = `EXE_RES_ARITH; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_SUB_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SUB_OP; - alusel_o = `EXE_RES_ARITH; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_SLT: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SLT_OP; - alusel_o = `EXE_RES_ARITH; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_SLTU: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SLTU_OP; - alusel_o = `EXE_RES_ARITH; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_NOR: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_NOR_OP; - alusel_o = `EXE_RES_LOGIC; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_AND: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_AND_OP; - alusel_o = `EXE_RES_LOGIC; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_OR: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_OR_OP; - alusel_o = `EXE_RES_LOGIC; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_XOR: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_XOR_OP; - alusel_o = `EXE_RES_LOGIC; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_SLL_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SLL_OP; - alusel_o = `EXE_RES_SHIFT; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_SRL_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SRL_OP; - alusel_o = `EXE_RES_SHIFT; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_SRA_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SRA_OP; - alusel_o = `EXE_RES_SHIFT; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_MUL_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_MUL_OP; - alusel_o = `EXE_RES_ARITH; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_MULH_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_MULH_OP; - alusel_o = `EXE_RES_ARITH; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_MULH_WU: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_MULHU_OP; - alusel_o = `EXE_RES_ARITH; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - default: begin - end - - endcase - end - `EXE_DIV_ARITH: begin - casez (opcode_3) - `EXE_DIV_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_DIV_OP; - alusel_o = `EXE_RES_ARITH; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_MOD_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_MOD_OP; - alusel_o = `EXE_RES_ARITH; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_DIV_WU: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_DIV_OP; - alusel_o = `EXE_RES_ARITH; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_MOD_WU: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_MOD_OP; - alusel_o = `EXE_RES_ARITH; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_BREAK: begin - wreg_o = `WriteDisable; - aluop_o = `EXE_BREAK_OP; - alusel_o = `EXE_RES_NOP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - inst_valid = `InstValid; - inst_break = `True_v; - end - `EXE_SYSCALL: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SYSCALL_OP; - alusel_o = `EXE_RES_NOP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - inst_valid = `InstValid; - inst_syscall = `True_v; - end - default: begin - end - endcase - end - `EXE_SHIFT_ARITH: begin - casez (opcode_3) - `EXE_SLLI_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SLL_OP; - alusel_o = `EXE_RES_SHIFT; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - imm = {27'b0, imm_5}; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_SRLI_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SRL_OP; - alusel_o = `EXE_RES_SHIFT; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - imm = {27'b0, imm_5}; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_SRAI_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SRA_OP; - alusel_o = `EXE_RES_SHIFT; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - imm = {27'b0, imm_5}; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - default: begin - end - endcase - end - default: begin - - end - endcase - end - default: begin - end - endcase - end - end - - always @(*) begin - if (rst == `RstEnable) reg1_o = `ZeroWord; - else if (opcode_2[5:4] == 2'b00) - reg1_o = csr_data_i; // EXE_CSR_RELATED, TODO: replace magic number - else if ((reg1_read_o == 1'b1) && (reg1_addr_o == 0)) reg1_o = `ZeroWord; - else if ((reg1_read_o == 1'b1) && (ex_wreg_i_2 == 1'b1) && (ex_waddr_i_2 == reg1_addr_o)) - reg1_o = ex_wdata_i_2; - else if ((reg1_read_o == 1'b1) && (mem_wreg_i_2 == 1'b1) && (mem_waddr_i_2 == reg1_addr_o)) - reg1_o = mem_wdata_i_2; - else if ((reg1_read_o == 1'b1) && (ex_wreg_i_1 == 1'b1) && (ex_waddr_i_1 == reg1_addr_o)) - reg1_o = ex_wdata_i_1; - else if ((reg1_read_o == 1'b1) && (mem_wreg_i_1 == 1'b1) && (mem_waddr_i_1 == reg1_addr_o)) - reg1_o = mem_wdata_i_1; - else if (reg1_read_o == 1'b1) reg1_o = reg1_data_i; - else if (reg1_read_o == 1'b0) reg1_o = imm; - else reg1_o = `ZeroWord; - end - - always @(*) begin - if (rst == `RstEnable) reg2_o = `ZeroWord; - else if (opcode_2[5:4] == 2'b00) reg2_o = `ZeroWord; - else if ((reg2_read_o == 1'b1) && (reg2_addr_o == 0)) reg2_o = `ZeroWord; - else if ((reg2_read_o == 1'b1) && (ex_wreg_i_2 == 1'b1) && (ex_waddr_i_2 == reg2_addr_o)) - reg2_o = ex_wdata_i_2; - else if ((reg2_read_o == 1'b1) && (mem_wreg_i_2 == 1'b1) && (mem_waddr_i_2 == reg2_addr_o)) - reg2_o = mem_wdata_i_2; - else if ((reg2_read_o == 1'b1) && (ex_wreg_i_1 == 1'b1) && (ex_waddr_i_1 == reg2_addr_o)) - reg2_o = ex_wdata_i_1; - else if ((reg2_read_o == 1'b1) && (mem_wreg_i_1 == 1'b1) && (mem_waddr_i_1 == reg2_addr_o)) - reg2_o = mem_wdata_i_1; - else if (reg2_read_o == 1'b1) reg2_o = reg2_data_i; - else if (reg2_read_o == 1'b0) reg2_o = imm; - else reg2_o = `ZeroWord; - end - endmodule diff --git a/src/vsrc/pipeline/2_decode/id_bak.sv b/src/vsrc/pipeline/2_decode/id_bak.sv new file mode 100644 index 0000000..e42f483 --- /dev/null +++ b/src/vsrc/pipeline/2_decode/id_bak.sv @@ -0,0 +1,928 @@ +`timescale 1ns / 1ns + +`include "defines.sv" +`include "instr_info.sv" +`include "csr_defines.sv" + + + +module id ( + input logic rst, + + // <- Instruction Buffer + input instr_buffer_info_t instr_buffer_i, + + + input logic excp_i, + input logic [3:0] excp_num_i, + + // <- Regfile + input logic [`RegBus] reg1_data_i, + input logic [`RegBus] reg2_data_i, + + input instr_buffer_info_t instr_buffer_i_other, + + // <- EXE + input logic ex_wreg_i_1, + input logic [`RegAddrBus] ex_waddr_i_1, + input logic [`RegBus] ex_wdata_i_1, + input logic [`AluOpBus] ex_aluop_i_1, + + + // <- ANOTHER_EXE + input logic ex_wreg_i_2, + input logic [`RegAddrBus] ex_waddr_i_2, + input logic [`RegBus] ex_wdata_i_2, + input logic [`AluOpBus] ex_aluop_i_2, + + // <- Mem + input logic mem_wreg_i_1, + input logic [`RegAddrBus] mem_waddr_i_1, + input logic [`RegBus] mem_wdata_i_1, + + // <- ANOTHER_Mem + input logic mem_wreg_i_2, + input logic [`RegAddrBus] mem_waddr_i_2, + input logic [`RegBus] mem_wdata_i_2, + + // -> Regfile + output reg reg1_read_o, + output reg reg2_read_o, + + // -> EXE + output reg [`RegAddrBus] reg1_addr_o, + output reg [`RegAddrBus] reg2_addr_o, + output reg [`AluOpBus] aluop_o, + output reg [`AluSelBus] alusel_o, + output reg [`RegBus] reg1_o, + output reg [`RegBus] reg2_o, + output reg [`RegAddrBus] reg_waddr_o, + output reg wreg_o, + output reg inst_valid, + output reg [`InstAddrBus] inst_pc, + output logic [`RegBus] inst_o, + output logic [`RegBus] current_inst_address_o, + output reg csr_we, + output csr_write_signal csr_signal_o, + output logic excp_o, + output logic [8:0] excp_num_o, + + // <- CSR + input logic has_int, + input logic [`RegBus] csr_data_i, + input logic [1:0] csr_plv, + + // -> CSR + output reg [13:0] csr_read_addr_o, + + // -> PC + output reg branch_flag_o, + output reg [`RegBus] branch_target_address_o, + output reg [`RegBus] link_addr_o, + output reg [`InstAddrBus] idle_pc, + + // ->Ctrl + output logic stallreq, + output reg idle_stallreq +); + + logic [`InstAddrBus] pc_i; + assign pc_i = instr_buffer_i.valid ? instr_buffer_i.pc : `ZeroWord; + logic [`InstBus] inst_i; + assign inst_i = instr_buffer_i.valid ? instr_buffer_i.instr : `ZeroWord; + + + logic [ 5:0] opcode_6 = inst_i[31:26]; + logic [ 6:0] opcode_7 = inst_i[31:25]; + logic [ 7:0] opcode_8 = inst_i[31:24]; + logic [ 9:0] opcode_10 = inst_i[31:22]; + logic [13:0] opcode_14 = inst_i[31:18]; + logic [16:0] opcode_17 = inst_i[31:15]; + logic [21:0] opcode_22 = inst_i[31:10]; + logic [ 4:0] imm_5 = inst_i[14:10]; + logic [ 9:0] imm_10 = inst_i[9:0]; + logic [13:0] imm_14 = inst_i[23:10]; + logic [15:0] imm_16 = inst_i[25:10]; + logic [11:0] imm_12 = inst_i[21:10]; + logic [19:0] imm_20 = inst_i[24:5]; + logic [ 4:0] op1; + assign op1 = inst_i[4:0]; + logic [4:0] op2 = inst_i[9:5]; + logic [4:0] op3 = inst_i[14:10]; + logic [4:0] op4 = inst_i[19:15]; + + logic [5:0] opcode_1 = inst_i[31:26]; + logic [5:0] opcode_2 = inst_i[25:20]; + logic [4:0] opcode_3 = inst_i[19:15]; + logic [4:0] opcode_4 = inst_i[14:10]; + + logic [`RegBus] pc_plus_4; + + assign pc_plus_4 = pc_i + 4; + assign inst_o = inst_i; + + reg [`RegBus] imm; + + reg stallreq_for_reg1_loadrelate; + reg stallreq_for_reg2_loadrelate; + logic pre_inst_is_load; + + + logic res_from_csr; + logic excp_ine; + logic excp_ipe; + + assign pre_inst_is_load = (((ex_aluop_i_1 == `EXE_LD_B_OP) || + (ex_aluop_i_1 == `EXE_LD_H_OP) || + (ex_aluop_i_1 == `EXE_LD_W_OP) || + (ex_aluop_i_1 == `EXE_LD_BU_OP) || + (ex_aluop_i_1 == `EXE_LD_HU_OP) || + (ex_aluop_i_1 == `EXE_ST_B_OP) || + (ex_aluop_i_1 == `EXE_ST_H_OP) || + (ex_aluop_i_1 == `EXE_ST_W_OP))||( + (ex_aluop_i_2 == `EXE_LD_B_OP) || + (ex_aluop_i_2 == `EXE_LD_H_OP) || + (ex_aluop_i_2 == `EXE_LD_W_OP) || + (ex_aluop_i_2 == `EXE_LD_BU_OP) || + (ex_aluop_i_2 == `EXE_LD_HU_OP) || + (ex_aluop_i_2 == `EXE_ST_B_OP) || + (ex_aluop_i_2 == `EXE_ST_H_OP) || + (ex_aluop_i_2 == `EXE_ST_W_OP)) && (pc_i == instr_buffer_i_other.pc + 4)) ? 1'b1 : 1'b0; + + reg inst_syscall; + reg inst_break; + reg kernel_inst; + + + + assign current_inst_address_o = pc_i; + + + assign excp_ine = (inst_valid == `InstInvalid) && instr_buffer_i.valid; + assign excp_ipe = kernel_inst && (csr_plv == 2'b11); + + assign excp_o = excp_ipe | inst_syscall | inst_break | excp_i | excp_ine | has_int; + assign excp_num_o = {excp_ipe, excp_ine, inst_break, inst_syscall, excp_num_i, has_int}; + + + always @(*) begin + if (rst == `RstEnable) stallreq_for_reg1_loadrelate = `NoStop; + else if (pre_inst_is_load == 1'b1 && ex_waddr_i_1 == reg1_addr_o && reg1_read_o == 1'b1) + stallreq_for_reg1_loadrelate = `Stop; + end + + always @(*) begin + + if (rst == `RstEnable) stallreq_for_reg2_loadrelate = `NoStop; + else if (pre_inst_is_load == 1'b1 && ex_waddr_i_1 == reg2_addr_o && reg2_read_o == 1'b1) + stallreq_for_reg2_loadrelate = `Stop; + end + + //如果这条指令与另一条相邻且存在依赖就直接暂停 + assign stallreq = stallreq_for_reg1_loadrelate | stallreq_for_reg2_loadrelate; + + always @(*) begin + inst_pc = pc_i; + end + + always @(*) begin + if (rst == `RstEnable) begin + aluop_o = `EXE_NOP_OP; + alusel_o = `EXE_RES_NOP; + reg_waddr_o = `NOPRegAddr; + wreg_o = `WriteDisable; + inst_valid = `InstInvalid; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + reg1_addr_o = `NOPRegAddr; + reg2_addr_o = `NOPRegAddr; + imm = 32'h0; + branch_flag_o = `NotBranch; + branch_target_address_o = `ZeroWord; + link_addr_o = `ZeroWord; + inst_break = `False_v; + inst_syscall = `False_v; + idle_stallreq = 1'b0; + end else begin + aluop_o = `EXE_NOP_OP; + alusel_o = `EXE_RES_NOP; + reg_waddr_o = op1; + wreg_o = `WriteDisable; + inst_valid = `InstInvalid; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + reg1_addr_o = op2; + reg2_addr_o = op3; + imm = `ZeroWord; + branch_flag_o = `NotBranch; + branch_target_address_o = `ZeroWord; + link_addr_o = `ZeroWord; + idle_stallreq = 1'b0; + case (opcode_1) + `EXE_JIRL: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_JIRL_OP; + alusel_o = `EXE_RES_JUMP; + reg1_read_o = 1'b1; + reg2_read_o = 1'b0; + link_addr_o = pc_plus_4; + branch_flag_o = `Branch; + branch_target_address_o = reg1_o + {{14{imm_16[15]}}, imm_16, 2'b0}; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_B: begin + wreg_o = `WriteDisable; + aluop_o = `EXE_B_OP; + alusel_o = `EXE_RES_JUMP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + branch_flag_o = `Branch; + branch_target_address_o = pc_i + {{4{imm_10[9]}}, imm_10, imm_16, 2'b0}; + inst_valid = `InstValid; + end + `EXE_BL: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_BL_OP; + alusel_o = `EXE_RES_JUMP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + branch_flag_o = `Branch; + link_addr_o = pc_plus_4; + branch_target_address_o = pc_i + {{4{imm_10[9]}}, imm_10, imm_16, 2'b0}; + reg_waddr_o = 5'b1; + inst_valid = `InstValid; + end + `EXE_BEQ: begin + wreg_o = `WriteDisable; + aluop_o = `EXE_BEQ_OP; + alusel_o = `EXE_RES_JUMP; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg1_addr_o = op2; + reg2_addr_o = op1; + if (reg1_o == reg2_o) begin + branch_flag_o = `Branch; + branch_target_address_o = pc_i + {{14{imm_16[15]}}, imm_16, 2'b0}; + end + inst_valid = `InstValid; + end + `EXE_BNE: begin + wreg_o = `WriteDisable; + aluop_o = `EXE_BNE_OP; + alusel_o = `EXE_RES_JUMP; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg1_addr_o = op2; + reg2_addr_o = op1; + if (reg1_o != reg2_o) begin + branch_flag_o = `Branch; + branch_target_address_o = pc_i + {{14{imm_16[15]}}, imm_16, 2'b0}; + end + inst_valid = `InstValid; + end + `EXE_BLT: begin + wreg_o = `WriteDisable; + aluop_o = `EXE_BLT_OP; + alusel_o = `EXE_RES_JUMP; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg1_addr_o = op2; + reg2_addr_o = op1; + if ({~reg1_o[31], reg1_o[30:0]} < {~reg2_o[31], reg2_o[30:0]}) begin + branch_flag_o = `Branch; + branch_target_address_o = pc_i + {{14{imm_16[15]}}, imm_16, 2'b0}; + end + inst_valid = `InstValid; + end + `EXE_BGE: begin + wreg_o = `WriteDisable; + aluop_o = `EXE_BGE_OP; + alusel_o = `EXE_RES_JUMP; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg1_addr_o = op2; + reg2_addr_o = op1; + if ({~reg1_o[31], reg1_o[30:0]} >= {~reg2_o[31], reg2_o[30:0]}) begin + branch_flag_o = `Branch; + branch_target_address_o = pc_i + {{14{imm_16[15]}}, imm_16, 2'b0}; + end + inst_valid = `InstValid; + end + `EXE_BLTU: begin + wreg_o = `WriteDisable; + aluop_o = `EXE_BLTU_OP; + alusel_o = `EXE_RES_JUMP; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg1_addr_o = op2; + reg2_addr_o = op1; + if (reg1_o < reg2_o) begin + branch_flag_o = `Branch; + branch_target_address_o = pc_i + {{14{imm_16[15]}}, imm_16, 2'b0}; + end + inst_valid = `InstValid; + end + `EXE_BGEU: begin + wreg_o = `WriteDisable; + aluop_o = `EXE_BGEU_OP; + alusel_o = `EXE_RES_JUMP; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg1_addr_o = op2; + reg2_addr_o = op1; + if (reg1_o >= reg2_o) begin + branch_flag_o = `Branch; + branch_target_address_o = pc_i + {{14{imm_16[15]}}, imm_16, 2'b0}; + end + inst_valid = `InstValid; + end + `EXE_LU12I_W: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_LUI_OP; + alusel_o = `EXE_RES_MOVE; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + imm = {imm_20, 12'b0}; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_PCADDU12I: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_PCADD_OP; + alusel_o = `EXE_RES_MOVE; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + imm = {imm_20, 12'b0}; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_ATOMIC_MEM: begin + casez (opcode_2) + `EXE_LL_W: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_LL_OP; + alusel_o = `EXE_RES_LOAD_STORE; + reg1_read_o = 1'b1; + reg2_read_o = 1'b0; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_SC_W: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_SC_OP; + alusel_o = `EXE_RES_LOAD_STORE; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg2_addr_o = op1; + inst_valid = `InstValid; + end + default: begin + end + endcase + end + `EXE_MEM_RELATED: begin + casez (opcode_2) + `EXE_LD_B: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_LD_B_OP; + alusel_o = `EXE_RES_LOAD_STORE; + reg1_read_o = 1'b1; + reg2_read_o = 1'b0; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_LD_H: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_LD_H_OP; + alusel_o = `EXE_RES_LOAD_STORE; + reg1_read_o = 1'b1; + reg2_read_o = 1'b0; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_LD_W: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_LD_W_OP; + alusel_o = `EXE_RES_LOAD_STORE; + reg1_read_o = 1'b1; + reg2_read_o = 1'b0; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_ST_B: begin + wreg_o = `WriteDisable; + aluop_o = `EXE_ST_B_OP; + alusel_o = `EXE_RES_LOAD_STORE; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg2_addr_o = op1; + inst_valid = `InstValid; + end + `EXE_ST_H: begin + wreg_o = `WriteDisable; + aluop_o = `EXE_ST_H_OP; + alusel_o = `EXE_RES_LOAD_STORE; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg2_addr_o = op1; + inst_valid = `InstValid; + end + `EXE_ST_W: begin + wreg_o = `WriteDisable; + aluop_o = `EXE_ST_W_OP; + alusel_o = `EXE_RES_LOAD_STORE; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg2_addr_o = op1; + inst_valid = `InstValid; + end + `EXE_LD_BU: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_LD_BU_OP; + alusel_o = `EXE_RES_LOAD_STORE; + reg1_read_o = 1'b1; + reg2_read_o = 1'b0; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_LD_HU: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_LD_HU_OP; + alusel_o = `EXE_RES_LOAD_STORE; + reg1_read_o = 1'b1; + reg2_read_o = 1'b0; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + default: begin + end + endcase + end + + `EXE_SPECIAL: begin + case (opcode_2) + `EXE_CSR_RELATED: begin + case (op2) + `EXE_CSRRD: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_CSRRD_OP; + reg1_read_o = 1'b1; + reg2_read_o = 1'b0; + imm = {18'b0, imm_14}; + csr_signal_o.we = 1'b1; + csr_signal_o.addr = imm_14; + csr_signal_o.data = `ZeroWord; + reg_waddr_o = op1; + inst_valid = `InstValid; + res_from_csr = 1'b1; + kernel_inst = 1'b1; + end + `EXE_CSRWR: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_CSRWR_OP; + reg1_read_o = 1'b1; + reg2_read_o = 1'b0; + imm = {18'b0, imm_14}; + csr_signal_o.we = 1'b1; + csr_signal_o.addr = imm_14; + csr_signal_o.data = reg1_data_i; + reg1_addr_o = op1; + reg_waddr_o = op1; + inst_valid = `InstValid; + res_from_csr = 1'b1; + kernel_inst = 1'b1; + end + default: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_CSRXCHG_OP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + imm = {18'b0, imm_14}; + csr_signal_o.we = 1'b1; + csr_signal_o.addr = imm_14; + csr_signal_o.data = reg1_data_i; + reg_waddr_o = op1; + inst_valid = `InstValid; + res_from_csr = 1'b1; + kernel_inst = 1'b1; + end + endcase + end + `EXE_OTHER: begin + case (opcode_3) + `EXE_TLB_RELATED: begin + case (opcode_22) + `EXE_TLBFILL: begin + wreg_o = `WriteDisable; + aluop_o = `EXE_TLBFILL_OP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + inst_valid = `InstValid; + kernel_inst = 1'b1; + end + `EXE_TLBRD: begin + wreg_o = `WriteDisable; + aluop_o = `EXE_TLBRD_OP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + inst_valid = `InstValid; + kernel_inst = 1'b1; + end + `EXE_TLBSRCH: begin + wreg_o = `WriteDisable; + aluop_o = `EXE_TLBSRCH_OP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + inst_valid = `InstValid; + kernel_inst = 1'b1; + end + `EXE_TLBWR: begin + wreg_o = `WriteDisable; + aluop_o = `EXE_TLBWR_OP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + inst_valid = `InstValid; + kernel_inst = 1'b1; + end + `EXE_ERTN: begin + wreg_o = `WriteDisable; + aluop_o = `EXE_ERTN_OP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + inst_valid = `InstValid; + kernel_inst = 1'b1; + end + default: begin + end + endcase + end + default: begin + case (opcode_17) + `EXE_IDLE: begin + wreg_o = `WriteDisable; + aluop_o = `EXE_IDLE_OP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + idle_stallreq = 1; + idle_pc = pc_i + 32'h4; + inst_valid = `InstValid; + kernel_inst = 1'b1; + end + `EXE_INVTLB: begin + wreg_o = `WriteDisable; + aluop_o = `EXE_INVTLB_OP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + inst_valid = `InstValid; + kernel_inst = 1'b1; + end + default: begin + end + endcase + end + endcase + end + default: begin + end + endcase + end + + `EXE_ARITHMETIC: begin + casez (opcode_2) + `EXE_SLTI: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_SLT_OP; + alusel_o = `EXE_RES_ARITH; + reg1_read_o = 1'b1; + reg2_read_o = 1'b0; + imm = {{20{imm_12[11]}}, imm_12}; // Signed Extension + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_SLTUI: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_SLTU_OP; + alusel_o = `EXE_RES_ARITH; + reg1_read_o = 1'b1; + reg2_read_o = 1'b0; + imm = {{20{imm_12[11]}}, imm_12}; // Signed Extension + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_ADDI_W: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_ADD_OP; + alusel_o = `EXE_RES_ARITH; + reg1_read_o = 1'b1; + reg2_read_o = 1'b0; + imm = {{20{imm_12[11]}}, imm_12}; // Signed Extension + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_ANDI: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_AND_OP; + alusel_o = `EXE_RES_LOGIC; + reg1_read_o = 1'b1; + reg2_read_o = 1'b0; + imm = {20'h0, imm_12}; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_ORI: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_OR_OP; + alusel_o = `EXE_RES_LOGIC; + reg1_read_o = 1'b1; + reg2_read_o = 1'b0; + imm = {20'h0, imm_12}; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_XORI: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_XOR_OP; + alusel_o = `EXE_RES_LOGIC; + reg1_read_o = 1'b1; + reg2_read_o = 1'b0; + imm = {20'h0, imm_12}; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_LONG_ARITH: begin + case (opcode_3) + `EXE_ADD_W: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_ADD_OP; + alusel_o = `EXE_RES_ARITH; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_SUB_W: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_SUB_OP; + alusel_o = `EXE_RES_ARITH; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_SLT: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_SLT_OP; + alusel_o = `EXE_RES_ARITH; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_SLTU: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_SLTU_OP; + alusel_o = `EXE_RES_ARITH; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_NOR: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_NOR_OP; + alusel_o = `EXE_RES_LOGIC; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_AND: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_AND_OP; + alusel_o = `EXE_RES_LOGIC; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_OR: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_OR_OP; + alusel_o = `EXE_RES_LOGIC; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_XOR: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_XOR_OP; + alusel_o = `EXE_RES_LOGIC; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_SLL_W: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_SLL_OP; + alusel_o = `EXE_RES_SHIFT; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_SRL_W: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_SRL_OP; + alusel_o = `EXE_RES_SHIFT; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_SRA_W: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_SRA_OP; + alusel_o = `EXE_RES_SHIFT; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_MUL_W: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_MUL_OP; + alusel_o = `EXE_RES_ARITH; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_MULH_W: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_MULH_OP; + alusel_o = `EXE_RES_ARITH; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_MULH_WU: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_MULHU_OP; + alusel_o = `EXE_RES_ARITH; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + default: begin + end + + endcase + end + `EXE_DIV_ARITH: begin + casez (opcode_3) + `EXE_DIV_W: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_DIV_OP; + alusel_o = `EXE_RES_ARITH; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_MOD_W: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_MOD_OP; + alusel_o = `EXE_RES_ARITH; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_DIV_WU: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_DIV_OP; + alusel_o = `EXE_RES_ARITH; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_MOD_WU: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_MOD_OP; + alusel_o = `EXE_RES_ARITH; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_BREAK: begin + wreg_o = `WriteDisable; + aluop_o = `EXE_BREAK_OP; + alusel_o = `EXE_RES_NOP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + inst_valid = `InstValid; + inst_break = `True_v; + end + `EXE_SYSCALL: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_SYSCALL_OP; + alusel_o = `EXE_RES_NOP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + inst_valid = `InstValid; + inst_syscall = `True_v; + end + default: begin + end + endcase + end + `EXE_SHIFT_ARITH: begin + casez (opcode_3) + `EXE_SLLI_W: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_SLL_OP; + alusel_o = `EXE_RES_SHIFT; + reg1_read_o = 1'b1; + reg2_read_o = 1'b0; + imm = {27'b0, imm_5}; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_SRLI_W: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_SRL_OP; + alusel_o = `EXE_RES_SHIFT; + reg1_read_o = 1'b1; + reg2_read_o = 1'b0; + imm = {27'b0, imm_5}; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_SRAI_W: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_SRA_OP; + alusel_o = `EXE_RES_SHIFT; + reg1_read_o = 1'b1; + reg2_read_o = 1'b0; + imm = {27'b0, imm_5}; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + default: begin + end + endcase + end + default: begin + + end + endcase + end + default: begin + end + endcase + end + end + + always @(*) begin + if (rst == `RstEnable) reg1_o = `ZeroWord; + else if (opcode_2[5:4] == 2'b00) + reg1_o = csr_data_i; // EXE_CSR_RELATED, TODO: replace magic number + else if ((reg1_read_o == 1'b1) && (reg1_addr_o == 0)) reg1_o = `ZeroWord; + else if ((reg1_read_o == 1'b1) && (ex_wreg_i_2 == 1'b1) && (ex_waddr_i_2 == reg1_addr_o)) + reg1_o = ex_wdata_i_2; + else if ((reg1_read_o == 1'b1) && (mem_wreg_i_2 == 1'b1) && (mem_waddr_i_2 == reg1_addr_o)) + reg1_o = mem_wdata_i_2; + else if ((reg1_read_o == 1'b1) && (ex_wreg_i_1 == 1'b1) && (ex_waddr_i_1 == reg1_addr_o)) + reg1_o = ex_wdata_i_1; + else if ((reg1_read_o == 1'b1) && (mem_wreg_i_1 == 1'b1) && (mem_waddr_i_1 == reg1_addr_o)) + reg1_o = mem_wdata_i_1; + else if (reg1_read_o == 1'b1) reg1_o = reg1_data_i; + else if (reg1_read_o == 1'b0) reg1_o = imm; + else reg1_o = `ZeroWord; + end + + always @(*) begin + if (rst == `RstEnable) reg2_o = `ZeroWord; + else if (opcode_2[5:4] == 2'b00) reg2_o = `ZeroWord; + else if ((reg2_read_o == 1'b1) && (reg2_addr_o == 0)) reg2_o = `ZeroWord; + else if ((reg2_read_o == 1'b1) && (ex_wreg_i_2 == 1'b1) && (ex_waddr_i_2 == reg2_addr_o)) + reg2_o = ex_wdata_i_2; + else if ((reg2_read_o == 1'b1) && (mem_wreg_i_2 == 1'b1) && (mem_waddr_i_2 == reg2_addr_o)) + reg2_o = mem_wdata_i_2; + else if ((reg2_read_o == 1'b1) && (ex_wreg_i_1 == 1'b1) && (ex_waddr_i_1 == reg2_addr_o)) + reg2_o = ex_wdata_i_1; + else if ((reg2_read_o == 1'b1) && (mem_wreg_i_1 == 1'b1) && (mem_waddr_i_1 == reg2_addr_o)) + reg2_o = mem_wdata_i_1; + else if (reg2_read_o == 1'b1) reg2_o = reg2_data_i; + else if (reg2_read_o == 1'b0) reg2_o = imm; + else reg2_o = `ZeroWord; + end + +endmodule diff --git a/src/vsrc/pipeline/2_decode/id_old.sv b/src/vsrc/pipeline/2_decode/id_old.sv new file mode 100644 index 0000000..a51fde5 --- /dev/null +++ b/src/vsrc/pipeline/2_decode/id_old.sv @@ -0,0 +1,427 @@ +`timescale 1ns / 1ns + +`include "defines.sv" +`include "instr_info.sv" +`include "csr_defines.sv" + + + +module id ( + input logic rst, + + // <- Instruction Buffer + input instr_buffer_info_t instr_buffer_i, + + + input logic excp_i, + input logic [3:0] excp_num_i, + + // <- Regfile + input logic [`RegBus] reg1_data_i, + input logic [`RegBus] reg2_data_i, + + input instr_buffer_info_t instr_buffer_i_other, + + // <- EXE + input logic ex_wreg_i_1, + input logic [`RegAddrBus] ex_waddr_i_1, + input logic [`RegBus] ex_wdata_i_1, + input logic [`AluOpBus] ex_aluop_i_1, + + + // <- ANOTHER_EXE + input logic ex_wreg_i_2, + input logic [`RegAddrBus] ex_waddr_i_2, + input logic [`RegBus] ex_wdata_i_2, + input logic [`AluOpBus] ex_aluop_i_2, + + // <- Mem + input logic mem_wreg_i_1, + input logic [`RegAddrBus] mem_waddr_i_1, + input logic [`RegBus] mem_wdata_i_1, + + // <- ANOTHER_Mem + input logic mem_wreg_i_2, + input logic [`RegAddrBus] mem_waddr_i_2, + input logic [`RegBus] mem_wdata_i_2, + + // -> Regfile + output reg reg1_read_o, + output reg reg2_read_o, + + // -> EXE + output reg [`RegAddrBus] reg1_addr_o, + output reg [`RegAddrBus] reg2_addr_o, + output reg [`AluOpBus] aluop_o, + output reg [`AluSelBus] alusel_o, + output reg [`RegBus] reg1_o, + output reg [`RegBus] reg2_o, + output reg [`RegAddrBus] reg_waddr_o, + output reg wreg_o, + output reg inst_valid, + output reg [`InstAddrBus] inst_pc, + output logic [`RegBus] inst_o, + output logic [`RegBus] current_inst_address_o, + output reg csr_we, + output csr_write_signal csr_signal_o, + output logic excp_o, + output logic [8:0] excp_num_o, + + // <- CSR + input logic has_int, + input logic [`RegBus] csr_data_i, + input logic [1:0] csr_plv, + + // -> CSR + output reg [13:0] csr_read_addr_o, + + // -> PC + output reg branch_flag_o, + output reg [`RegBus] branch_target_address_o, + output reg [`RegBus] link_addr_o, + output reg [`InstAddrBus] idle_pc, + + // ->Ctrl + output logic stallreq, + output reg idle_stallreq +); + + logic [`InstAddrBus] pc_i; + assign pc_i = instr_buffer_i.valid ? instr_buffer_i.pc : `ZeroWord; + logic [`InstBus] inst_i; + assign inst_i = instr_buffer_i.valid ? instr_buffer_i.instr : `ZeroWord; + + + logic [ 5:0] opcode_6 = inst_i[31:26]; + logic [ 6:0] opcode_7 = inst_i[31:25]; + logic [ 7:0] opcode_8 = inst_i[31:24]; + logic [ 9:0] opcode_10 = inst_i[31:22]; + logic [13:0] opcode_14 = inst_i[31:18]; + logic [16:0] opcode_17 = inst_i[31:15]; + logic [21:0] opcode_22 = inst_i[31:10]; + logic [ 4:0] imm_5 = inst_i[14:10]; + logic [ 9:0] imm_10 = inst_i[9:0]; + logic [13:0] imm_14 = inst_i[23:10]; + logic [15:0] imm_16 = inst_i[25:10]; + logic [11:0] imm_12 = inst_i[21:10]; + logic [19:0] imm_20 = inst_i[24:5]; + logic [ 4:0] op1; + assign op1 = inst_i[4:0]; + logic [4:0] op2 = inst_i[9:5]; + logic [4:0] op3 = inst_i[14:10]; + logic [4:0] op4 = inst_i[19:15]; + + logic [5:0] opcode_1 = inst_i[31:26]; + logic [5:0] opcode_2 = inst_i[25:20]; + logic [4:0] opcode_3 = inst_i[19:15]; + logic [4:0] opcode_4 = inst_i[14:10]; + + logic [`RegBus] pc_plus_4; + + assign pc_plus_4 = pc_i + 4; + assign inst_o = inst_i; + + reg [`RegBus] imm; + + reg stallreq_for_reg1_loadrelate; + reg stallreq_for_reg2_loadrelate; + logic pre_inst_is_load; + + + logic res_from_csr; + logic excp_ine; + logic excp_ipe; + + assign pre_inst_is_load = (((ex_aluop_i_1 == `EXE_LD_B_OP) || + (ex_aluop_i_1 == `EXE_LD_H_OP) || + (ex_aluop_i_1 == `EXE_LD_W_OP) || + (ex_aluop_i_1 == `EXE_LD_BU_OP) || + (ex_aluop_i_1 == `EXE_LD_HU_OP) || + (ex_aluop_i_1 == `EXE_ST_B_OP) || + (ex_aluop_i_1 == `EXE_ST_H_OP) || + (ex_aluop_i_1 == `EXE_ST_W_OP))||( + (ex_aluop_i_2 == `EXE_LD_B_OP) || + (ex_aluop_i_2 == `EXE_LD_H_OP) || + (ex_aluop_i_2 == `EXE_LD_W_OP) || + (ex_aluop_i_2 == `EXE_LD_BU_OP) || + (ex_aluop_i_2 == `EXE_LD_HU_OP) || + (ex_aluop_i_2 == `EXE_ST_B_OP) || + (ex_aluop_i_2 == `EXE_ST_H_OP) || + (ex_aluop_i_2 == `EXE_ST_W_OP)) && (pc_i == instr_buffer_i_other.pc + 4)) ? 1'b1 : 1'b0; + + reg inst_syscall; + reg inst_break; + reg kernel_inst; + + + + assign current_inst_address_o = pc_i; + + + assign excp_ine = (inst_valid == `InstInvalid) && instr_buffer_i.valid; + assign excp_ipe = kernel_inst && (csr_plv == 2'b11); + + assign excp_o = excp_ipe | inst_syscall | inst_break | excp_i | excp_ine | has_int; + assign excp_num_o = {excp_ipe, excp_ine, inst_break, inst_syscall, excp_num_i, has_int}; + + + always @(*) begin + if (rst == `RstEnable) stallreq_for_reg1_loadrelate = `NoStop; + else if (pre_inst_is_load == 1'b1 && ex_waddr_i_1 == reg1_addr_o && reg1_read_o == 1'b1) + stallreq_for_reg1_loadrelate = `Stop; + end + + always @(*) begin + + if (rst == `RstEnable) stallreq_for_reg2_loadrelate = `NoStop; + else if (pre_inst_is_load == 1'b1 && ex_waddr_i_1 == reg2_addr_o && reg2_read_o == 1'b1) + stallreq_for_reg2_loadrelate = `Stop; + end + + //如果这条指令与另一条相邻且存在依赖就直接暂停 + assign stallreq = stallreq_for_reg1_loadrelate | stallreq_for_reg2_loadrelate; + + always @(*) begin + inst_pc = pc_i; + end + + always @(*) begin + if (rst == `RstEnable) begin + aluop_o = `EXE_NOP_OP; + alusel_o = `EXE_RES_NOP; + reg_waddr_o = `NOPRegAddr; + wreg_o = `WriteDisable; + inst_valid = `InstInvalid; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + reg1_addr_o = `NOPRegAddr; + reg2_addr_o = `NOPRegAddr; + imm = 32'h0; + branch_flag_o = `NotBranch; + branch_target_address_o = `ZeroWord; + link_addr_o = `ZeroWord; + inst_break = `False_v; + inst_syscall = `False_v; + idle_stallreq = 1'b0; + end else begin + aluop_o = `EXE_NOP_OP; + alusel_o = `EXE_RES_NOP; + reg_waddr_o = op1; + wreg_o = `WriteDisable; + inst_valid = `InstInvalid; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + reg1_addr_o = op2; + reg2_addr_o = op3; + imm = `ZeroWord; + branch_flag_o = `NotBranch; + branch_target_address_o = `ZeroWord; + link_addr_o = `ZeroWord; + idle_stallreq = 1'b0; + case (opcode_1) + `EXE_B: begin + wreg_o = `WriteDisable; + aluop_o = `EXE_B_OP; + alusel_o = `EXE_RES_JUMP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + branch_flag_o = `Branch; + branch_target_address_o = pc_i + {{4{imm_10[9]}}, imm_10, imm_16, 2'b0}; + inst_valid = `InstValid; + end + `EXE_BL: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_BL_OP; + alusel_o = `EXE_RES_JUMP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + branch_flag_o = `Branch; + link_addr_o = pc_plus_4; + branch_target_address_o = pc_i + {{4{imm_10[9]}}, imm_10, imm_16, 2'b0}; + reg_waddr_o = 5'b1; + inst_valid = `InstValid; + end + `EXE_LU12I_W: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_LUI_OP; + alusel_o = `EXE_RES_MOVE; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + imm = {imm_20, 12'b0}; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_PCADDU12I: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_PCADD_OP; + alusel_o = `EXE_RES_MOVE; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + imm = {imm_20, 12'b0}; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_ATOMIC_MEM: begin + casez (opcode_2) + `EXE_LL_W: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_LL_OP; + alusel_o = `EXE_RES_LOAD_STORE; + reg1_read_o = 1'b1; + reg2_read_o = 1'b0; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_SC_W: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_SC_OP; + alusel_o = `EXE_RES_LOAD_STORE; + reg1_read_o = 1'b1; + reg2_read_o = 1'b1; + reg2_addr_o = op1; + inst_valid = `InstValid; + end + default: begin + end + endcase + end + + `EXE_SPECIAL: begin + case (opcode_2) + `EXE_CSR_RELATED: begin + case (op2) + `EXE_CSRRD: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_CSRRD_OP; + reg1_read_o = 1'b1; + reg2_read_o = 1'b0; + imm = {18'b0, imm_14}; + csr_signal_o.we = 1'b1; + csr_signal_o.addr = imm_14; + csr_signal_o.data = `ZeroWord; + reg_waddr_o = op1; + inst_valid = `InstValid; + res_from_csr = 1'b1; + kernel_inst = 1'b1; + end + `EXE_CSRWR: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_CSRWR_OP; + reg1_read_o = 1'b1; + reg2_read_o = 1'b0; + imm = {18'b0, imm_14}; + csr_signal_o.we = 1'b1; + csr_signal_o.addr = imm_14; + csr_signal_o.data = reg1_data_i; + reg1_addr_o = op1; + reg_waddr_o = op1; + inst_valid = `InstValid; + res_from_csr = 1'b1; + kernel_inst = 1'b1; + end + default: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_CSRXCHG_OP; + reg1_read_o = 1'b0; + reg2_read_o = 1'b0; + imm = {18'b0, imm_14}; + csr_signal_o.we = 1'b1; + csr_signal_o.addr = imm_14; + csr_signal_o.data = reg1_data_i; + reg_waddr_o = op1; + inst_valid = `InstValid; + res_from_csr = 1'b1; + kernel_inst = 1'b1; + end + endcase + end + endcase + end + + `EXE_ARITHMETIC: begin + casez (opcode_2) + + + `EXE_SHIFT_ARITH: begin + casez (opcode_3) + `EXE_SLLI_W: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_SLL_OP; + alusel_o = `EXE_RES_SHIFT; + reg1_read_o = 1'b1; + reg2_read_o = 1'b0; + imm = {27'b0, imm_5}; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_SRLI_W: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_SRL_OP; + alusel_o = `EXE_RES_SHIFT; + reg1_read_o = 1'b1; + reg2_read_o = 1'b0; + imm = {27'b0, imm_5}; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + `EXE_SRAI_W: begin + wreg_o = `WriteEnable; + aluop_o = `EXE_SRA_OP; + alusel_o = `EXE_RES_SHIFT; + reg1_read_o = 1'b1; + reg2_read_o = 1'b0; + imm = {27'b0, imm_5}; + reg_waddr_o = op1; + inst_valid = `InstValid; + end + default: begin + end + endcase + end + default: begin + + end + endcase + end + default: begin + end + endcase + end + end + + always @(*) begin + if (rst == `RstEnable) reg1_o = `ZeroWord; + else if (opcode_2[5:4] == 2'b00) + reg1_o = csr_data_i; // EXE_CSR_RELATED, TODO: replace magic number + else if ((reg1_read_o == 1'b1) && (reg1_addr_o == 0)) reg1_o = `ZeroWord; + else if ((reg1_read_o == 1'b1) && (ex_wreg_i_2 == 1'b1) && (ex_waddr_i_2 == reg1_addr_o)) + reg1_o = ex_wdata_i_2; + else if ((reg1_read_o == 1'b1) && (mem_wreg_i_2 == 1'b1) && (mem_waddr_i_2 == reg1_addr_o)) + reg1_o = mem_wdata_i_2; + else if ((reg1_read_o == 1'b1) && (ex_wreg_i_1 == 1'b1) && (ex_waddr_i_1 == reg1_addr_o)) + reg1_o = ex_wdata_i_1; + else if ((reg1_read_o == 1'b1) && (mem_wreg_i_1 == 1'b1) && (mem_waddr_i_1 == reg1_addr_o)) + reg1_o = mem_wdata_i_1; + else if (reg1_read_o == 1'b1) reg1_o = reg1_data_i; + else if (reg1_read_o == 1'b0) reg1_o = imm; + else reg1_o = `ZeroWord; + end + + always @(*) begin + if (rst == `RstEnable) reg2_o = `ZeroWord; + else if (opcode_2[5:4] == 2'b00) reg2_o = `ZeroWord; + else if ((reg2_read_o == 1'b1) && (reg2_addr_o == 0)) reg2_o = `ZeroWord; + else if ((reg2_read_o == 1'b1) && (ex_wreg_i_2 == 1'b1) && (ex_waddr_i_2 == reg2_addr_o)) + reg2_o = ex_wdata_i_2; + else if ((reg2_read_o == 1'b1) && (mem_wreg_i_2 == 1'b1) && (mem_waddr_i_2 == reg2_addr_o)) + reg2_o = mem_wdata_i_2; + else if ((reg2_read_o == 1'b1) && (ex_wreg_i_1 == 1'b1) && (ex_waddr_i_1 == reg2_addr_o)) + reg2_o = ex_wdata_i_1; + else if ((reg2_read_o == 1'b1) && (mem_wreg_i_1 == 1'b1) && (mem_waddr_i_1 == reg2_addr_o)) + reg2_o = mem_wdata_i_1; + else if (reg2_read_o == 1'b1) reg2_o = reg2_data_i; + else if (reg2_read_o == 1'b0) reg2_o = imm; + else reg2_o = `ZeroWord; + end + +endmodule diff --git a/src/vsrc/regfile.sv b/src/vsrc/regfile.sv index 85804bc..58d0a4c 100644 --- a/src/vsrc/regfile.sv +++ b/src/vsrc/regfile.sv @@ -27,11 +27,12 @@ module regfile ( output reg [`RegBus] rdata2_2 ); + // Used in difftest, should named regs reg [`RegBus] regs[0:`RegNum-1]; always @(posedge clk) begin if (rst == `RstEnable) begin - for (integer i = 0; i < 32; i = i + 1) begin + for (integer i = 0; i < `RegNum; i = i + 1) begin regs[i] <= 0; end end else begin //同时写入一个位置,将后面的写入 From e185c7f60b3bfa655abb06b9354112576d4a9fac Mon Sep 17 00:00:00 2001 From: Easton Man Date: Sat, 7 May 2022 10:23:57 +0800 Subject: [PATCH 075/114] refactor: add ID wires to Regfile --- src/vsrc/cpu_top.sv | 273 ++++++-------------- src/vsrc/defines.sv | 56 ++-- src/vsrc/pipeline/2_decode/decoder_2RI12.sv | 4 + src/vsrc/pipeline/2_decode/decoder_2RI16.sv | 4 + src/vsrc/pipeline/2_decode/decoder_3R.sv | 8 +- src/vsrc/pipeline/2_decode/id.sv | 7 +- src/vsrc/regfile.sv | 75 ++---- 7 files changed, 144 insertions(+), 283 deletions(-) diff --git a/src/vsrc/cpu_top.sv b/src/vsrc/cpu_top.sv index 6748772..66488f2 100644 --- a/src/vsrc/cpu_top.sv +++ b/src/vsrc/cpu_top.sv @@ -210,7 +210,7 @@ module cpu_top ( ); logic backend_flush; - instr_buffer_info_t backend_ib_instr_info[2]; + instr_buffer_info_t ib_backend_instr_info[2]; // IB -> ID instr_buffer #( .IF_WIDTH(FETCH_WIDTH), @@ -224,11 +224,66 @@ module cpu_top ( .frontend_stallreq_o(ib_frontend_stallreq), // <-> Backend - .backend_accept_i({id_inst_valid_2, id_inst_valid_1}), // 1 means valid - .backend_flush_i (backend_flush), - .backend_instr_o (backend_ib_instr_info) + .backend_accept_i(2'b11), // 1 means valid + .backend_flush_i(backend_flush), + .backend_instr_o(ib_backend_instr_info) ); + // ID <-> Regfile + logic [1:0] id_regfile_reg_read_valid[2]; + logic [`RegNumLog2*2-1:0] id_regfile_reg_read_addr[2]; + logic [1:0][1:0][`RegBus] regfile_id_reg_read_data; + + generate + genvar i; + for (i = 0; i < 2; i++) begin : id + id #( + .EXE_STAGE_WIDTH(2), // Obviously 2 for now + .MEM_STAGE_WIDTH(2) + ) u_id ( + .instr_buffer_i(ib_backend_instr_info[i]), + // FIXME: excp info, currently unused + .excp_i (), + .excp_num_i (), + + // <-> Regfile + .regfile_reg_read_valid_o(id_regfile_reg_read_valid[i]), + .regfile_reg_read_addr_o (id_regfile_reg_read_addr[i]), + .regfile_reg_read_data_i (regfile_id_reg_read_data[i]), + + // Data forwarding network, unused for now + // TODO: add data forwarding network + .ex_write_reg_valid_i (), + .ex_write_reg_addr_i (), + .ex_write_reg_data_i (), + .ex_aluop_i (), + .mem_write_reg_valid_i(), + .mem_write_reg_addr_i (), + .mem_write_reg_data_i (), + + // -> EXE + .ex_aluop_o (), + .ex_alusel_o (), + .ex_op1_o (), + .ex_op2_o (), + .ex_reg_write_valid_o(), + .ex_reg_write_addr_o (), + .ex_instr_info_o (), + .ex_csr_we_o (), + .ex_csr_signal_o (), + + // Exception broadcast + .broadcast_excp_o (), + .broadcast_excp_num_o(), + + // <-> CSR Registers + .has_int (), + .csr_data_i (), + .csr_plv (), + .csr_read_addr_o() + ); + end + endgenerate @@ -434,181 +489,6 @@ module cpu_top ( csr_write_signal id_csr_signal_o_2; - id u_id_1 ( - .rst(rst), - .instr_buffer_i(backend_ib_instr_info[0]), - - .instr_buffer_i_other(backend_ib_instr_info[1]), - - .reg1_data_i(reg1_data_1), - .reg2_data_i(reg2_data_1), - - .ex_wreg_i_1 (ex_wreg_o_1), - .ex_waddr_i_1(ex_reg_waddr_o_1), - .ex_wdata_i_1(ex_reg_wdata_1), - .ex_aluop_i_1(ex_aluop_o_1), - - .ex_wreg_i_2 (ex_wreg_o_2), - .ex_waddr_i_2(ex_reg_waddr_o_2), - .ex_wdata_i_2(ex_reg_wdata_2), - .ex_aluop_i_2(ex_aluop_o_2), - - .mem_wreg_i_1 (mem_wreg_o_1), - .mem_waddr_i_1(mem_reg_waddr_o_1), - .mem_wdata_i_1(mem_reg_wdata_o_1), - - .mem_wreg_i_2 (mem_wreg_o_2), - .mem_waddr_i_2(mem_reg_waddr_o_2), - .mem_wdata_i_2(mem_reg_wdata_o_2), - - .reg1_read_o(reg1_read_1), - .reg2_read_o(reg2_read_1), - - .reg1_addr_o(reg1_addr_1), - .reg2_addr_o(reg2_addr_1), - - .aluop_o (id_aluop_1), - .alusel_o (id_alusel_1), - .reg1_o (id_reg1_1), - .reg2_o (id_reg2_1), - .reg_waddr_o (id_reg_waddr_1), - .wreg_o (id_wreg_1), - .inst_valid (id_inst_valid_1), - .inst_pc (id_inst_pc_1), - .inst_o (id_inst_o_1), - .csr_signal_o(id_csr_signal_o_1), - - .csr_read_addr_o(id_csr_read_addr_o_1), - .csr_data_i(id_csr_data_1), - .has_int(has_int), - .csr_plv(csr_plv), - - .excp_i(if_excp_o_1), - .excp_num_i(if_excp_num_o_1), - .excp_o(id_excp_o_1), - .excp_num_o(id_excp_num_o_1), - - .branch_flag_o(branch_flag_1), - .branch_target_address_o(branch_target_address_1), - .link_addr_o(link_addr_1), - - .stallreq(stallreq_to_next_1), - .idle_stallreq(), - - .current_inst_address_o(id_current_inst_address_o_1) - ); - - logic [`AluOpBus] id_aluop_2; - logic [`AluSelBus] id_alusel_2; - logic [`RegBus] id_reg1_2; - logic [`RegBus] id_reg2_2; - - logic id_wreg_2; - logic id_inst_valid_2; - logic [`InstAddrBus] id_inst_pc_2; - logic [`RegBus] id_inst_o_2; - - logic reg1_read_2; - logic reg2_read_2; - logic [`RegBus] reg1_data_2; - logic [`RegBus] reg2_data_2; - - - - logic stallreq_from_id_2; - logic stallreq_from_ex_2; - - logic [1:0] id_excepttype_o_2; - logic [`RegBus] id_current_inst_address_o_2; - - - - id u_id_2 ( - .rst(rst), - .instr_buffer_i(backend_ib_instr_info[1]), - - .instr_buffer_i_other(backend_ib_instr_info[0]), - - .reg1_data_i(reg1_data_2), - .reg2_data_i(reg2_data_2), - - .ex_wreg_i_1 (ex_wreg_o_2), - .ex_waddr_i_1(ex_reg_waddr_o_2), - .ex_wdata_i_1(ex_reg_wdata_2), - .ex_aluop_i_1(ex_aluop_o_2), - - .ex_wreg_i_2 (ex_wreg_o_1), - .ex_waddr_i_2(ex_reg_waddr_o_1), - .ex_wdata_i_2(ex_reg_wdata_1), - .ex_aluop_i_2(ex_aluop_o_1), - - .mem_wreg_i_1 (mem_wreg_o_2), - .mem_waddr_i_1(mem_reg_waddr_o_2), - .mem_wdata_i_1(mem_reg_wdata_o_2), - - .mem_wreg_i_2 (mem_wreg_o_1), - .mem_waddr_i_2(mem_reg_waddr_o_1), - .mem_wdata_i_2(mem_reg_wdata_o_1), - - .reg1_read_o(reg1_read_2), - .reg2_read_o(reg2_read_2), - - .reg1_addr_o(reg1_addr_2), - .reg2_addr_o(reg2_addr_2), - - .aluop_o (id_aluop_2), - .alusel_o (id_alusel_2), - .reg1_o (id_reg1_2), - .reg2_o (id_reg2_2), - .reg_waddr_o(id_reg_waddr_2), - .wreg_o (id_wreg_2), - .inst_valid (id_inst_valid_2), - .inst_pc (id_inst_pc_2), - .inst_o (id_inst_o_2), - - .csr_signal_o(id_csr_signal_o_2), - .csr_data_i (id_csr_data_2), - - .csr_read_addr_o(id_csr_read_addr_o_2), - .has_int(has_int), - .csr_plv(csr_plv), - - .excp_i(if_excp_o_2), - .excp_num_i(if_excp_num_o_2), - .excp_o(id_excp_o_2), - .excp_num_o(id_excp_num_o_2), - - .branch_flag_o(branch_flag_2), - .branch_target_address_o(branch_target_address_2), - .link_addr_o(link_addr_2), - - .stallreq(stallreq_to_next_2), - .idle_stallreq(), - - .current_inst_address_o(id_current_inst_address_o_2) - - ); - - logic [`AluOpBus] ex_aluop_1; - logic [`AluSelBus] ex_alusel_1; - logic [`RegBus] ex_reg1_1; - logic [`RegBus] ex_reg2_1; - logic [`RegAddrBus] ex_reg_waddr_i_1; - logic ex_wreg_i_1; - logic ex_inst_valid_i_1; - logic [`InstAddrBus] ex_inst_pc_i_1; - logic [`RegBus] ex_link_address_1; - logic [`RegBus] ex_inst_i_1; - logic [1:0] ex_excepttype_i_1; - logic [`RegBus] ex_current_inst_address_i_1; - csr_write_signal ex_csr_signal_i_1; - csr_write_signal ex_csr_signal_i_2; - - logic ex_excp_i_1; - logic [8:0] ex_excp_num_i_1; - logic ex_excp_o_1; - logic [8:0] ex_excp_num_i_2; - id_ex id_ex_1 ( .clk (clk), .rst (rst), @@ -1285,7 +1165,9 @@ module cpu_top ( .excp_tlb_vppn(excp_tlb_vppn_2) ); - regfile u_regfile ( + regfile #( + .READ_PORTS(4) // 2 for each ID, 2 ID in total, TODO: remove magic number + ) u_regfile ( .clk(clk), .rst(rst), @@ -1298,20 +1180,13 @@ module cpu_top ( .waddr_2(wb_reg_waddr_2), .wdata_2(wb_reg_wdata_2), - .re1_1 (reg1_read_1), - .raddr1_1(reg1_addr_1), - .rdata1_1(reg1_data_1), - .re2_1 (reg2_read_1), - .raddr2_1(reg2_addr_1), - .rdata2_1(reg2_data_1), - .re1_2 (reg1_read_2), - .raddr1_2(reg1_addr_2), - .rdata1_2(reg1_data_2), - .re2_2 (reg2_read_2), - .raddr2_2(reg2_addr_2), - .rdata2_2(reg2_data_2) + // Read signals + .read_valid_i({id_regfile_reg_read_valid[1], id_regfile_reg_read_valid[0]}), + .read_addr_i ({id_regfile_reg_read_addr[1], id_regfile_reg_read_addr[0]}), + .read_data_o (regfile_id_reg_read_data) ); + ctrl u_ctrl ( .clk(clk), .rst(rst), @@ -1466,19 +1341,19 @@ module cpu_top ( // Difftest DPI-C `ifdef SIMU // SIMU is defined in chiplab run_func/Makefile logic [`RegBus] debug_commit_pc_1_delay_1; - log debug_commit_valid_1_delay_1; - always_ff @( posedge clk) begin : - debug_commit_pc_1_delay_1 <= debug_commit_valid_1; + logic debug_commit_valid_1_delay_1; + always_ff @(posedge clk) begin + debug_commit_valid_1_delay_1 <= debug_commit_valid_1; debug_commit_pc_1_delay_1 <= debug_commit_pc_1; end DifftestInstrCommit difftest_instr_commit_0 ( // TODO: not finished yet, blank signal is needed .clock (aclk), - .coreid (0), // Only one core, so always 0 - .index (0), // Commit channel index - .valid (debug_commit_valid_1_delay_1), // 1 means valid + .coreid (0), // Only one core, so always 0 + .index (0), // Commit channel index + .valid (debug_commit_valid_1_delay_1), // 1 means valid .pc (debug_commit_pc_1_delay_1), .instr (debug_commit_instr_1), - .skip (0), // Not sure meaning, but keep 0 for now + .skip (0), // Not sure meaning, but keep 0 for now .is_TLBFILL (), .TLBFILL_index (), .is_CNTinst (), diff --git a/src/vsrc/defines.sv b/src/vsrc/defines.sv index d27003d..288e180 100644 --- a/src/vsrc/defines.sv +++ b/src/vsrc/defines.sv @@ -29,14 +29,7 @@ // Instruction Encode -// 2RI16-type -`define EXE_JIRL 6'b010011 -`define EXE_BEQ 6'b010110 -`define EXE_BNE 6'b010111 -`define EXE_BLT 6'b011000 -`define EXE_BGE 6'b011001 -`define EXE_BLTU 6'b011010 -`define EXE_BGEU 6'b011011 + `define EXE_LU12I_W 6'b000101 // 7'b0001010 `define EXE_PCADDU12I 6'b000111 // 7'b0001110 @@ -56,29 +49,14 @@ `define EXE_CSRWR 5'b00001 `define EXE_CSRXCHG 5'b00011 `define EXE_TLB_RELATED 5'b10000 + +// 2R-type `define EXE_TLBSRCH 22'b0000011001001000001010 `define EXE_TLBRD 22'b0000011001001000001011 `define EXE_TLBWR 22'b0000011001001000001100 `define EXE_TLBFILL 22'b0000011001001000001101 `define EXE_ERTN 22'b0000011001001000001110 -// 2RI12-type -`define EXE_SLTI 10'b0000001000 -`define EXE_SLTUI 10'b0000001001 -`define EXE_ADDI_W 10'b0000001010 -`define EXE_ANDI 10'b0000001101 -`define EXE_ORI 10'b0000001110 -`define EXE_XORI 10'b0000001111 -`define EXE_LD_B 10'b0010100000 -`define EXE_LD_H 10'b0010100001 -`define EXE_LD_W 10'b0010100010 -`define EXE_ST_B 10'b0010100100 -`define EXE_ST_H 10'b0010100101 -`define EXE_ST_W 10'b0010100110 -`define EXE_LD_BU 10'b0010101000 -`define EXE_LD_HU 10'b0010101001 -`define EXE_PRELD 10'b0010101011 - // 3R-type `define EXE_ADD_W 17'b00000000000100000 `define EXE_SUB_W 17'b00000000000100010 @@ -107,6 +85,34 @@ `define EXE_DBAR 17'b00111000011100100 `define EXE_IBAR 17'b00111000011100101 +// 2RI12-type +`define EXE_SLTI 10'b0000001000 +`define EXE_SLTUI 10'b0000001001 +`define EXE_ADDI_W 10'b0000001010 +`define EXE_ANDI 10'b0000001101 +`define EXE_ORI 10'b0000001110 +`define EXE_XORI 10'b0000001111 +`define EXE_LD_B 10'b0010100000 +`define EXE_LD_H 10'b0010100001 +`define EXE_LD_W 10'b0010100010 +`define EXE_ST_B 10'b0010100100 +`define EXE_ST_H 10'b0010100101 +`define EXE_ST_W 10'b0010100110 +`define EXE_LD_BU 10'b0010101000 +`define EXE_LD_HU 10'b0010101001 +`define EXE_PRELD 10'b0010101011 + +// 2RI16-type +`define EXE_JIRL 6'b010011 +`define EXE_BEQ 6'b010110 +`define EXE_BNE 6'b010111 +`define EXE_BLT 6'b011000 +`define EXE_BGE 6'b011001 +`define EXE_BLTU 6'b011010 +`define EXE_BGEU 6'b011011 + + + `define EXE_SLLI_W 5'b00??? // EXE_SHIFT_ARITH `define EXE_SRLI_W 5'b01??? `define EXE_SRAI_W 5'b10??? diff --git a/src/vsrc/pipeline/2_decode/decoder_2RI12.sv b/src/vsrc/pipeline/2_decode/decoder_2RI12.sv index a50de9b..2a0b3ed 100644 --- a/src/vsrc/pipeline/2_decode/decoder_2RI12.sv +++ b/src/vsrc/pipeline/2_decode/decoder_2RI12.sv @@ -135,6 +135,10 @@ module decoder_2RI12 #( end default: begin decode_result_valid_o = 0; + reg_write_valid_o = 0; + reg_write_addr_o = 0; + reg_read_valid_o = 0; + reg_read_addr_o = 0; aluop_o = 0; alusel_o = 0; end diff --git a/src/vsrc/pipeline/2_decode/decoder_2RI16.sv b/src/vsrc/pipeline/2_decode/decoder_2RI16.sv index 60d2b66..75bb471 100644 --- a/src/vsrc/pipeline/2_decode/decoder_2RI16.sv +++ b/src/vsrc/pipeline/2_decode/decoder_2RI16.sv @@ -94,6 +94,10 @@ module decoder_2RI16 #( end default: begin decode_result_valid_o = 0; + reg_write_valid_o = 0; + reg_write_addr_o = 0; + reg_read_valid_o = 0; + reg_read_addr_o = 0; aluop_o = 0; alusel_o = 0; imm_o = 0; diff --git a/src/vsrc/pipeline/2_decode/decoder_3R.sv b/src/vsrc/pipeline/2_decode/decoder_3R.sv index 96359ef..71ecaed 100644 --- a/src/vsrc/pipeline/2_decode/decoder_3R.sv +++ b/src/vsrc/pipeline/2_decode/decoder_3R.sv @@ -147,9 +147,15 @@ module decoder_3R #( aluop_o = `EXE_INVTLB_OP; alusel_o = `EXE_RES_NOP; end - default: begin + default: begin // Means no match in the current decoder decode_result_valid_o = 0; aluop_o = 0; + reg_write_valid_o = 0; + reg_write_addr_o = 0; + reg_read_valid_o = 0; + reg_read_addr_o = 0; + instr_break = 0; + instr_syscall = 0; end endcase end diff --git a/src/vsrc/pipeline/2_decode/id.sv b/src/vsrc/pipeline/2_decode/id.sv index 87d582e..691058d 100644 --- a/src/vsrc/pipeline/2_decode/id.sv +++ b/src/vsrc/pipeline/2_decode/id.sv @@ -2,6 +2,11 @@ `include "instr_info.sv" `include "csr_defines.sv" +`include "pipeline/2_decode/decoder_2R.sv" +`include "pipeline/2_decode/decoder_3R.sv" +`include "pipeline/2_decode/decoder_2RI12.sv" +`include "pipeline/2_decode/decoder_2RI16.sv" + // ID stage // Should be totally cominational circuit @@ -26,7 +31,7 @@ module id #( // <-> Regfile output logic [1:0] regfile_reg_read_valid_o, // Read valid for 2 regs output logic [`RegNumLog2*2-1:0] regfile_reg_read_addr_o, // Read addr, {reg2, reg1} - input logic [`RegBus] regfile_reg_read_data_o, // Read result + input logic [`RegBus][1:0] regfile_reg_read_data_i, // Read result // <- EXE // Data forwarding diff --git a/src/vsrc/regfile.sv b/src/vsrc/regfile.sv index 58d0a4c..8fb2dd8 100644 --- a/src/vsrc/regfile.sv +++ b/src/vsrc/regfile.sv @@ -1,5 +1,7 @@ `include "defines.sv" -module regfile ( +module regfile #( + parameter READ_PORTS = 4 +) ( input wire clk, input wire rst, @@ -12,24 +14,16 @@ module regfile ( input wire [`RegAddrBus] waddr_2, input wire [`RegBus] wdata_2, - input wire re1_1, - input wire [`RegAddrBus] raddr1_1, - output reg [`RegBus] rdata1_1, - input wire re1_2, - input wire [`RegAddrBus] raddr1_2, - output reg [`RegBus] rdata1_2, - - input wire re2_1, - input wire [`RegAddrBus] raddr2_1, - output reg [`RegBus] rdata2_1, - input wire re2_2, - input wire [`RegAddrBus] raddr2_2, - output reg [`RegBus] rdata2_2 + // Read signals, all packed + input logic [READ_PORTS-1:0] read_valid_i, + input logic [`RegNumLog2*READ_PORTS - 1:0] read_addr_i, + output logic [`RegWidth*READ_PORTS - 1:0] read_data_o ); - // Used in difftest, should named regs + // Used in difftest, should named regs, IMPORTANT!! reg [`RegBus] regs[0:`RegNum-1]; + // Write Logic always @(posedge clk) begin if (rst == `RstEnable) begin for (integer i = 0; i < `RegNum; i = i + 1) begin @@ -48,48 +42,15 @@ module regfile ( end end - always @(*) begin - if (rst == `RstEnable) rdata1_1 = `ZeroWord; - else if (raddr1_1 == `RegNumLog2'h0) rdata1_1 = `ZeroWord; - else if ((raddr1_1 == waddr_1) && (we_1 == `WriteEnable) && (re1_1 == `ReadEnable)) - rdata1_1 = wdata_1; - else if ((raddr1_1 == waddr_2) && (we_2 == `WriteEnable) && (re1_1 == `ReadEnable)) - rdata1_1 = wdata_2; - else if (re1_1 == `ReadEnable) rdata1_1 = regs[raddr1_1]; - else rdata1_1 = `ZeroWord; - end - - always @(*) begin - if (rst == `RstEnable) rdata1_2 = `ZeroWord; - else if (raddr1_2 == `RegNumLog2'h0) rdata1_2 = `ZeroWord; - else if ((raddr1_2 == waddr_1) && (we_1 == `WriteEnable) && (re1_2 == `ReadEnable)) - rdata1_2 = wdata_1; - else if ((raddr1_2 == waddr_2) && (we_2 == `WriteEnable) && (re1_2 == `ReadEnable)) - rdata1_2 = wdata_2; - else if (re1_2 == `ReadEnable) rdata1_2 = regs[raddr1_2]; - else rdata1_2 = `ZeroWord; - end - - always @(*) begin - if (rst == `RstEnable) rdata2_1 = `ZeroWord; - else if (raddr2_1 == `RegNumLog2'h0) rdata2_1 = `ZeroWord; - else if ((raddr2_1 == waddr_1) && (we_1 == `WriteEnable) && (re2_1 == `ReadEnable)) - rdata2_1 = wdata_1; - else if ((raddr2_1 == waddr_2) && (we_2 == `WriteEnable) && (re2_1 == `ReadEnable)) - rdata2_1 = wdata_2; - else if (re2_1 == `ReadEnable) rdata2_1 = regs[raddr2_1]; - else rdata2_1 = `ZeroWord; - end - - always @(*) begin - if (rst == `RstEnable) rdata2_2 = `ZeroWord; - else if (raddr2_2 == `RegNumLog2'h0) rdata2_2 = `ZeroWord; - else if ((raddr2_2 == waddr_1) && (we_1 == `WriteEnable) && (re2_2 == `ReadEnable)) - rdata2_2 = wdata_1; - else if ((raddr2_2 == waddr_2) && (we_2 == `WriteEnable) && (re2_2 == `ReadEnable)) - rdata2_2 = wdata_2; - else if (re2_1 == `ReadEnable) rdata2_2 = regs[raddr2_2]; - else rdata2_2 = `ZeroWord; + // Read Logic + always_comb begin : read_comb + for (integer i = 0; i < READ_PORTS; i++) begin + if (rst == `RstEnable) read_data_o[i] = `ZeroWord; // Reset to zero + else if (read_addr_i[i] == 0) read_data_o[i] = `ZeroWord; // r0 is always zero + // TODO: add shortcut from write to read + else if (read_valid_i[i]) read_data_o[i] = regs[read_addr_i[i]]; // Read reg when valid + else read_data_o[i] = `ZeroWord; // Else zero + end end endmodule From aa88862d2b280fd6fab01504cbcc4f5a9cd44fc6 Mon Sep 17 00:00:00 2001 From: Rookie-rookie-rookie <292601787@qq.com> Date: Sat, 7 May 2022 11:48:43 +0800 Subject: [PATCH 076/114] add decoder --- src/vsrc/defines.sv | 16 +-- src/vsrc/pipeline/2_decode/decoder_1RI20.sv | 74 +++++++++++++ src/vsrc/pipeline/2_decode/decoder_2RI12.sv | 4 +- src/vsrc/pipeline/2_decode/decoder_2RI14.sv | 85 +++++++++++++++ src/vsrc/pipeline/2_decode/decoder_2RI16.sv | 2 +- src/vsrc/pipeline/2_decode/decoder_2RI8.sv | 80 ++++++++++++++ src/vsrc/pipeline/2_decode/decoder_CSR.sv | 84 +++++++++++++++ src/vsrc/pipeline/2_decode/decoder_I26.sv | 72 +++++++++++++ src/vsrc/pipeline/2_decode/id.sv | 56 +++++++++- src/vsrc/pipeline/2_decode/id_old.sv | 111 -------------------- 10 files changed, 460 insertions(+), 124 deletions(-) create mode 100644 src/vsrc/pipeline/2_decode/decoder_1RI20.sv create mode 100644 src/vsrc/pipeline/2_decode/decoder_2RI14.sv create mode 100644 src/vsrc/pipeline/2_decode/decoder_2RI8.sv create mode 100644 src/vsrc/pipeline/2_decode/decoder_CSR.sv create mode 100644 src/vsrc/pipeline/2_decode/decoder_I26.sv diff --git a/src/vsrc/defines.sv b/src/vsrc/defines.sv index d27003d..2dcd846 100644 --- a/src/vsrc/defines.sv +++ b/src/vsrc/defines.sv @@ -37,19 +37,19 @@ `define EXE_BGE 6'b011001 `define EXE_BLTU 6'b011010 `define EXE_BGEU 6'b011011 -`define EXE_LU12I_W 6'b000101 // 7'b0001010 -`define EXE_PCADDU12I 6'b000111 // 7'b0001110 +`define EXE_LU12I_W 7'b0001010 +`define EXE_PCADDU12I 7'b0001110 `define EXE_B 6'b010100 `define EXE_BL 6'b010101 // 6-12 bit opcode, decoded in opcode_2 `define EXE_ATOMIC_MEM 6'b001000 -`define EXE_LL_W 6'b00???? -`define EXE_SC_W 6'b01???? +`define EXE_LL_W 8'b00100000 +`define EXE_SC_W 8'b00100001 -`define EXE_SPECIAL 6'b000001 +`define EXE_SPECIAL 8'b00000100 `define EXE_CSR_RELATED 6'b00???? `define EXE_OTHER 6'b100100 `define EXE_CSRRD 5'b00000 @@ -107,9 +107,9 @@ `define EXE_DBAR 17'b00111000011100100 `define EXE_IBAR 17'b00111000011100101 -`define EXE_SLLI_W 5'b00??? // EXE_SHIFT_ARITH -`define EXE_SRLI_W 5'b01??? -`define EXE_SRAI_W 5'b10??? +`define EXE_SLLI_W 14'b00000000010000 // EXE_SHIFT_ARITH +`define EXE_SRLI_W 14'b00000000010001 +`define EXE_SRAI_W 14'b00000000010010 `define EXE_NOP 22'b0 diff --git a/src/vsrc/pipeline/2_decode/decoder_1RI20.sv b/src/vsrc/pipeline/2_decode/decoder_1RI20.sv new file mode 100644 index 0000000..f2780fc --- /dev/null +++ b/src/vsrc/pipeline/2_decode/decoder_1RI20.sv @@ -0,0 +1,74 @@ +`include "defines.sv" +`include "instr_info.sv" + +// decoder_1RI20 is the decoder for 1RI20-type instructions +// 1RI20-type {opcode[7], imm[20] , rd[5]} +// LU12i PCADDU12i +// all combinational circuit +module decoder_1RI20 #( + parameter ADDR_WIDTH = 32, + parameter DATA_WIDTH = 32, + parameter GPR_NUM = 32, + parameter ALU_OP_WIDTH = 8, + parameter ALU_SEL_WIDTH = 3 +) ( + input instr_buffer_info_t instr_info_i, + + // indicates current decoder module result is valid or not + // 1 means valid + output logic decode_result_valid_o, + + // GPR read + // 1 means valid, {rj, rk} + output logic [1:0] reg_read_valid_o, + output logic [$clog2(GPR_NUM)*2-1:0] reg_read_addr_o, + + // Generate imm + output logic [DATA_WIDTH-1:0] imm_o, + + // GPR write + // 1 means valid, {rd} + output logic reg_write_valid_o, + output logic [$clog2(GPR_NUM)-1:0] reg_write_addr_o, + + + // ALU info + output logic [ ALU_OP_WIDTH-1:0] aluop_o, + output logic [ALU_SEL_WIDTH-1:0] alusel_o + +); + + logic [DATA_WIDTH-1:0] instr; + assign instr = instr_info_i.instr; + + // 2 Registers + logic [4:0] rd; + assign rd = instr[4:0]; + + // imm12 + logic [19:0] imm_20; + assign imm_20 = instr[24:5]; + + always_comb begin + decode_result_valid_o = 1; + reg_write_valid_o = 1; + reg_write_addr_o = rd; + reg_read_valid_o = 2'b00; + reg_read_addr_o = 10'b0; + imm_o = {imm_20,12'b0}; + case (instr[31:25]) + `EXE_LU12I_W: begin + aluop_o = `EXE_LUI_OP; + alusel_o = `EXE_RES_MOVE; + end + `EXE_PCADDU12I:begin + aluop_o = `EXE_PCADD_OP; + alusel_o = `EXE_RES_MOVE; + end + default: begin + decode_result_valid_o = 0; + end + endcase + end + +endmodule \ No newline at end of file diff --git a/src/vsrc/pipeline/2_decode/decoder_2RI12.sv b/src/vsrc/pipeline/2_decode/decoder_2RI12.sv index a50de9b..5743e78 100644 --- a/src/vsrc/pipeline/2_decode/decoder_2RI12.sv +++ b/src/vsrc/pipeline/2_decode/decoder_2RI12.sv @@ -35,13 +35,13 @@ module decoder_2RI12 #( // ALU info output logic [ ALU_OP_WIDTH-1:0] aluop_o, output logic [ALU_SEL_WIDTH-1:0] alusel_o - + ); logic [DATA_WIDTH-1:0] instr; assign instr = instr_info_i.instr; - // 3 Registers + // 2 Registers logic [4:0] rd, rj; assign rd = instr[4:0]; assign rj = instr[9:5]; diff --git a/src/vsrc/pipeline/2_decode/decoder_2RI14.sv b/src/vsrc/pipeline/2_decode/decoder_2RI14.sv new file mode 100644 index 0000000..167c898 --- /dev/null +++ b/src/vsrc/pipeline/2_decode/decoder_2RI14.sv @@ -0,0 +1,85 @@ +`include "defines.sv" +`include "instr_info.sv" + +// decoder_2RI14 is the decoder for 2RI14-type instructions +// 2RI14-type {opcode[8], imm[14] ,rj[5], rd[5]} +// for CSR instructions +// all combinational circuit +module decoder_2RI14 #( + parameter ADDR_WIDTH = 32, + parameter DATA_WIDTH = 32, + parameter GPR_NUM = 32, + parameter ALU_OP_WIDTH = 8, + parameter ALU_SEL_WIDTH = 3 +)( + input instr_buffer_info_t instr_info_i, + + // indicates current decoder module result is valid or not + // 1 means valid + output logic decode_result_valid_o, + + // GPR read + // 1 means valid, {rj, rk} + output logic [1:0] reg_read_valid_o, + output logic [$clog2(GPR_NUM)*2-1:0] reg_read_addr_o, + + // Generate imm + // sext.w(imm_16) << 2 + output logic [DATA_WIDTH-1:0] imm_o, + + // GPR write + // 1 means valid, {rd} + output logic reg_write_valid_o, + output logic [$clog2(GPR_NUM)-1:0] reg_write_addr_o, + + + // ALU info + output logic [ ALU_OP_WIDTH-1:0] aluop_o, + output logic [ALU_SEL_WIDTH-1:0] alusel_o + +); + + logic [DATA_WIDTH-1:0] instr; + assign instr = instr_info_i.instr; + + // 2 Registers + logic [4:0] rd, rj; + assign rd = instr[4:0]; + assign rj = instr[9:5]; + + // imm14 + logic [13:0] imm_14; + assign imm_14 = instr[23:10]; + + always_comb begin + decode_result_valid_o = 1; + reg_write_valid_o = 1; + reg_write_addr_o = 0; + reg_read_valid_o = 2'b00; + reg_read_addr_o = 10'b0; + imm_o = {{18{imm_14[13]}}, imm_14}; // Signed Extension + case (instr[31:24]) + `EXE_LL_W:begin + aluop_o = `EXE_LL_OP; + alusel_o = `EXE_RES_MOVE; + reg_write_valid_o = 1; + reg_write_addr_o = rd; + reg_read_valid_o = 2'b01; + reg_read_addr_o = {5'b0,rj}; + end + `EXE_SC_W:begin + aluop_o = `EXE_SC_OP; + alusel_o = `EXE_RES_MOVE; + reg_write_valid_o = 0; + reg_write_addr_o = 0; + reg_read_valid_o = 2'b01; + reg_read_addr_o = {5'b0,rj}; + end + default:begin + decode_result_valid_o = 0; + end + endcase + end + + +endmodule \ No newline at end of file diff --git a/src/vsrc/pipeline/2_decode/decoder_2RI16.sv b/src/vsrc/pipeline/2_decode/decoder_2RI16.sv index 60d2b66..221cf9f 100644 --- a/src/vsrc/pipeline/2_decode/decoder_2RI16.sv +++ b/src/vsrc/pipeline/2_decode/decoder_2RI16.sv @@ -47,7 +47,7 @@ module decoder_2RI16 #( assign rd = instr[4:0]; assign rj = instr[9:5]; - // imm12 + // imm16 logic [15:0] imm_16; assign imm_16 = instr[25:10]; diff --git a/src/vsrc/pipeline/2_decode/decoder_2RI8.sv b/src/vsrc/pipeline/2_decode/decoder_2RI8.sv new file mode 100644 index 0000000..5f96d6f --- /dev/null +++ b/src/vsrc/pipeline/2_decode/decoder_2RI8.sv @@ -0,0 +1,80 @@ +`include "defines.sv" +`include "instr_info.sv" + +// decoder_2RI8 is the decoder for 2RI12-type instructions +// 2RI8-type {opcode[14], imm[8] ,rj[5], rd[5]} +// arithmetic instructions & memory instructions +// all combinational circuit +module decoder_2RI8 #( + parameter ADDR_WIDTH = 32, + parameter DATA_WIDTH = 32, + parameter GPR_NUM = 32, + parameter ALU_OP_WIDTH = 8, + parameter ALU_SEL_WIDTH = 3 +) ( + input instr_buffer_info_t instr_info_i, + + // indicates current decoder module result is valid or not + // 1 means valid + output logic decode_result_valid_o, + + // GPR read + // 1 means valid, {rj, rk} + output logic [1:0] reg_read_valid_o, + output logic [$clog2(GPR_NUM)*2-1:0] reg_read_addr_o, + + // Generate imm + output logic [DATA_WIDTH-1:0] imm_o, + + // GPR write + // 1 means valid, {rd} + output logic reg_write_valid_o, + output logic [$clog2(GPR_NUM)-1:0] reg_write_addr_o, + + + // ALU info + output logic [ ALU_OP_WIDTH-1:0] aluop_o, + output logic [ALU_SEL_WIDTH-1:0] alusel_o + +); + + logic [DATA_WIDTH-1:0] instr; + assign instr = instr_info_i.instr; + + // 2 Registers + logic [4:0] rd, rj; + assign rd = instr[4:0]; + assign rj = instr[9:5]; + + // imm8 + logic [7:0] imm_8; + assign imm_8 = instr[17:10]; + + always_comb begin + // Default decode + decode_result_valid_o = 1; + reg_write_valid_o = 1; + reg_write_addr_o = rd; + reg_read_valid_o = 2'b01; + reg_read_addr_o = {5'b0, rj}; + imm_o = {27'b0,imm_8[4:0]}; + case (instr[31:18]) + `EXE_SLLI_W:begin + aluop_o = `EXE_SLL_OP; + alusel_o = `EXE_RES_SHIFT; + end + `EXE_SRLI_W:begin + aluop_o = `EXE_SRL_OP; + alusel_o = `EXE_RES_SHIFT; + end + `EXE_SRAI_W:begin + aluop_o = `EXE_SRA_OP; + alusel_o = `EXE_RES_SHIFT; + end + default: begin + decode_result_valid_o = 0; + end + endcase + end + +endmodule \ No newline at end of file diff --git a/src/vsrc/pipeline/2_decode/decoder_CSR.sv b/src/vsrc/pipeline/2_decode/decoder_CSR.sv new file mode 100644 index 0000000..089fca8 --- /dev/null +++ b/src/vsrc/pipeline/2_decode/decoder_CSR.sv @@ -0,0 +1,84 @@ +`include "defines.sv" +`include "instr_info.sv" + +// decoder_CSR is the decoder for CSR instructions +// CSR {opcode[8], csr_num[14] ,rj[5], rd[5]} +// CSR instructions +// all combinational circuit +module decoder_CSR #( + parameter ADDR_WIDTH = 32, + parameter DATA_WIDTH = 32, + parameter GPR_NUM = 32, + parameter ALU_OP_WIDTH = 8, + parameter ALU_SEL_WIDTH = 3 +) ( + input instr_buffer_info_t instr_info_i, + + // indicates current decoder module result is valid or not + // 1 means valid + output logic decode_result_valid_o, + + // GPR read + // 1 means valid, {rj, rk} + output logic [1:0] reg_read_valid_o, + output logic [$clog2(GPR_NUM)*2-1:0] reg_read_addr_o, + + // Generate imm + output logic [DATA_WIDTH-1:0] imm_o, + + // GPR write + // 1 means valid, {rd} + output logic reg_write_valid_o, + output logic [$clog2(GPR_NUM)-1:0] reg_write_addr_o, + + + // ALU info + output logic [ ALU_OP_WIDTH-1:0] aluop_o + +); + + logic [DATA_WIDTH-1:0] instr; + assign instr = instr_info_i.instr; + + // 2 Registers + logic [4:0] rd, rj; + assign rd = instr[4:0]; + assign rj = instr[9:5]; + + // imm12 + logic [13:0] csr_num; + assign csr_num = instr[23:10]; + + always_comb begin + // Default decode + decode_result_valid_o = 1; + reg_write_valid_o = 1; + reg_write_addr_o = rd; + reg_read_valid_o = 2'b00; + reg_read_addr_o = 10'b0; + imm_o = {18'b0,csr_num}; + case (instr[31:24]) + `EXE_SPECIAL:begin + case (rj) + `EXE_CSRRD:begin + aluop_o = `EXE_CSRRD_OP; + end + `EXE_CSRWR:begin + aluop_o = `EXE_CSRWR_OP; + reg_read_valid_o = 2'b01; + reg_read_addr_o = {5'b0,rd}; + end + default:begin // EXE_CSRXCHG + aluop_o = `EXE_CSRXCHG_OP; + reg_read_valid_o = 2'b11; + reg_read_addr_o = {rj,rd}; + end + endcase + end + default: begin + decode_result_valid_o = 0; + end + endcase + end + +endmodule \ No newline at end of file diff --git a/src/vsrc/pipeline/2_decode/decoder_I26.sv b/src/vsrc/pipeline/2_decode/decoder_I26.sv new file mode 100644 index 0000000..b3e736e --- /dev/null +++ b/src/vsrc/pipeline/2_decode/decoder_I26.sv @@ -0,0 +1,72 @@ +`include "defines.sv" +`include "instr_info.sv" + +// decoder_I26 is the decoder for I26-type instructions +// I26-type {opcode[6], imm[14] ,rj[5], rd[5]} +// for B and BL instructions +// all combinational circuit +module decoder_I26 #( + parameter ADDR_WIDTH = 32, + parameter DATA_WIDTH = 32, + parameter GPR_NUM = 32, + parameter ALU_OP_WIDTH = 8, + parameter ALU_SEL_WIDTH = 3 +)( + input instr_buffer_info_t instr_info_i, + + // indicates current decoder module result is valid or not + // 1 means valid + output logic decode_result_valid_o, + + // B and BL instructions do not read GPR + + // Generate imm + // sext.w(imm_16) << 2 + output logic [DATA_WIDTH-1:0] imm_o, + + // GPR write + // 1 means valid, {rd} + output logic reg_write_valid_o, + output logic [$clog2(GPR_NUM)-1:0] reg_write_addr_o, + + // ALU info + output logic [ ALU_OP_WIDTH-1:0] aluop_o, + output logic [ALU_SEL_WIDTH-1:0] alusel_o + +); + + logic [DATA_WIDTH-1:0] instr; + assign instr = instr_info_i.instr; + + + // imm26 + logic [25:0] imm_26; + assign imm_26 = {instr[9:0] ,instr[25:10]}; + + always_comb begin + // Default decode + decode_result_valid_o = 1; + reg_write_valid_o = 0; + reg_write_addr_o = 0; + imm_o = {{4{imm_26[25]}},imm_26,2'b0}; + case (instr[31:26]) + `EXE_B:begin + aluop_o = `EXE_B_OP; + alusel_o = `EXE_RES_JUMP; + end + `EXE_BL:begin + aluop_o = `EXE_BL_OP; + alusel_o = `EXE_RES_JUMP; + reg_write_valid_o = 1; + reg_write_addr_o = 5'b1; + end + default:begin + decode_result_valid_o = 0; + aluop_o = 0; + alusel_o = 0; + imm_o = 0; + end + endcase + end + +endmodule \ No newline at end of file diff --git a/src/vsrc/pipeline/2_decode/id.sv b/src/vsrc/pipeline/2_decode/id.sv index 87d582e..3f2a5fd 100644 --- a/src/vsrc/pipeline/2_decode/id.sv +++ b/src/vsrc/pipeline/2_decode/id.sv @@ -73,7 +73,7 @@ module id #( logic instr_break, instr_syscall, kernel_instr; // Sub-decoder section - localparam SUB_DECODER_NUM = 7; + localparam SUB_DECODER_NUM = 9; logic sub_decoder_valid[SUB_DECODER_NUM]; logic [`AluOpBus] sub_decoder_aluop[SUB_DECODER_NUM]; logic [`AluSelBus] sub_decoder_alusel[SUB_DECODER_NUM]; @@ -102,7 +102,17 @@ module id #( .instr_break (instr_break), .instr_syscall (instr_syscall) ); - // FIXME: 2RI8 not implemented + decoder_2RI8 U_decoder_2RI8( + .instr_info_i (instr_buffer_i), + .decode_result_valid_o(sub_decoder_valid[2]), + .reg_read_valid_o (sub_decoder_reg_read_valid[2]), + .reg_read_addr_o (sub_decoder_reg_read_addr[2]), + .imm_o (sub_decoder_imm[2]), + .reg_write_valid_o (sub_decoder_reg_write_valid[2]), + .reg_write_addr_o (sub_decoder_reg_write_addr[2]), + .aluop_o (sub_decoder_aluop[2]), + .alusel_o (sub_decoder_alusel[2]) + ); decoder_2RI12 u_decoder_2RI12 ( .instr_info_i (instr_buffer_i), .decode_result_valid_o(sub_decoder_valid[3]), @@ -125,6 +135,48 @@ module id #( .aluop_o (sub_decoder_aluop[4]), .alusel_o (sub_decoder_alusel[4]) ); + + decoder_1RI20 U_decoder_1RI20( + .instr_info_i (instr_buffer_i), + .decode_result_valid_o(sub_decoder_valid[5]), + .reg_read_valid_o (sub_decoder_reg_read_valid[5]), + .reg_read_addr_o (sub_decoder_reg_read_addr[5]), + .imm_o (sub_decoder_imm[5]), + .reg_write_valid_o (sub_decoder_reg_write_valid[5]), + .reg_write_addr_o (sub_decoder_reg_write_addr[5]), + .aluop_o (sub_decoder_aluop[5]), + .alusel_o (sub_decoder_alusel[5]) + ); + decoder_2RI14 U_decoder_2RI14( + .instr_info_i (instr_buffer_i), + .decode_result_valid_o(sub_decoder_valid[6]), + .reg_read_valid_o (sub_decoder_reg_read_valid[6]), + .reg_read_addr_o (sub_decoder_reg_read_addr[6]), + .imm_o (sub_decoder_imm[6]), + .reg_write_valid_o (sub_decoder_reg_write_valid[6]), + .reg_write_addr_o (sub_decoder_reg_write_addr[6]), + .aluop_o (sub_decoder_aluop[6]), + .alusel_o (sub_decoder_alusel[6]) + ); + decoder_I26 U_decoder_I26( + .instr_info_i (instr_buffer_i), + .decode_result_valid_o(sub_decoder_valid[7]), + .imm_o (sub_decoder_imm[7]), + .reg_write_valid_o (sub_decoder_reg_write_valid[7]), + .reg_write_addr_o (sub_decoder_reg_write_addr[7]), + .aluop_o (sub_decoder_aluop[7]), + .alusel_o (sub_decoder_alusel[7]) + ); + decoder_CSR u_decoder_CSR( + .instr_info_i (instr_buffer_i), + .decode_result_valid_o(sub_decoder_valid[8]), + .reg_read_valid_o (sub_decoder_reg_read_valid[8]), + .reg_read_addr_o (sub_decoder_reg_read_addr[8]), + .imm_o (sub_decoder_imm[8]), + .reg_write_valid_o (sub_decoder_reg_write_valid[8]), + .reg_write_addr_o (sub_decoder_reg_write_addr[8]), + .aluop_o (sub_decoder_aluop[8]) + ); // FIXME: I16 and Special not implemented // Sub-decoder END diff --git a/src/vsrc/pipeline/2_decode/id_old.sv b/src/vsrc/pipeline/2_decode/id_old.sv index a51fde5..5c58ee9 100644 --- a/src/vsrc/pipeline/2_decode/id_old.sv +++ b/src/vsrc/pipeline/2_decode/id_old.sv @@ -219,72 +219,6 @@ module id ( link_addr_o = `ZeroWord; idle_stallreq = 1'b0; case (opcode_1) - `EXE_B: begin - wreg_o = `WriteDisable; - aluop_o = `EXE_B_OP; - alusel_o = `EXE_RES_JUMP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - branch_flag_o = `Branch; - branch_target_address_o = pc_i + {{4{imm_10[9]}}, imm_10, imm_16, 2'b0}; - inst_valid = `InstValid; - end - `EXE_BL: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_BL_OP; - alusel_o = `EXE_RES_JUMP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - branch_flag_o = `Branch; - link_addr_o = pc_plus_4; - branch_target_address_o = pc_i + {{4{imm_10[9]}}, imm_10, imm_16, 2'b0}; - reg_waddr_o = 5'b1; - inst_valid = `InstValid; - end - `EXE_LU12I_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_LUI_OP; - alusel_o = `EXE_RES_MOVE; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - imm = {imm_20, 12'b0}; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_PCADDU12I: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_PCADD_OP; - alusel_o = `EXE_RES_MOVE; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - imm = {imm_20, 12'b0}; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_ATOMIC_MEM: begin - casez (opcode_2) - `EXE_LL_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_LL_OP; - alusel_o = `EXE_RES_LOAD_STORE; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_SC_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SC_OP; - alusel_o = `EXE_RES_LOAD_STORE; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg2_addr_o = op1; - inst_valid = `InstValid; - end - default: begin - end - endcase - end `EXE_SPECIAL: begin case (opcode_2) @@ -338,51 +272,6 @@ module id ( endcase end - `EXE_ARITHMETIC: begin - casez (opcode_2) - - - `EXE_SHIFT_ARITH: begin - casez (opcode_3) - `EXE_SLLI_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SLL_OP; - alusel_o = `EXE_RES_SHIFT; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - imm = {27'b0, imm_5}; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_SRLI_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SRL_OP; - alusel_o = `EXE_RES_SHIFT; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - imm = {27'b0, imm_5}; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_SRAI_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SRA_OP; - alusel_o = `EXE_RES_SHIFT; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - imm = {27'b0, imm_5}; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - default: begin - end - endcase - end - default: begin - - end - endcase - end default: begin end endcase From 85684c3b32dc9c7ecba08a2e690184e768113d86 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Sat, 7 May 2022 11:49:06 +0800 Subject: [PATCH 077/114] refactor: add dispatch stage --- src/vsrc/cpu_top.sv | 166 +++--------------- .../{2_decode => 1_decode}/decoder_2R.sv | 0 .../{2_decode => 1_decode}/decoder_2RI12.sv | 0 .../{2_decode => 1_decode}/decoder_2RI16.sv | 0 .../{2_decode => 1_decode}/decoder_3R.sv | 0 .../pipeline/{2_decode => 1_decode}/id.sv | 46 +++-- .../pipeline/{2_decode => 1_decode}/id_bak.sv | 0 src/vsrc/pipeline/1_decode/id_dispatch.sv | 45 +++++ .../pipeline/{2_decode => 1_decode}/id_old.sv | 0 src/vsrc/pipeline/2_decode/id_ex.sv | 120 ------------- src/vsrc/pipeline/2_dispatch/dispatch.sv | 17 ++ src/vsrc/pipeline_defines.sv | 19 ++ 12 files changed, 128 insertions(+), 285 deletions(-) rename src/vsrc/pipeline/{2_decode => 1_decode}/decoder_2R.sv (100%) rename src/vsrc/pipeline/{2_decode => 1_decode}/decoder_2RI12.sv (100%) rename src/vsrc/pipeline/{2_decode => 1_decode}/decoder_2RI16.sv (100%) rename src/vsrc/pipeline/{2_decode => 1_decode}/decoder_3R.sv (100%) rename src/vsrc/pipeline/{2_decode => 1_decode}/id.sv (84%) rename src/vsrc/pipeline/{2_decode => 1_decode}/id_bak.sv (100%) create mode 100644 src/vsrc/pipeline/1_decode/id_dispatch.sv rename src/vsrc/pipeline/{2_decode => 1_decode}/id_old.sv (100%) delete mode 100644 src/vsrc/pipeline/2_decode/id_ex.sv create mode 100644 src/vsrc/pipeline/2_dispatch/dispatch.sv create mode 100644 src/vsrc/pipeline_defines.sv diff --git a/src/vsrc/cpu_top.sv b/src/vsrc/cpu_top.sv index 66488f2..5023c10 100644 --- a/src/vsrc/cpu_top.sv +++ b/src/vsrc/cpu_top.sv @@ -11,8 +11,9 @@ `include "dummy_icache.sv" `include "LLbit_reg.sv" `include "ctrl.sv" -`include "pipeline/2_decode/id.sv" -`include "pipeline/2_decode/id_ex.sv" +`include "pipeline_defines.sv" +`include "pipeline/1_decode/id.sv" +`include "pipeline/1_decode/id_dispatch.sv" `include "pipeline/3_execution/ex.sv" `include "pipeline/3_execution/ex_mem.sv" `include "pipeline/4_mem/mem.sv" @@ -188,6 +189,7 @@ module cpu_top ( instr_buffer_info_t frontend_ib_instr_info[FETCH_WIDTH]; logic [`RegBus] next_pc; + // All frontend structures frontend u_frontend ( .clk(clk), .rst(rst), @@ -212,6 +214,8 @@ module cpu_top ( logic backend_flush; instr_buffer_info_t ib_backend_instr_info[2]; // IB -> ID + // Instruction Buffer + // FIFO buffer instr_buffer #( .IF_WIDTH(FETCH_WIDTH), .ID_WIDTH(2) // TODO: remove magic number @@ -234,6 +238,10 @@ module cpu_top ( logic [`RegNumLog2*2-1:0] id_regfile_reg_read_addr[2]; logic [1:0][1:0][`RegBus] regfile_id_reg_read_data; + // ID -> ID_DISPATCH + id_dispatch_struct [1:0] id_id_dispatch; + + // ID Stage generate genvar i; for (i = 0; i < 2; i++) begin : id @@ -261,16 +269,8 @@ module cpu_top ( .mem_write_reg_addr_i (), .mem_write_reg_data_i (), - // -> EXE - .ex_aluop_o (), - .ex_alusel_o (), - .ex_op1_o (), - .ex_op2_o (), - .ex_reg_write_valid_o(), - .ex_reg_write_addr_o (), - .ex_instr_info_o (), - .ex_csr_we_o (), - .ex_csr_signal_o (), + // -> Dispatch + .dispatch_o(id_id_dispatch[i]), // Exception broadcast .broadcast_excp_o (), @@ -285,6 +285,21 @@ module cpu_top ( end endgenerate + // ID_DISPATCH -> EXE + id_dispatch_struct [1:0] id_dispatch_exe; + + + // ID_DISPATCH + id_dispatch u_id_dispatch ( + .clk (clk), + .rst (rst), + .stall (), + .flush (), + .id_i (id_id_dispatch), + .dispatch_o(id_dispatch_exe) + ); + + logic [`RegBus] branch_target_address_1; @@ -489,133 +504,6 @@ module cpu_top ( csr_write_signal id_csr_signal_o_2; - id_ex id_ex_1 ( - .clk (clk), - .rst (rst), - .stall(stall1[3]), - - .id_aluop(id_aluop_1), - .id_alusel(id_alusel_1), - .id_reg1(id_reg1_1), - .id_reg2(id_reg2_1), - .id_wd(id_reg_waddr_1), - .id_wreg(id_wreg_1), - .id_inst_pc(id_inst_pc_1), - .id_inst_valid(id_inst_valid_1), - .id_link_address(link_addr_1), - .id_inst(id_inst_o_1), - .flush(flush), - .id_excepttype(id_excepttype_o_1), - .id_current_inst_address(id_current_inst_address_o_1), - .id_csr_signal_o(id_csr_signal_o_1), - - .ex_aluop(ex_aluop_1), - .ex_alusel(ex_alusel_1), - .ex_reg1(ex_reg1_1), - .ex_reg2(ex_reg2_1), - .ex_wd(ex_reg_waddr_i_1), - .ex_wreg(ex_wreg_i_1), - .ex_inst_pc(ex_inst_pc_i_1), - .ex_inst_valid(ex_inst_valid_i_1), - .ex_link_address(ex_link_address_1), - .ex_inst(ex_inst_i_1), - .ex_excepttype(ex_excepttype_i_1), - .ex_current_inst_address(ex_current_inst_address_i_1), - .ex_csr_signal_i(ex_csr_signal_i_1), - - .reg1_addr_i(reg1_addr_1), - .reg2_addr_i(reg2_addr_1), - .pc_i_other(id_inst_pc_2), - .reg1_addr_i_other(reg1_addr_2), - .reg2_addr_i_other(reg2_addr_2), - .waddr_i_other(id_reg_waddr_2), - - .stallreq_from_id(stallreq_to_next_1), - .stallreq(stallreq_from_id_1), - - .excp_i(id_excp_o_1), - .excp_num_i(id_excp_num_o_1), - .excp_o(ex_excp_i_1), - .excp_num_o(ex_excp_num_i_1), - - .excp_flush(excp_flush), - .ertn_flush(ertn_flush) - ); - - logic [`AluOpBus] ex_aluop_2; - logic [`AluSelBus] ex_alusel_2; - logic [`RegBus] ex_reg1_2; - logic [`RegBus] ex_reg2_2; - logic [`RegAddrBus] ex_reg_waddr_i_2; - logic ex_wreg_i_2; - logic ex_inst_valid_i_2; - logic [`InstAddrBus] ex_inst_pc_i_2; - logic [`RegBus] ex_link_address_2; - logic [`RegBus] ex_inst_i_2; - logic [1:0] ex_excepttype_i_2; - logic [`RegBus] ex_current_inst_address_i_2; - logic ex_csr_we_i_2; - logic [13:0] ex_csr_addr_i_2; - logic [31:0] ex_csr_data_i_2; - - logic ex_excp_i_2; - logic [9:0] ex_excp_num_o_1; - logic ex_excp_o_2; - logic [9:0] ex_excp_num_o_2; - - id_ex id_ex_2 ( - .clk (clk), - .rst (rst), - .stall(stall2[3]), - - .id_aluop(id_aluop_2), - .id_alusel(id_alusel_2), - .id_reg1(id_reg1_2), - .id_reg2(id_reg2_2), - .id_wd(id_reg_waddr_2), - .id_wreg(id_wreg_2), - .id_inst_pc(id_inst_pc_2), - .id_inst_valid(id_inst_valid_2), - .id_link_address(link_addr_2), - .id_inst(id_inst_o_2), - .flush(flush), - .id_excepttype(id_excepttype_o_2), - .id_current_inst_address(id_current_inst_address_o_2), - .id_csr_signal_o(id_csr_signal_o_2), - - .ex_aluop(ex_aluop_2), - .ex_alusel(ex_alusel_2), - .ex_reg1(ex_reg1_2), - .ex_reg2(ex_reg2_2), - .ex_wd(ex_reg_waddr_i_2), - .ex_wreg(ex_wreg_i_2), - .ex_inst_pc(ex_inst_pc_i_2), - .ex_inst_valid(ex_inst_valid_i_2), - .ex_link_address(ex_link_address_2), - .ex_inst(ex_inst_i_2), - .ex_excepttype(ex_excepttype_i_2), - .ex_current_inst_address(ex_current_inst_address_i_2), - .ex_csr_signal_i(ex_csr_signal_i_2), - - .reg1_addr_i(reg1_addr_2), - .reg2_addr_i(reg2_addr_2), - .pc_i_other(id_inst_pc_1), - .reg1_addr_i_other(reg1_addr_1), - .reg2_addr_i_other(reg2_addr_2), - .waddr_i_other(id_reg_waddr_1), - - .stallreq_from_id(stallreq_to_next_2), - .stallreq(stallreq_from_id_2), - - .excp_i(id_excp_o_2), - .excp_num_i(id_excp_num_o_2), - .excp_o(ex_excp_i_2), - .excp_num_o(ex_excp_num_i_2), - - .excp_flush(excp_flush), - .ertn_flush(ertn_flush) - ); - logic ex_inst_valid_o_1; logic [`InstAddrBus] ex_inst_pc_o_1; diff --git a/src/vsrc/pipeline/2_decode/decoder_2R.sv b/src/vsrc/pipeline/1_decode/decoder_2R.sv similarity index 100% rename from src/vsrc/pipeline/2_decode/decoder_2R.sv rename to src/vsrc/pipeline/1_decode/decoder_2R.sv diff --git a/src/vsrc/pipeline/2_decode/decoder_2RI12.sv b/src/vsrc/pipeline/1_decode/decoder_2RI12.sv similarity index 100% rename from src/vsrc/pipeline/2_decode/decoder_2RI12.sv rename to src/vsrc/pipeline/1_decode/decoder_2RI12.sv diff --git a/src/vsrc/pipeline/2_decode/decoder_2RI16.sv b/src/vsrc/pipeline/1_decode/decoder_2RI16.sv similarity index 100% rename from src/vsrc/pipeline/2_decode/decoder_2RI16.sv rename to src/vsrc/pipeline/1_decode/decoder_2RI16.sv diff --git a/src/vsrc/pipeline/2_decode/decoder_3R.sv b/src/vsrc/pipeline/1_decode/decoder_3R.sv similarity index 100% rename from src/vsrc/pipeline/2_decode/decoder_3R.sv rename to src/vsrc/pipeline/1_decode/decoder_3R.sv diff --git a/src/vsrc/pipeline/2_decode/id.sv b/src/vsrc/pipeline/1_decode/id.sv similarity index 84% rename from src/vsrc/pipeline/2_decode/id.sv rename to src/vsrc/pipeline/1_decode/id.sv index 691058d..1756670 100644 --- a/src/vsrc/pipeline/2_decode/id.sv +++ b/src/vsrc/pipeline/1_decode/id.sv @@ -1,11 +1,12 @@ `include "defines.sv" `include "instr_info.sv" `include "csr_defines.sv" +`include "pipeline_defines.sv" -`include "pipeline/2_decode/decoder_2R.sv" -`include "pipeline/2_decode/decoder_3R.sv" -`include "pipeline/2_decode/decoder_2RI12.sv" -`include "pipeline/2_decode/decoder_2RI16.sv" +`include "pipeline/1_decode/decoder_2R.sv" +`include "pipeline/1_decode/decoder_3R.sv" +`include "pipeline/1_decode/decoder_2RI12.sv" +`include "pipeline/1_decode/decoder_2RI16.sv" // ID stage @@ -17,7 +18,8 @@ // What ID NOT DO: // 1. Determine whether a instruction dispatch in EXE or not // 2. Calculate anything, such as branch target -// +// TODO: move regfile read to dispatch stage +// module id #( parameter EXE_STAGE_WIDTH = 2, parameter MEM_STAGE_WIDTH = 2 @@ -47,16 +49,8 @@ module id #( input logic [`RegBus] mem_write_reg_data_i[MEM_STAGE_WIDTH], - // -> EXE - output reg [`AluOpBus] ex_aluop_o, - output reg [`AluSelBus] ex_alusel_o, - output reg [`RegBus] ex_op1_o, - output reg [`RegBus] ex_op2_o, - output reg ex_reg_write_valid_o, - output reg [`RegAddrBus] ex_reg_write_addr_o, - output instr_buffer_info_t ex_instr_info_o, // Instruction info passed to EXE - output reg ex_csr_we_o, - output csr_write_signal ex_csr_signal_o, + // -> Dispatch + output id_dispatch_struct dispatch_o, output logic broadcast_excp_o, output logic [8:0] broadcast_excp_num_o, @@ -152,15 +146,15 @@ module id #( end // Generate output to EXE always_comb begin - ex_aluop_o = 0; - ex_alusel_o = 0; - ex_reg_write_valid_o = 0; - ex_reg_write_addr_o = 0; + dispatch_o.aluop = 0; + dispatch_o.alusel = 0; + dispatch_o.reg_write_valid = 0; + dispatch_o.reg_write_addr = 0; for (integer i = 0; i < SUB_DECODER_NUM; i++) begin - ex_aluop_o = ex_aluop_o | sub_decoder_aluop[i]; - ex_alusel_o = ex_alusel_o | sub_decoder_alusel[i]; - ex_reg_write_valid_o = ex_reg_write_valid_o | sub_decoder_reg_write_valid[i]; - ex_reg_write_addr_o = ex_reg_write_addr_o | sub_decoder_reg_write_addr[i]; + dispatch_o.aluop = dispatch_o.aluop | sub_decoder_aluop[i]; + dispatch_o.alusel = dispatch_o.alusel | sub_decoder_alusel[i]; + dispatch_o.reg_write_valid = dispatch_o.reg_write_valid | sub_decoder_reg_write_valid[i]; + dispatch_o.reg_write_addr = dispatch_o.reg_write_addr | sub_decoder_reg_write_addr[i]; end end // Generate output to Regfile @@ -175,9 +169,9 @@ module id #( // Generate output - assign ex_instr_info_o.valid = instr_valid; - assign ex_instr_info_o.pc = pc_i; - assign ex_instr_info_o.instr = inst_i; + assign dispatch_o.instr_info.valid = instr_valid; + assign dispatch_o.instr_info.pc = pc_i; + assign dispatch_o.instr_info.instr = inst_i; // TODO: add explanation diff --git a/src/vsrc/pipeline/2_decode/id_bak.sv b/src/vsrc/pipeline/1_decode/id_bak.sv similarity index 100% rename from src/vsrc/pipeline/2_decode/id_bak.sv rename to src/vsrc/pipeline/1_decode/id_bak.sv diff --git a/src/vsrc/pipeline/1_decode/id_dispatch.sv b/src/vsrc/pipeline/1_decode/id_dispatch.sv new file mode 100644 index 0000000..568dd93 --- /dev/null +++ b/src/vsrc/pipeline/1_decode/id_dispatch.sv @@ -0,0 +1,45 @@ +`include "defines.sv" +`include "instr_info.sv" +`include "csr_defines.sv" +`include "pipeline_defines.sv" + +// id_dispatch is a sequential logic +// merge all ID stage output to dispatch stage +// ID -> -> EXE +// ID -> id_dispatch -> dispatch -> EXE +// + +module id_dispatch #( + parameter DECODE_WIDTH = 2 +) ( + input logic clk, + input logic rst, + + // Stall & flush + // <-> Ctrl + input logic stall, + input logic flush, + + // <- ID stage + input id_dispatch_struct [DECODE_WIDTH-1:0] id_i, + + // -> Dispatch stage + output id_dispatch_struct [DECODE_WIDTH-1:0] dispatch_o +); + + logic rst_n; + assign rst_n = ~rst; + + always @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + dispatch_o <= 0; + end else if (flush) begin + dispatch_o <= 0; + end else if (stall) begin + // Do nothing, hold output + end else begin + dispatch_o <= id_i; + end + end + +endmodule diff --git a/src/vsrc/pipeline/2_decode/id_old.sv b/src/vsrc/pipeline/1_decode/id_old.sv similarity index 100% rename from src/vsrc/pipeline/2_decode/id_old.sv rename to src/vsrc/pipeline/1_decode/id_old.sv diff --git a/src/vsrc/pipeline/2_decode/id_ex.sv b/src/vsrc/pipeline/2_decode/id_ex.sv deleted file mode 100644 index 9154d67..0000000 --- a/src/vsrc/pipeline/2_decode/id_ex.sv +++ /dev/null @@ -1,120 +0,0 @@ -`include "defines.sv" -`include "csr_defines.sv" -module id_ex ( - input wire clk, - input wire rst, - input wire stall, - input wire excp_flush, - input wire ertn_flush, - - input wire [`AluOpBus] id_aluop, - input wire [`AluSelBus] id_alusel, - input wire [`RegBus] id_reg1, - input wire [`RegBus] id_reg2, - input wire [`RegAddrBus] id_wd, - input wire id_wreg, - input wire id_inst_valid, - input wire [`InstAddrBus] id_inst_pc, - input wire [`RegBus] id_link_address, - input wire [`RegBus] id_inst, - input wire flush, - input wire [1:0] id_excepttype, - input wire [`RegBus] id_current_inst_address, - input csr_write_signal id_csr_signal_o, - - output reg [`AluOpBus] ex_aluop, - output reg [`AluSelBus] ex_alusel, - output reg [`RegBus] ex_reg1, - output reg [`RegBus] ex_reg2, - output reg [`RegAddrBus] ex_wd, - output reg ex_wreg, - output reg ex_inst_valid, - output reg [`InstAddrBus] ex_inst_pc, - output reg [`RegBus] ex_link_address, - output reg [`RegBus] ex_inst, - output reg [1:0] ex_excepttype, - output reg [`RegBus] ex_current_inst_address, - output csr_write_signal ex_csr_signal_i, - - input wire [ `RegAddrBus] reg1_addr_i, - input wire [ `RegAddrBus] reg2_addr_i, - input wire [`InstAddrBus] pc_i_other, - input wire [ `RegAddrBus] reg1_addr_i_other, - input wire [ `RegAddrBus] reg2_addr_i_other, - input wire [ `RegAddrBus] waddr_i_other, - - input stallreq_from_id, - output reg stallreq, - - input wire excp_i, - input wire [8:0] excp_num_i, - output reg excp_o, - output reg [8:0] excp_num_o -); - - - //always @(*) begin - //stallreq = stallreq_from_id | stallreq1 | stallreq7; - //end - - always @(*) begin - stallreq = stallreq_from_id | ((id_inst_pc == pc_i_other + 4) && ( (reg1_addr_i == waddr_i_other) | (reg2_addr_i == waddr_i_other))); - end - - - always @(posedge clk) begin - if (rst == `RstEnable) begin - ex_aluop <= `EXE_NOP_OP; - ex_alusel <= `EXE_RES_NOP; - ex_reg1 <= `ZeroWord; - ex_reg2 <= `ZeroWord; - ex_wd <= `NOPRegAddr; - ex_wreg <= `WriteDisable; - ex_inst_pc <= `ZeroWord; - ex_inst_valid <= `InstInvalid; - ex_link_address <= `ZeroWord; - ex_inst <= `ZeroWord; - ex_excepttype <= 2'b00; - ex_current_inst_address <= `ZeroWord; - ex_csr_signal_i <= 47'b0; - excp_o <= 1'b0; - excp_num_o <= 9'b0; - end else if (flush == 1'b1 || excp_flush == 1'b1 || ertn_flush == 1'b1) begin - ex_aluop <= `EXE_NOP_OP; - ex_alusel <= `EXE_RES_NOP; - ex_reg1 <= `ZeroWord; - ex_reg2 <= `ZeroWord; - ex_wd <= `NOPRegAddr; - ex_wreg <= `WriteDisable; - ex_inst_pc <= `ZeroWord; - ex_inst_valid <= `InstInvalid; - ex_link_address <= `ZeroWord; - ex_inst <= `ZeroWord; - ex_excepttype <= 2'b00; - ex_current_inst_address <= `ZeroWord; - ex_csr_signal_i <= 47'b0; - excp_o <= 1'b0; - excp_num_o <= 9'b0; - end else - if (stall == `Stop || stallreq == `Stop) begin - - end else begin - ex_aluop <= id_aluop; - ex_alusel <= id_alusel; - ex_reg1 <= id_reg1; - ex_reg2 <= id_reg2; - ex_wd <= id_wd; - ex_wreg <= id_wreg; - ex_inst_pc <= id_inst_pc; - ex_inst_valid <= id_inst_valid; - ex_link_address <= id_link_address; - ex_inst <= id_inst; - ex_excepttype <= id_excepttype; - ex_current_inst_address <= id_current_inst_address; - ex_csr_signal_i <= id_csr_signal_o; - excp_o <= excp_i; - excp_num_o <= excp_num_i; - end - end - -endmodule diff --git a/src/vsrc/pipeline/2_dispatch/dispatch.sv b/src/vsrc/pipeline/2_dispatch/dispatch.sv new file mode 100644 index 0000000..3769016 --- /dev/null +++ b/src/vsrc/pipeline/2_dispatch/dispatch.sv @@ -0,0 +1,17 @@ + +`include "pipeline_defines.sv" + +module dispatch #( + parameter DECODE_WIDTH = 2 +) ( + input logic clk, + input logic rst, + + // <- ID + input id_dispatch_struct [DECODE_WIDTH-1:0] id_i, + + // Dispatch Port + output logic ex_aluop_o +); + +endmodule diff --git a/src/vsrc/pipeline_defines.sv b/src/vsrc/pipeline_defines.sv new file mode 100644 index 0000000..a57de45 --- /dev/null +++ b/src/vsrc/pipeline_defines.sv @@ -0,0 +1,19 @@ +`ifndef PIPELINE_DEFINES_SV +`define PIPELINE_DEFINES_SV +`include "defines.sv" +`include "instr_info.sv" +`include "csr_defines.sv" + +`define DECODE_WIDTH 2 +typedef struct packed { + logic [`AluOpBus] aluop; + logic [`AluSelBus] alusel; + logic [`RegAddrBus] reg_write_addr; + logic reg_write_valid; + logic instr_valid; + instr_buffer_info_t instr_info; + logic csr_we; + csr_write_signal csr_signal; +} id_dispatch_struct; + +`endif From cbbfd22ad40b7520cf6405fbf7a68f67581aeed2 Mon Sep 17 00:00:00 2001 From: Rookie-rookie-rookie <292601787@qq.com> Date: Sat, 7 May 2022 15:11:23 +0800 Subject: [PATCH 078/114] connect mem and axi --- src/vsrc/AXI/axi_master.sv | 925 ++++++++++++++++++++++++++----------- src/vsrc/cpu_top.sv | 77 ++- 2 files changed, 719 insertions(+), 283 deletions(-) diff --git a/src/vsrc/AXI/axi_master.sv b/src/vsrc/AXI/axi_master.sv index 32a2b11..f51bfed 100644 --- a/src/vsrc/AXI/axi_master.sv +++ b/src/vsrc/AXI/axi_master.sv @@ -1,207 +1,548 @@ -`include "AXI/axi_defines.sv" -module axi_master ( +`include "axi_defines.sv" +module axi_Master ( input wire aclk, input wire aresetn, //low is valid - //CPU - input wire [`ADDR] cpu_addr_i, - input wire cpu_ce_i, - input wire [`Data] cpu_data_i, - input wire cpu_we_i, - input wire [3:0] cpu_sel_i, - input wire stall_i, - input wire flush_i, - output reg [`Data] cpu_data_o, - output wire stallreq, - input wire [3:0] id, //决定是读数据还是取指令 - - //Master - - //ar - - //r - - //aw - - //w - - //b - + // //CPU + // input wire [`ADDR]cpu_addr_i, + // input wire cpu_ce_i, + // input wire [`Data]cpu_data_i, + // input wire cpu_we_i , + // input wire [3:0]cpu_sel_i, + // input wire stall_i, + // input wire flush_i, + // output reg [`Data]cpu_data_o, + // output wire stallreq, + // input wire [3:0]id,//决定是读数据还是取指令 + + //inst + input wire [`ADDR]inst_cpu_addr_i, + input wire inst_cpu_ce_i, + input wire [`Data]inst_cpu_data_i, + input wire inst_cpu_we_i , + input wire [3:0]inst_cpu_sel_i, + input wire inst_stall_i, + input wire inst_flush_i, + output reg [`Data]inst_cpu_data_o, + output wire inst_stallreq, + input wire [3:0]inst_id,//决定是读数据还是取指令 + + //data + input wire [`ADDR]data_cpu_addr_i, + input wire data_cpu_ce_i, + input wire [`Data]data_cpu_data_i, + input wire data_cpu_we_i , + input wire [3:0]data_cpu_sel_i, + input wire data_stall_i, + input wire data_flush_i, + output reg [`Data]data_cpu_data_o, + output wire data_stallreq, + input wire [3:0]data_id,//决定是读数据还是取指令 + //Slave //ar - output reg [`ID] s_arid, //arbitration - output reg [`ADDR] s_araddr, - output wire [`Len] s_arlen, - output reg [`Size] s_arsize, - output wire [`Burst] s_arburst, - output wire [`Lock] s_arlock, - output wire [`Cache] s_arcache, - output wire [`Prot] s_arprot, - output reg s_arvalid, + output wire [`ID]s_arid, //arbitration + output wire [`ADDR]s_araddr, + output wire [`Len]s_arlen, + output wire [`Size]s_arsize, + output wire [`Burst]s_arburst, + output wire [`Lock]s_arlock, + output wire [`Cache]s_arcache, + output wire [`Prot]s_arprot, + output wire s_arvalid, input wire s_arready, //r - input wire [`ID] s_rid, - input wire [`Data] s_rdata, - input wire [`Resp] s_rresp, - input wire s_rlast, //the last read data + input wire [`ID]s_rid, + input wire [`Data]s_rdata, + input wire [`Resp]s_rresp, + input wire s_rlast,//the last read data input wire s_rvalid, - output reg s_rready, + output wire s_rready, //aw - output wire [`ID] s_awid, - output reg [`ADDR] s_awaddr, - output wire [`Len] s_awlen, - output reg [`Size] s_awsize, - output wire [`Burst] s_awburst, - output wire [`Lock] s_awlock, - output wire [`Cache] s_awcache, - output wire [`Prot] s_awprot, + output wire [`ID]s_awid, + output reg [`ADDR]s_awaddr, + output wire [`Len]s_awlen, + output reg [`Size]s_awsize, + output wire [`Burst]s_awburst, + output wire [`Lock]s_awlock, + output wire [`Cache]s_awcache, + output wire [`Prot]s_awprot, output reg s_awvalid, input wire s_awready, //w - output wire [`ID] s_wid, - output reg [`Data] s_wdata, - output wire [3:0] s_wstrb, //字节选通位和sel差不多 - output wire s_wlast, + output wire [`ID]s_wid, + output reg [`Data]s_wdata, + output wire [3:0]s_wstrb,//字节选通位和sel差不多 + output wire s_wlast, output reg s_wvalid, input wire s_wready, //b - input wire [`ID] s_bid, - input wire [`Resp] s_bresp, + input wire [`ID]s_bid, + input wire [`Resp]s_bresp, input wire s_bvalid, output reg s_bready -); - reg stall_req_r; - reg stall_req_w; - - assign stallreq = stall_req_r || stall_req_w; - reg [31:0] data_buffer; +); + reg write_wait_enable; + //read instruction stall + reg inst_stall_req_r; + assign inst_stallreq=inst_stall_req_r; + reg [31:0]inst_buffer; + //read and write data stall + reg stall_req_w; + reg data_stall_req_r; + reg [31:0]data_buffer; + assign data_stallreq=data_stall_req_r||stall_req_w; + + reg [3:0]inst_r_state; + reg [3:0]data_r_state; + + //fetch instruction before fetch data + reg is_fetching_inst; + reg is_fetch_inst_OK; + + //read instruction signal to slave + reg [`ID]inst_s_arid; //arbitration + reg [`ADDR]inst_s_araddr; + reg [`Size]inst_s_arsize; + reg inst_s_arvalid; + //r + reg inst_s_rready; - reg [ 3:0] r_state; +/** +**read state machine for fetch instruction +**/ //改变输出 - always @(*) begin - if (!aresetn) begin - stall_req_r = 0; - cpu_data_o = 0; - end else begin - case (r_state) - `R_FREE: begin - if (cpu_ce_i && cpu_we_i == 0) begin - stall_req_r = 1; - cpu_data_o = 0; - end else begin - stall_req_r = 0; - cpu_data_o = 0; + always @(*) + begin + if(!aresetn)begin + inst_stall_req_r=0; + inst_cpu_data_o=0; + is_fetching_inst=0; + end + else + begin + case(inst_r_state) + `R_FREE:begin + if(inst_cpu_ce_i&&inst_cpu_we_i==0) + begin + inst_stall_req_r=1; + inst_cpu_data_o=0; + //is_fetching_inst=1; + is_fetching_inst=0; + end + else + begin + inst_stall_req_r=0; + inst_cpu_data_o=0; + is_fetching_inst=0; + end + end + `R_ADDR:begin + inst_stall_req_r=1; + inst_cpu_data_o=0; + is_fetching_inst=1; + end + `R_DATA:begin + if(s_rvalid&&s_rlast) + begin + inst_stall_req_r=0; + inst_cpu_data_o=s_rdata; + is_fetching_inst=0; + end + else + begin + inst_stall_req_r=1; + inst_cpu_data_o=0; + is_fetching_inst=1; + end + end + `STALL:begin + inst_stall_req_r=0; + inst_cpu_data_o=inst_buffer; + is_fetching_inst=0; + end + default:begin + end + endcase + end + end + + //read + //state machine + always @(posedge aclk) + begin + if(!aresetn) + begin + inst_r_state<=`R_FREE; + inst_s_arid<=0; + inst_s_araddr<=0; + inst_s_arsize<=0; + inst_buffer<=0; + inst_s_rready<=0; + + inst_s_arvalid<=0; + end + else + begin + case(inst_r_state) + + `R_FREE:begin + if(write_wait_enable==0) + begin + if((inst_cpu_ce_i&&(inst_cpu_we_i==0))&&(!(data_cpu_ce_i&&(data_cpu_we_i==0))))//fetch inst but don't fetch data + begin + inst_r_state<=`R_ADDR; + inst_s_arid<=inst_id; + inst_s_araddr<=inst_cpu_addr_i; + inst_s_arsize<=3'b010; + inst_buffer<=0; + inst_s_rready<=0; + + inst_s_arvalid<=1; + + end + else if((inst_cpu_ce_i&&(inst_cpu_we_i==0))&&(data_cpu_ce_i&&(data_cpu_we_i==0)))//fetch inst and fetch data + begin + //wait for fetch data request run into R_DATA state + if(data_r_state==`R_DATA) + begin + inst_r_state<=`R_ADDR; + inst_s_arid<=inst_id; + inst_s_araddr<=inst_cpu_addr_i; + inst_s_arsize<=3'b010; + inst_buffer<=0; + inst_s_rready<=0; + + inst_s_arvalid<=1; + end + else + begin + inst_r_state<=`R_FREE; + inst_s_arid<=0; + inst_s_araddr<=0; + inst_s_arsize<=0; + inst_buffer<=0; + inst_s_rready<=0; + + inst_s_arvalid<=0; + end + end + else + begin + inst_r_state<=inst_r_state; + inst_s_arid<=0; + inst_s_araddr<=0; + inst_s_arsize<=0; + inst_buffer<=0; + inst_s_rready<=0; + + inst_s_arvalid<=0; + end end + else + begin + inst_r_state<=`R_FREE; + inst_s_arid<=0; + inst_s_araddr<=0; + inst_s_arsize<=0; + inst_buffer<=0; + inst_s_rready<=0; + + inst_s_arvalid<=0; + end + end - `R_ADDR: begin - stall_req_r = 1; - cpu_data_o = 0; + + /** AR **/ + `R_ADDR:begin + + if(s_arready&&s_arvalid) + begin + //wait for fetch data request run into R_FREE state + if(data_cpu_ce_i&&data_cpu_we_i==0) + begin + if(data_r_state==`R_FREE) + begin + inst_r_state<=`R_DATA; + inst_s_arid<=0; + inst_s_araddr<=0; + inst_s_arsize<=0; + inst_buffer<=0; + inst_s_rready<=1; + + inst_s_arvalid<=0; + end + else + begin + inst_r_state<=inst_r_state; + inst_s_arid<=inst_s_arid; + inst_s_araddr<=inst_s_araddr; + inst_s_arsize<=inst_s_arsize; + inst_buffer<=0; + inst_s_rready<=inst_s_rready; + + inst_s_arvalid<=inst_s_arvalid; + end + end + else + begin + inst_r_state<=`R_DATA; + inst_s_arid<=0; + inst_s_araddr<=0; + inst_s_arsize<=0; + inst_buffer<=0; + inst_s_rready<=1; + + inst_s_arvalid<=0; + end + + end + else + begin + inst_r_state<=inst_r_state; + inst_s_arid<=inst_s_arid; + inst_s_araddr<=inst_s_araddr; + inst_s_arsize<=inst_s_arsize; + inst_buffer<=0; + inst_s_rready<=inst_s_rready; + + inst_s_arvalid<=inst_s_arvalid; + + end + + end - `R_DATA: begin - if (s_rvalid && s_rlast) begin - stall_req_r = 0; - cpu_data_o = s_rdata; - end else begin - stall_req_r = 1; - cpu_data_o = 0; + + /** R **/ + `R_DATA:begin + if(s_rvalid&&s_rlast) + begin + if(!(data_cpu_ce_i&&(data_cpu_we_i==0))) + begin + inst_r_state<=`R_FREE; + inst_buffer<=s_rdata; + inst_s_rready<=0; + + inst_s_arid<=0; + inst_s_araddr<=0; + inst_s_arsize<=0; + end + else + begin + inst_r_state<=`STALL; + inst_buffer<=s_rdata; + inst_s_rready<=0; + + inst_s_arid<=0; + inst_s_araddr<=0; + inst_s_arsize<=0; + end + + end + else + begin + inst_r_state<=inst_r_state; + inst_buffer<=0; + inst_s_rready<=inst_s_rready; + + inst_s_arid<=inst_s_arid; + inst_s_araddr<=inst_s_araddr; + inst_s_arsize<=inst_s_arsize; end + + // //set s_rready + // if(~s_rready) + // begin + // s_rready<=1; + // end + // else if(s_rready&&s_rvalid) + // begin + // s_rready<=0; + + // end + // else + // begin + // s_rready<=s_rready; + // end end - default: begin + + /**STALL**/ + `STALL: + begin + if(data_stall_req_r==0) inst_r_state<=`R_FREE; + else inst_r_state<=inst_r_state; end + + default: + begin + + end + + endcase + end + end + + //read data signal to slave + reg [`ID]data_s_arid; //arbitration + reg [`ADDR]data_s_araddr; + reg [`Size]data_s_arsize; + reg data_s_arvalid; + + //r + reg data_s_rready; +/** +**read state machine for fetch data +**/ + + //改变输出 + always @(*) + begin + if(!aresetn)begin + data_stall_req_r=0; + data_cpu_data_o=0; + end + else + begin + case(data_r_state) + `R_FREE:begin + if(data_cpu_ce_i&&data_cpu_we_i==0) + begin + data_stall_req_r=1; + data_cpu_data_o=0; + end + else + begin + data_stall_req_r=0; + data_cpu_data_o=0; + end + end + `R_ADDR:begin + data_stall_req_r=1; + data_cpu_data_o=0; + end + `R_DATA:begin + if(s_rvalid&&s_rlast) + begin + data_stall_req_r=0; + data_cpu_data_o=s_rdata; + end + else + begin + data_stall_req_r=1; + data_cpu_data_o=0; + end + end + default:begin + end endcase end end //read //state machine - always @(posedge aclk) begin - if (!aresetn) begin - r_state <= `R_FREE; - s_arid <= 0; - s_araddr <= 0; - s_arsize <= 0; - data_buffer <= 0; - s_rready <= 0; - - s_arvalid <= 0; - end else begin - case (r_state) - - `R_FREE: begin - - if (cpu_ce_i && (cpu_we_i == 0)) begin - r_state <= `R_ADDR; - s_arid <= 0; - s_araddr <= cpu_addr_i; - s_arsize <= 0; - data_buffer <= 0; - s_rready <= 0; - - s_arvalid <= 1; - - - end else begin - r_state <= r_state; - s_arid <= 0; - s_araddr <= 0; - s_arsize <= 0; - data_buffer <= 0; - s_rready <= 0; - - s_arvalid <= 0; + always @(posedge aclk) + begin + if(!aresetn) + begin + data_r_state<=`R_FREE; + data_s_arid<=0; + data_s_araddr<=0; + data_s_arsize<=0; + data_buffer<=0; + data_s_rready<=0; + + data_s_arvalid<=0; + end + else + begin + case(data_r_state) + + `R_FREE:begin + + if(data_cpu_ce_i&&(data_cpu_we_i==0)&&(is_fetching_inst==0)) + begin + data_r_state<=`R_ADDR; + data_s_arid<=data_id; + data_s_araddr<=data_cpu_addr_i; + data_s_arsize<=3'b010; + data_buffer<=0; + data_s_rready<=0; + + data_s_arvalid<=1; + end + else + begin + data_r_state<=data_r_state; + data_s_arid<=0; + data_s_araddr<=0; + data_s_arsize<=0; + data_buffer<=0; + data_s_rready<=0; + + data_s_arvalid<=0; end end /** AR **/ - `R_ADDR: begin - - if (s_arready && s_arvalid) begin - r_state <= `R_DATA; - s_arid <= id; - s_araddr <= cpu_addr_i; - s_arsize <= 3'b010; - data_buffer <= 0; - s_rready <= 1; - - s_arvalid <= 0; - end else begin - r_state <= r_state; - s_arid <= s_arid; - s_araddr <= s_araddr; - s_arsize <= s_arsize; - data_buffer <= 0; - s_rready <= s_rready; - - s_arvalid <= s_arvalid; - + `R_ADDR:begin + + if(s_arready&&s_arvalid) + begin + data_r_state<=`R_DATA; + data_s_arid<=0; + data_s_araddr<=0; + data_s_arsize<=0; + data_buffer<=0; + data_s_rready<=1; + + data_s_arvalid<=0; end + else + begin + data_r_state<=data_r_state; + data_s_arid<=data_s_arid; + data_s_araddr<=data_s_araddr; + data_s_arsize<=data_s_arsize; + data_buffer<=0; + data_s_rready<=data_s_rready; + data_s_arvalid<=data_s_arvalid; + end + + end /** R **/ - `R_DATA: begin - // if(!aresetn) - // begin - - // end - if (s_rvalid && s_rlast) begin - r_state <= `R_FREE; - data_buffer <= s_rdata; - s_rready <= 0; - end else begin - r_state <= r_state; - data_buffer <= 0; - s_rready <= s_rready; + `R_DATA:begin + if(s_rvalid&&s_rlast) + begin + data_r_state<=`R_FREE; + data_buffer<=s_rdata; + data_s_rready<=0; + + data_s_arid<=0; + data_s_araddr<=0; + data_s_arsize<=0; + end + else + begin + data_r_state<=data_r_state; + data_buffer<=0; + data_s_rready<=data_s_rready; + + data_s_arid<=0; + data_s_araddr<=0; + data_s_arsize<=0; end // //set s_rready @@ -212,7 +553,7 @@ module axi_master ( // else if(s_rready&&s_rvalid) // begin // s_rready<=0; - + // end // else // begin @@ -220,139 +561,190 @@ module axi_master ( // end end - default: begin - + default: + begin + end endcase end end + //set default //ar - assign s_arlen = 0; - assign s_arburst = `INCR; - assign s_arlock = 0; - assign s_arcache = 4'b0000; - assign s_arprot = 3'b000; + assign s_arlen=0; + assign s_arburst=`INCR; + assign s_arlock=0; + assign s_arcache=4'b0000; + assign s_arprot=3'b000; //write //state machine - reg [3:0] w_state; + reg [3:0]w_state; //改变输出 always @(*) begin - if (!aresetn) stall_req_w = 0; - else begin - case (w_state) - `W_FREE: begin - if (cpu_ce_i && (cpu_we_i)) stall_req_w = 1; - else stall_req_w = 0; + if(!aresetn) + begin + stall_req_w=0; + write_wait_enable=0; + end + + else + begin + case(w_state) + `W_FREE:begin + if(data_cpu_ce_i&&(data_cpu_we_i)) + begin + stall_req_w=1; + write_wait_enable=1; + end + else + begin + stall_req_w=0; + write_wait_enable=0; + end end - `W_ADDR, `W_DATA: stall_req_w = 1; - `W_RESP: begin - if (s_bvalid && s_bready) stall_req_w = 0; - else stall_req_w = 1; + `W_ADDR,`W_DATA: + begin + stall_req_w=1; + write_wait_enable=1; end - default: begin - stall_req_w = 0; + `W_RESP:begin + if(s_bvalid&&s_bready) + begin + stall_req_w=0; + write_wait_enable=0; + end + else + begin + stall_req_w=1; + write_wait_enable=1; + end + end + default: + begin end endcase - end - + end + end always @(posedge aclk) begin - if (!aresetn) begin - w_state <= `W_FREE; - s_awaddr <= 0; - s_awsize <= 0; - - s_awvalid <= 0; - s_wdata <= 0; - s_wvalid <= 0; - s_bready <= 0; - end else begin - case (w_state) - - `W_FREE: begin - - if (cpu_ce_i && (cpu_we_i)) begin - w_state <= `W_ADDR; - s_awaddr <= 0; - s_awsize <= 0; - - s_awvalid <= 1; - s_wdata <= 0; - s_wvalid <= 0; - s_bready <= 0; - end else begin - w_state <= w_state; - s_awaddr <= 0; - s_awsize <= 0; - - s_awvalid <= 0; - s_wdata <= 0; - s_wvalid <= 0; - s_bready <= 0; + if(!aresetn) + begin + w_state<=`W_FREE; + s_awaddr<=0; + s_awsize<=0; + + s_awvalid<=0; + s_wdata<=0; + s_wvalid<=0; + s_bready<=0; + end + else + begin + case(w_state) + + `W_FREE:begin + + if(data_cpu_ce_i&&(data_cpu_we_i)) + begin + w_state<=`W_ADDR; + s_awaddr<=data_cpu_addr_i; + s_awsize<=3'b010; + + s_awvalid<=1; + s_wdata<=0; + s_wvalid<=0; + s_bready<=0; + end + else + begin + w_state<=w_state; + s_awaddr<=0; + s_awsize<=0; + + s_awvalid<=0; + s_wdata<=0; + s_wvalid<=0; + s_bready<=0; end end /** AW **/ - `W_ADDR: begin - - if (s_awvalid && s_awready) begin - w_state <= `W_DATA; - s_awaddr <= cpu_addr_i; - s_awsize <= 3'b010; - - s_awvalid <= 0; - s_wvalid <= 1; - s_bready <= 1; - end else begin - w_state <= w_state; - s_awaddr <= s_awaddr; - s_awsize <= s_awsize; - - s_awvalid <= s_awvalid; - s_wvalid <= s_wvalid; - s_bready <= s_bready; + `W_ADDR:begin + + if(s_awvalid&&s_awready) + begin + w_state<=`W_DATA; + s_awaddr<=0; + s_awsize<=0; + + s_awvalid<=0; + s_wvalid<=1; + s_bready<=1; + s_wdata<=data_cpu_data_i; + end + else + begin + w_state<=w_state; + s_awaddr<=s_awaddr; + s_awsize<=s_awsize; + + s_awvalid<=s_awvalid; + s_wvalid<=s_wvalid; + s_bready<=s_bready; + s_wdata<=0; end end /** W **/ - `W_DATA: begin - - if (s_wvalid && s_wready) begin - w_state <= `W_RESP; - s_wdata <= cpu_data_i; - end else begin - w_state <= w_state; - s_wdata <= s_wdata; + `W_DATA:begin + + if(s_wvalid&&s_wready) + begin + w_state<=`W_RESP; + s_wdata<=0; + end + else + begin + w_state<=w_state; + s_wdata<=s_wdata; end //set wvalid - if (s_wvalid && s_wready) begin - s_wvalid <= 0; - end else if (~s_wvalid) begin - s_wvalid <= 1; - end else begin - s_wvalid <= s_wvalid; + if(s_wvalid&&s_wready) + begin + s_wvalid<=0; + end + else if(~s_wvalid) + begin + s_wvalid<=1; + end + else + begin + s_wvalid<=s_wvalid; end end /** B **/ - `W_RESP: begin - - if (s_bvalid && s_bready) begin - w_state <= `W_FREE; - s_bready <= 0; - end else begin - w_state <= w_state; - s_bready <= s_bready; + `W_RESP:begin + + if(s_bvalid&&s_bready) + begin + w_state<=`W_FREE; + s_bready<=0; + end + else + begin + w_state<=w_state; + s_bready<=s_bready; end end - default: begin - + default: + begin + end endcase @@ -361,15 +753,22 @@ module axi_master ( //set default //aw - assign s_awid = 1; - assign s_awlen = 0; - assign s_awburst = `INCR; - assign s_awlock = 0; - assign s_awcache = 0; - assign s_awprot = 0; - assign s_wid = 0; - assign s_wstrb = {4{cpu_we_i}} & cpu_sel_i; - assign s_wlast = 1; - - -endmodule + assign s_awid=1; + assign s_awlen=0; + assign s_awburst=`INCR; + assign s_awlock=0; + assign s_awcache=0; + assign s_awprot=0; + assign s_wid=0; + assign s_wstrb={4{data_cpu_we_i}}&data_cpu_sel_i; + assign s_wlast=1; + + + //set axi signal + assign s_arid=inst_s_arid|data_s_arid; + assign s_araddr=inst_s_araddr|data_s_araddr; + assign s_arsize=inst_s_arsize|data_s_arsize; + assign s_arvalid=inst_s_arvalid|data_s_arvalid; + assign s_rready=inst_s_rready|data_s_rready; + +endmodule \ No newline at end of file diff --git a/src/vsrc/cpu_top.sv b/src/vsrc/cpu_top.sv index 5023c10..426912a 100644 --- a/src/vsrc/cpu_top.sv +++ b/src/vsrc/cpu_top.sv @@ -96,20 +96,57 @@ module cpu_top ( logic [`RegBus] axi_data; logic [`RegBus] axi_addr; + logic data_axi_we; + logic data_axi_ce; + logic [3:0] data_axi_sel; + logic [`RegAddrBus] data_axi_addr; + logic [`RegBus] data_axi_data; + logic data_axi_busy; + + logic data_axi_we_1; + logic data_axi_ce_1; + logic [3:0] data_axi_sel_1; + logic [`RegAddrBus] data_axi_addr_1; + logic [`RegBus] data_axi_data_1; + + logic data_axi_we_2; + logic data_axi_ce_2; + logic [3:0] data_axi_sel_2; + logic [`RegAddrBus] data_axi_addr_2; + logic [`RegBus] data_axi_data_2; + + assign data_axi_we = data_axi_we_1 | data_axi_we_2; + assign data_axi_ce = data_axi_ce_1 | data_axi_ce_2; + assign data_axi_sel = data_axi_we_1 ? data_axi_sel_1 : data_axi_we_2 ? data_axi_sel_2 : 4'b0; + assign data_axi_addr = data_axi_we_1 ? data_axi_addr_1 : data_axi_we_2 ? data_axi_addr_2 : 5'b0; + assign data_axi_data = data_axi_we_1 ? data_axi_data_1 : data_axi_we_2 ? data_axi_data_2 : 32'b0; + axi_master u_axi_master ( .aclk (aclk), .aresetn(aresetn), - .cpu_addr_i(axi_addr), - .cpu_ce_i(axi_addr != 0), // FIXME: ce should not be used as valid? - .cpu_data_i(0), - .cpu_we_i(1'b0), - .cpu_sel_i(4'b1111), - .stall_i(Instram_branch_flag), - .flush_i(Instram_branch_flag), - .cpu_data_o(axi_data), - .stallreq(axi_busy), - .id(4'b0000), // Read Instruction only, TODO: move this from AXI to cache + .inst_cpu_addr_i(axi_addr), + .inst_cpu_ce_i(axi_addr != 0), // FIXME: ce should not be used as valid? + .inst_cpu_data_i(0), + .inst_cpu_we_i(1'b0), + .inst_cpu_sel_i(4'b1111), + .inst_stall_i(Instram_branch_flag), + .inst_flush_i(Instram_branch_flag), + .inst_cpu_data_o(axi_data), + .inst_stallreq(axi_busy), + .inst_id(4'b0000), // Read Instruction only, TODO: move this from AXI to cache + + .data_cpu_addr_i(data_axi_addr), + .data_cpu_ce_i(data_axi_addr != 0), // FIXME: ce should not be used as valid? + .data_cpu_data_i(0), + .data_cpu_we_i(1'b0), + .data_cpu_sel_i(4'b1111), + .data_stall_i(), + .data_flush_i(), + .data_cpu_data_o(data_axi_data), + .data_stallreq(data_axi_busy), + .data_id(4'b0000), + .s_arid(arid), .s_araddr(araddr), .s_arlen(arlen), @@ -779,11 +816,11 @@ module cpu_top ( .wdata_o (mem_reg_wdata_o_1), .aluop_o (mem_aluop_i_1), - .mem_addr_o(dram_addr_o_1), - .mem_we_o (dram_we_o_1), - .mem_sel_o (dram_sel_o_1), - .mem_data_o(dram_data_o_1), - .mem_ce_o (dram_ce_o_1), + .mem_addr_o(data_axi_addr_1), + .mem_we_o (data_axi_we_1), + .mem_sel_o (data_axi_sel_1), + .mem_data_o(data_axi_data_1), + .mem_ce_o (data_axi_ce_1), .LLbit_we_o(mem_LLbit_we_o_1), .LLbit_value_o(mem_LLbit_value_o_1), @@ -861,11 +898,11 @@ module cpu_top ( .wdata_o (mem_reg_wdata_o_2), .aluop_o (mem_aluop_o_2), - .mem_addr_o(dram_addr_o_2), - .mem_we_o (dram_we_o_2), - .mem_sel_o (dram_sel_o_2), - .mem_data_o(dram_data_o_2), - .mem_ce_o (dram_ce_o_2), + .mem_addr_o(data_axi_addr_2), + .mem_we_o (data_axi_we_2), + .mem_sel_o (data_axi_sel_2), + .mem_data_o(data_axi_data_2), + .mem_ce_o (data_axi_ce_2), .LLbit_we_o(mem_LLbit_we_o_2), .LLbit_value_o(mem_LLbit_value_o_2), From cb16ac077504f9b84efd99b36b195296fc59f25c Mon Sep 17 00:00:00 2001 From: Easton Man Date: Sat, 7 May 2022 15:15:10 +0800 Subject: [PATCH 079/114] refactor: finish dispatch logic - move register read to dispatch --- src/vsrc/cpu_top.sv | 337 ++------- src/vsrc/cs_reg.sv | 924 +++++++++++------------ src/vsrc/pipeline/1_decode/id.sv | 32 +- src/vsrc/pipeline/2_dispatch/dispatch.sv | 35 +- src/vsrc/pipeline/3_execution/ex.sv | 45 +- src/vsrc/pipeline_defines.sv | 25 +- 6 files changed, 600 insertions(+), 798 deletions(-) diff --git a/src/vsrc/cpu_top.sv b/src/vsrc/cpu_top.sv index 5023c10..d169457 100644 --- a/src/vsrc/cpu_top.sv +++ b/src/vsrc/cpu_top.sv @@ -14,6 +14,7 @@ `include "pipeline_defines.sv" `include "pipeline/1_decode/id.sv" `include "pipeline/1_decode/id_dispatch.sv" +`include "pipeline/2_dispatch/dispatch.sv" `include "pipeline/3_execution/ex.sv" `include "pipeline/3_execution/ex_mem.sv" `include "pipeline/4_mem/mem.sv" @@ -234,17 +235,16 @@ module cpu_top ( ); // ID <-> Regfile - logic [1:0] id_regfile_reg_read_valid[2]; - logic [`RegNumLog2*2-1:0] id_regfile_reg_read_addr[2]; - logic [1:0][1:0][`RegBus] regfile_id_reg_read_data; + logic [1:0][1:0] dispatch_regfile_reg_read_valid; + logic [1:0][1:0][`RegAddrBus] dispatch_regfile_reg_read_addr; + logic [1:0][1:0][`RegBus] regfile_dispatch_reg_read_data; // ID -> ID_DISPATCH id_dispatch_struct [1:0] id_id_dispatch; // ID Stage generate - genvar i; - for (i = 0; i < 2; i++) begin : id + for (genvar i = 0; i < 2; i++) begin : id id #( .EXE_STAGE_WIDTH(2), // Obviously 2 for now .MEM_STAGE_WIDTH(2) @@ -254,11 +254,6 @@ module cpu_top ( .excp_i (), .excp_num_i (), - // <-> Regfile - .regfile_reg_read_valid_o(id_regfile_reg_read_valid[i]), - .regfile_reg_read_addr_o (id_regfile_reg_read_addr[i]), - .regfile_reg_read_data_i (regfile_id_reg_read_data[i]), - // Data forwarding network, unused for now // TODO: add data forwarding network .ex_write_reg_valid_i (), @@ -286,22 +281,42 @@ module cpu_top ( endgenerate // ID_DISPATCH -> EXE - id_dispatch_struct [1:0] id_dispatch_exe; - + id_dispatch_struct [1:0] id_dispatch_dispatch; - // ID_DISPATCH + // ID -- DISPATCH, Sequential id_dispatch u_id_dispatch ( .clk (clk), .rst (rst), .stall (), .flush (), .id_i (id_id_dispatch), - .dispatch_o(id_dispatch_exe) + .dispatch_o(id_dispatch_dispatch) + ); + + // Dispatch -> EXE + dispatch_ex_struct [1:0] dispatch_exe; + + // Dispatch Stage, Sequential logic + dispatch #( + .DECODE_WIDTH(2) + ) u_dispatch ( + .clk (clk), + .rst (rst), + .id_i(id_dispatch_dispatch), + + // <-> Regfile + .regfile_reg_read_valid_o(dispatch_regfile_reg_read_valid), + .regfile_reg_read_addr_o (dispatch_regfile_reg_read_addr), + .regfile_reg_read_data_i (regfile_dispatch_reg_read_data), + + // -> EXE + .exe_o(dispatch_exe) ); + logic [`RegBus] branch_target_address_1; logic [`RegBus] branch_target_address_2; logic [`RegBus] link_addr; @@ -423,135 +438,44 @@ module cpu_top ( (excp_flush && excp_tlbrefill) ? csr_tlbrentry : ertn_flush ? csr_era : `ZeroWord; - logic if_inst_valid_1; - logic if_inst_valid_2; - logic if_excp_i_1; - logic [3:0] if_excp_num_i_1; - logic if_excp_i_2; - logic [3:0] if_excp_num_i_2; - - - - logic [`InstAddrBus] id_pc_1; - logic [`InstBus] id_inst_1; - logic [`InstAddrBus] id_pc_2; - logic [`InstBus] id_inst_2; - - logic if_excp_o_1; - logic [3:0] if_excp_num_o_1; - logic if_excp_o_2; - logic [3:0] if_excp_num_o_2; - - - logic [`AluOpBus] id_aluop_1; - logic [`AluSelBus] id_alusel_1; - logic [`RegBus] id_reg1_1; - logic [`RegBus] id_reg2_1; - logic [`RegAddrBus] id_reg_waddr_1; - logic id_wreg_1; - logic id_inst_valid_1; - logic [`InstAddrBus] id_inst_pc_1; - logic [`RegBus] id_inst_o_1; - - logic reg1_read_1; - logic reg2_read_1; - logic [`RegAddrBus] reg1_addr_1; - logic [`RegAddrBus] reg2_addr_1; - logic [`RegBus] reg1_data_1; - logic [`RegBus] reg2_data_1; - - logic ex_wreg_o_1; - logic [`RegAddrBus] ex_reg_waddr_o_1; - logic [`RegBus] ex_reg_wdata_1; - logic [`AluOpBus] ex_aluop_o_1; - - logic mem_wreg_o_1; - logic [`RegAddrBus] mem_reg_waddr_o_1; - logic [`RegBus] mem_reg_wdata_o_1; - - logic stallreq_from_id_1; - logic stallreq_from_ex_1; - - logic [1:0] id_excepttype_o_1; - logic [`RegBus] id_current_inst_address_o_1; - - logic ex_wreg_o_2; - logic [`RegAddrBus] ex_reg_waddr_o_2; - logic [`RegBus] ex_reg_wdata_2; - logic [`AluOpBus] ex_aluop_o_2; - - logic mem_wreg_o_2; - logic [`RegAddrBus] mem_reg_waddr_o_2; - logic [`RegBus] mem_reg_wdata_o_2; - - logic [`RegAddrBus] reg1_addr_2; - logic [`RegAddrBus] reg2_addr_2; - - logic [`RegBus] link_addr_1; - logic [`RegBus] link_addr_2; - - logic [`RegAddrBus] id_reg_waddr_2; - - logic stallreq_to_next_1; - logic stallreq_to_next_2; - - logic id_excp_o_1; - logic [8:0] id_excp_num_o_1; - logic id_excp_o_2; - logic [8:0] id_excp_num_o_2; csr_write_signal id_csr_signal_o_1; csr_write_signal id_csr_signal_o_2; - - - logic ex_inst_valid_o_1; - logic [`InstAddrBus] ex_inst_pc_o_1; - logic [`RegBus] ex_addr_o_1; - logic [`RegBus] ex_reg2_o_1; - logic [1:0] ex_excepttype_o_1; - logic [`RegBus] ex_current_inst_address_o_1; csr_write_signal ex_csr_signal_o_1; csr_write_signal ex_csr_signal_o_2; - - ex u_ex_1 ( - .rst(rst), - - .aluop_i(ex_aluop_1), - .alusel_i(ex_alusel_1), - .reg1_i(ex_reg1_1), - .reg2_i(ex_reg2_1), - .wd_i(ex_reg_waddr_i_1), - .wreg_i(ex_wreg_i_1), - .inst_valid_i(ex_inst_valid_i_1), - .inst_pc_i(ex_inst_pc_i_1), - .inst_i(ex_inst_i_1), - .link_addr_i(ex_link_address_1), - .excepttype_i(ex_excepttype_i_1), - .current_inst_address_i(ex_current_inst_address_i_1), - .csr_signal_i(ex_csr_signal_i_1), - - .wreg_o(ex_wreg_o_1), - .wd_o(ex_reg_waddr_o_1), - .wdata_o(ex_reg_wdata_1), - .inst_valid_o(ex_inst_valid_o_1), - .inst_pc_o(ex_inst_pc_o_1), - .aluop_o(ex_aluop_o_1), - .mem_addr_o(ex_addr_o_1), - .reg2_o(ex_reg2_o_1), - .excepttype_o(ex_excepttype_o_1), - .current_inst_address_o(ex_current_inst_address_o_1), - .csr_signal_o(ex_csr_signal_o_1), - - .stallreq(stallreq_from_ex_1), - - .excp_i(ex_excp_i_1), - .excp_num_i(ex_excp_num_i_1), - .excp_o(ex_excp_o_1), - .excp_num_o(ex_excp_num_o_1) - ); + // EXE Stage + generate + for (genvar i = 0; i < 2; i++) begin : ex + ex u_ex ( + .rst(rst), + + .dispatch_i(dispatch_exe[i]), + .excepttype_i(), + .csr_vppn(), + + .wreg_o(), + .wd_o(), + .wdata_o(), + .inst_valid_o(), + .inst_pc_o(), + .aluop_o(), + .mem_addr_o(), + .reg2_o(), + .excepttype_o(), + .csr_signal_o(), + + .stallreq(), + + .excp_i(), + .excp_num_i(), + .excp_o(), + .excp_num_o() + ); + end + endgenerate logic ex_inst_valid_o_2; logic [`InstAddrBus] ex_inst_pc_o_2; @@ -564,43 +488,6 @@ module cpu_top ( logic [31:0] ex_csr_data_o_2; - ex u_ex_2 ( - .rst(rst), - - .aluop_i(ex_aluop_2), - .alusel_i(ex_alusel_2), - .reg1_i(ex_reg1_2), - .reg2_i(ex_reg2_2), - .wd_i(ex_reg_waddr_i_2), - .wreg_i(ex_wreg_i_2), - .inst_valid_i(ex_inst_valid_i_2), - .inst_pc_i(ex_inst_pc_i_2), - .inst_i(ex_inst_i_2), - .link_addr_i(ex_link_address_2), - .excepttype_i(ex_excepttype_i_2), - .current_inst_address_i(ex_current_inst_address_i_2), - .csr_signal_i(ex_csr_signal_i_2), - - .wreg_o(ex_wreg_o_2), - .wd_o(ex_reg_waddr_o_2), - .wdata_o(ex_reg_wdata_2), - .inst_valid_o(ex_inst_valid_o_2), - .inst_pc_o(ex_inst_pc_o_2), - .aluop_o(ex_aluop_o_2), - .mem_addr_o(ex_addr_o_2), - .reg2_o(ex_reg2_o_2), - .excepttype_o(ex_excepttype_o_2), - .current_inst_address_o(ex_current_inst_address_o_2), - .csr_signal_o(ex_csr_signal_o_2), - - .stallreq(stallreq_from_ex_2), - - .excp_i(ex_excp_i_2), - .excp_num_i(ex_excp_num_i_2), - .excp_o(ex_excp_o_2), - .excp_num_o(ex_excp_num_o_2) - ); - logic mem_wreg_i_1; logic [`RegAddrBus] mem_reg_waddr_i_1; @@ -623,103 +510,6 @@ module cpu_top ( logic mem_excp_i_2; logic [9:0] mem_excp_num_i_2; - ex_mem u_ex_mem_1 ( - .clk (clk), - .rst (rst), - .stall(stall1[4]), - - .ex_wd (ex_reg_waddr_o_1), - .ex_wreg (ex_wreg_o_1), - .ex_wdata (ex_reg_wdata_1), - .ex_inst_pc (ex_inst_pc_o_1), - .ex_inst_valid (ex_inst_valid_o_1), - .ex_aluop (ex_aluop_o_1), - .ex_mem_addr (ex_addr_o_1), - .ex_reg2 (ex_reg2_o_1), - .flush (flush), - .ex_excepttype (ex_excepttype_o_1), - .ex_current_inst_address(ex_current_inst_address_o_1), - .ex_csr_signal_o (ex_csr_signal_o_1), - - .mem_wd (mem_reg_waddr_i_1), - .mem_wreg (mem_wreg_i_1), - .mem_wdata (mem_reg_wdata_i_1), - .mem_inst_valid (mem_inst_valid_1), - .mem_inst_pc (mem_inst_pc_1), - .mem_aluop (mem_aluop_i_1), - .mem_mem_addr (mem_addr_i_1), - .mem_reg2 (mem_reg2_i_1), - .mem_excepttype (mem_excepttype_i_1), - .mem_current_inst_address(mem_current_inst_address_i_1), - .mem_csr_signal_i (mem_csr_signal_i_1), - - .excp_i(ex_excp_o_1), - .excp_num_i(ex_excp_num_o_1), - .excp_o(mem_excp_i_1), - .excp_num_o(mem_excp_num_i_1), - - .excp_flush(excp_flush), - .ertn_flush(ertn_flush) - - ); - - - logic mem_wreg_i_2; - logic [`RegAddrBus] mem_reg_waddr_i_2; - logic [`RegBus] mem_reg_wdata_i_2; - - logic mem_inst_valid_2; - logic [`InstAddrBus] mem_inst_pc_2; - - logic [`AluOpBus] mem_aluop_i_2; - logic [`RegBus] mem_addr_i_2; - logic [`RegBus] mem_reg2_i_2; - logic [1:0] mem_excepttype_i_2; - logic [`RegBus] mem_current_inst_address_i_2; - logic mem_csr_we_i_2; - logic [13:0] mem_csr_addr_i_2; - logic [31:0] mem_csr_data_i_2; - - - ex_mem u_ex_mem_2 ( - .clk (clk), - .rst (rst), - .stall(stall2[4]), - - .ex_wd (ex_reg_waddr_o_2), - .ex_wreg (ex_wreg_o_2), - .ex_wdata (ex_reg_wdata_2), - .ex_inst_pc (ex_inst_pc_o_2), - .ex_inst_valid (ex_inst_valid_o_2), - .ex_aluop (ex_aluop_o_2), - .ex_mem_addr (ex_addr_o_2), - .ex_reg2 (ex_reg2_o_2), - .flush (flush), - .ex_excepttype (ex_excepttype_o_2), - .ex_current_inst_address(ex_current_inst_address_o_2), - .ex_csr_signal_o (ex_csr_signal_o_2), - - .mem_wd (mem_reg_waddr_i_2), - .mem_wreg (mem_wreg_i_2), - .mem_wdata (mem_reg_wdata_i_2), - .mem_inst_valid (mem_inst_valid_2), - .mem_inst_pc (mem_inst_pc_2), - .mem_aluop (mem_aluop_i_2), - .mem_mem_addr (mem_addr_i_2), - .mem_reg2 (mem_reg2_i_2), - .mem_excepttype (mem_excepttype_i_2), - .mem_current_inst_address(mem_current_inst_address_i_2), - .mem_csr_signal_i (mem_csr_signal_i_2), - - .excp_i(ex_excp_o_2), - .excp_num_i(ex_excp_num_o_2), - .excp_o(mem_excp_i_2), - .excp_num_o(mem_excp_num_i_2), - - .excp_flush(excp_flush), - .ertn_flush(ertn_flush) - - ); logic LLbit_o_1; logic wb_LLbit_we_i_1; @@ -1069,9 +859,9 @@ module cpu_top ( .wdata_2(wb_reg_wdata_2), // Read signals - .read_valid_i({id_regfile_reg_read_valid[1], id_regfile_reg_read_valid[0]}), - .read_addr_i ({id_regfile_reg_read_addr[1], id_regfile_reg_read_addr[0]}), - .read_data_o (regfile_id_reg_read_data) + .read_valid_i(dispatch_regfile_reg_read_valid), + .read_addr_i (dispatch_regfile_reg_read_addr), + .read_data_o (regfile_dispatch_reg_read_data) ); @@ -1156,8 +946,7 @@ module cpu_top ( .tlbelo0_in(tlbr_tlbelo0), .tlbelo1_in(tlbr_tlbelo1), .tlbidx_in(tlbr_tlbidx), - .asid_in(tlbr_asid), - .csr_diff(csr_diff) + .asid_in(tlbr_asid) ); diff --git a/src/vsrc/cs_reg.sv b/src/vsrc/cs_reg.sv index 6fd0cd4..e3c6f08 100644 --- a/src/vsrc/cs_reg.sv +++ b/src/vsrc/cs_reg.sv @@ -1,4 +1,4 @@ -`timescale 1ns/1ns +`timescale 1ns / 1ns `include "defines.sv" `include "csr_defines.sv" @@ -13,7 +13,7 @@ module cs_reg ( input wire excp_flush, input wire ertn_flush, input wire [8:0] interrupt_i, - input wire [31:0]era_i, + input wire [31:0] era_i, input wire [8:0] esubcode_i, input wire [5:0] ecode_i, input wire va_error_i, @@ -25,153 +25,141 @@ module cs_reg ( input wire excp_tlb, input wire [18:0] excp_tlb_vppn, - input wire[13:0] raddr_1, - output wire[`RegBus] rdata_1, - input wire[13:0] raddr_2, - output wire[`RegBus] rdata_2, + input wire [13:0] raddr_1, + output wire [`RegBus] rdata_1, + input wire [13:0] raddr_2, + output wire [`RegBus] rdata_2, input wire llbit_i, input wire llbit_set_i, output wire llbit_o, - output wire[18:0]vppn_o, + output wire [18:0] vppn_o, //to pc_reg output wire has_int, - output wire[31:0] eentry_out, - output wire[31:0] era_out, - output wire[31:0] tlbrentry_out, + output wire [31:0] eentry_out, + output wire [31:0] era_out, + output wire [31:0] tlbrentry_out, //to tlb - output wire[ 9:0] asid_out, - output wire[ 4:0] rand_index, - output wire[31:0] tlbehi_out, - output wire[31:0] tlbelo0_out, - output wire[31:0] tlbelo1_out, - output wire[31:0] tlbidx_out, + output wire [9:0] asid_out, + output wire [4:0] rand_index, + output wire [31:0] tlbehi_out, + output wire [31:0] tlbelo0_out, + output wire [31:0] tlbelo1_out, + output wire [31:0] tlbidx_out, output wire pg_out, output wire da_out, - output wire[31:0] dmw0_out, - output wire[31:0] dmw1_out, - output wire[1:0] datf_out, - output wire[1:0] datm_out, - output wire[5:0] ecode_out, + output wire [31:0] dmw0_out, + output wire [31:0] dmw1_out, + output wire [1:0] datf_out, + output wire [1:0] datm_out, + output wire [5:0] ecode_out, //from tlb input wire tlbrd_en, - input wire[31:0] tlbehi_in, - input wire[31:0] tlbelo0_in, - input wire[31:0] tlbelo1_in, - input wire[31:0] tlbidx_in, - input wire[ 9:0] asid_in, - - //csr output for difftest - output [831:0] csr_diff + input wire [31:0] tlbehi_in, + input wire [31:0] tlbelo0_in, + input wire [31:0] tlbelo1_in, + input wire [31:0] tlbidx_in, + input wire [9:0] asid_in ); -reg [31:0] csr_crmd; -reg [31:0] csr_prmd; -reg [31:0] csr_ectl; -reg [31:0] csr_estat; -reg [31:0] csr_era; -reg [31:0] csr_badv; -reg [31:0] csr_eentry; -reg [31:0] csr_tlbidx; -reg [31:0] csr_tlbehi; -reg [31:0] csr_tlbelo0; -reg [31:0] csr_tlbelo1; -reg [31:0] csr_tlbrentry; -reg [31:0] csr_tid; -reg [31:0] csr_tcfg; -reg [31:0] csr_tval; -reg [31:0] csr_cntc; -reg [31:0] csr_ticlr; -reg [31:0] csr_llbctl; -reg [31:0] csr_asid; -reg [31:0] csr_cpuid; -reg [31:0] csr_pgdl; -reg [31:0] csr_pgdh; -reg [31:0] csr_save0; -reg [31:0] csr_save1; -reg [31:0] csr_save2; -reg [31:0] csr_save3; -reg [31:0] csr_dmw0; -reg [31:0] csr_dmw1; - -wire [31:0] csr_pgd; -reg timer_en; -reg [63:0] timer_64; - -reg llbit; - -wire eret_tlbrefill_excp; -wire tlbrd_valid_wr_en; -wire tlbrd_invalid_wr_en; -wire no_forward; - -//选择有写入信号的进行赋值,同样假设不会有写冲突 -reg we; -reg [13:0]waddr; -reg [`RegBus] wdata; - -always @(*) begin - if(rst)begin - we = 1'b0; - waddr = 14'b0; - wdata = `ZeroWord; - end - else if(write_signal_1.we == 1'b1)begin - we = write_signal_1.we; - waddr = write_signal_1.addr; - wdata = write_signal_1.data; - end - else if(write_signal_2.we == 1'b1)begin - we = write_signal_2.we; - waddr = write_signal_2.addr; - wdata = write_signal_2.data; - end - else begin - we = 1'b0; - waddr = 14'b0; - wdata = `ZeroWord; - end -end - - -//csr_difftest output -assign csr_diff = {csr_crmd,csr_prmd,csr_ectl,csr_estat,csr_era,csr_badv,csr_eentry,csr_tlbidx, - csr_tlbehi,csr_tlbelo0,csr_tlbelo1,csr_asid,csr_save0,csr_save1,csr_save2, - csr_save3,csr_tid,csr_tcfg,csr_tval,csr_ticlr,{csr_llbctl[31:1], llbit}, - csr_tlbrentry,csr_dmw0,csr_dmw1,csr_pgdl,csr_pgdh }; -//data to pc_reg -assign no_forward = !excp_tlbrefill && !(eret_tlbrefill_excp && ertn_flush) && !(we == 1'b1 && waddr == `CRMD); - -assign pg_out = excp_tlbrefill & 1'b0 | + reg [31:0] csr_crmd; + reg [31:0] csr_prmd; + reg [31:0] csr_ectl; + reg [31:0] csr_estat; + reg [31:0] csr_era; + reg [31:0] csr_badv; + reg [31:0] csr_eentry; + reg [31:0] csr_tlbidx; + reg [31:0] csr_tlbehi; + reg [31:0] csr_tlbelo0; + reg [31:0] csr_tlbelo1; + reg [31:0] csr_tlbrentry; + reg [31:0] csr_tid; + reg [31:0] csr_tcfg; + reg [31:0] csr_tval; + reg [31:0] csr_cntc; + reg [31:0] csr_ticlr; + reg [31:0] csr_llbctl; + reg [31:0] csr_asid; + reg [31:0] csr_cpuid; + reg [31:0] csr_pgdl; + reg [31:0] csr_pgdh; + reg [31:0] csr_save0; + reg [31:0] csr_save1; + reg [31:0] csr_save2; + reg [31:0] csr_save3; + reg [31:0] csr_dmw0; + reg [31:0] csr_dmw1; + + wire [31:0] csr_pgd; + reg timer_en; + reg [63:0] timer_64; + + reg llbit; + + wire eret_tlbrefill_excp; + wire tlbrd_valid_wr_en; + wire tlbrd_invalid_wr_en; + wire no_forward; + + //选择有写入信号的进行赋值,同样假设不会有写冲突 + reg we; + reg [13:0] waddr; + reg [`RegBus] wdata; + + always @(*) begin + if (rst) begin + we = 1'b0; + waddr = 14'b0; + wdata = `ZeroWord; + end else if (write_signal_1.we == 1'b1) begin + we = write_signal_1.we; + waddr = write_signal_1.addr; + wdata = write_signal_1.data; + end else if (write_signal_2.we == 1'b1) begin + we = write_signal_2.we; + waddr = write_signal_2.addr; + wdata = write_signal_2.data; + end else begin + we = 1'b0; + waddr = 14'b0; + wdata = `ZeroWord; + end + end + + //data to pc_reg + assign no_forward = !excp_tlbrefill && !(eret_tlbrefill_excp && ertn_flush) && !(we == 1'b1 && waddr == `CRMD); + + assign pg_out = excp_tlbrefill & 1'b0 | (eret_tlbrefill_excp && ertn_flush) & 1'b1 | (we == 1'b1 && waddr == `CRMD) & wdata[`PG] | no_forward & csr_crmd[`PG]; -assign da_out = excp_tlbrefill & 1'b1 | + assign da_out = excp_tlbrefill & 1'b1 | (eret_tlbrefill_excp && ertn_flush) & 1'b0 | (we == 1'b1 && waddr == `CRMD) & wdata[`DA] | no_forward & csr_crmd[`DA]; -assign eret_tlbrefill_excp = csr_estat[`ECODE] == 6'h3f; + assign eret_tlbrefill_excp = csr_estat[`ECODE] == 6'h3f; -assign tlbrd_valid_wr_en = tlbrd_en && !tlbidx_in[`NE]; -assign tlbrd_invalid_wr_en = tlbrd_en && tlbidx_in[`NE]; + assign tlbrd_valid_wr_en = tlbrd_en && !tlbidx_in[`NE]; + assign tlbrd_invalid_wr_en = tlbrd_en && tlbidx_in[`NE]; -assign dmw0_out = we == 1'b1 && waddr == `DMW0 ? wdata : csr_dmw0; -assign dmw1_out = we == 1'b1 && waddr == `DMW1 ? wdata : csr_dmw1; + assign dmw0_out = we == 1'b1 && waddr == `DMW0 ? wdata : csr_dmw0; + assign dmw1_out = we == 1'b1 && waddr == `DMW1 ? wdata : csr_dmw1; -assign has_int = ((csr_ectl[`LIE] & csr_estat[`IS]) != 13'b0) & csr_crmd[`IE]; + assign has_int = ((csr_ectl[`LIE] & csr_estat[`IS]) != 13'b0) & csr_crmd[`IE]; -assign plv_out = {2{excp_flush}} & 2'b0 | + assign plv_out = {2{excp_flush}} & 2'b0 | {2{ertn_flush}} & csr_prmd[`PPLV] | {2{(we == 1'b1 && waddr == `CRMD) }} & wdata[`PLV] | {2{!excp_flush && !ertn_flush && !(we == 1'b1 && waddr == `CRMD)}} & csr_crmd[`PLV]; - assign rdata_1 = {32{raddr_1 == `CRMD }} & csr_crmd | + assign rdata_1 = {32{raddr_1 == `CRMD }} & csr_crmd | {32{raddr_1 == `PRMD }} & csr_prmd | {32{raddr_1 == `ECTL }} & csr_ectl | {32{raddr_1 == `ESTAT }} & csr_estat | @@ -232,394 +220,350 @@ assign plv_out = {2{excp_flush}} & 2'b0 | {32{raddr_2 == `DMW1}} & csr_dmw1 ; -//crmd -always @(posedge clk) begin - if (rst) begin - csr_crmd[`PLV] <= 2'b0; - csr_crmd[`IE] <= 1'b0; - csr_crmd[`DA] <= 1'b1; - csr_crmd[`PG] <= 1'b0; - csr_crmd[`DATF] <= 2'b0; - csr_crmd[`DATM] <= 2'b0; - csr_crmd[31:9] <= 23'b0; - end - else if (ertn_flush) begin - csr_crmd[`PLV] <= 2'b0; - csr_crmd[`IE] <= 1'b0; - if (excp_tlbrefill) begin - csr_crmd [`DA] <= 1'b1; - csr_crmd [`PG] <= 1'b0; + //crmd + always @(posedge clk) begin + if (rst) begin + csr_crmd[`PLV] <= 2'b0; + csr_crmd[`IE] <= 1'b0; + csr_crmd[`DA] <= 1'b1; + csr_crmd[`PG] <= 1'b0; + csr_crmd[`DATF] <= 2'b0; + csr_crmd[`DATM] <= 2'b0; + csr_crmd[31:9] <= 23'b0; + end else if (ertn_flush) begin + csr_crmd[`PLV] <= 2'b0; + csr_crmd[`IE] <= 1'b0; + if (excp_tlbrefill) begin + csr_crmd[`DA] <= 1'b1; + csr_crmd[`PG] <= 1'b0; + end + end else if (excp_flush) begin + csr_crmd[`PLV] <= csr_prmd[`PPLV]; + csr_crmd[`IE] <= csr_prmd[`PIE]; + if (eret_tlbrefill_excp) begin + csr_crmd[`DA] <= 1'b0; + csr_crmd[`PG] <= 1'b1; + end + end else if (we == 1'b1 && waddr == `CRMD) begin + csr_crmd[`PLV] <= wdata[`PLV]; + csr_crmd[`IE] <= wdata[`IE]; + csr_crmd[`DA] <= wdata[`DA]; + csr_crmd[`PG] <= wdata[`PG]; + csr_crmd[`DATF] <= wdata[`DATF]; + csr_crmd[`DATM] <= wdata[`DATM]; end end - else if(excp_flush)begin - csr_crmd[`PLV] <= csr_prmd[`PPLV]; - csr_crmd[`IE] <= csr_prmd[`PIE]; - if(eret_tlbrefill_excp)begin - csr_crmd[`DA] <= 1'b0; - csr_crmd[`PG] <= 1'b1; + + //prmd + always @(posedge clk) begin + if (rst) begin + csr_prmd[31:3] <= 29'b0; + end else if (excp_flush) begin + csr_prmd[`PPLV] <= csr_crmd[`PLV]; + csr_prmd[`PIE] <= csr_crmd[`IE]; + end else if (we == 1'b1 && waddr == `PRMD) begin + csr_prmd[`PPLV] <= wdata[`PPLV]; + csr_prmd[`PIE] <= wdata[`PIE]; end - end - else if (we == 1'b1 && waddr == `CRMD) begin - csr_crmd[`PLV] <= wdata[`PLV]; - csr_crmd[`IE] <= wdata[`IE]; - csr_crmd[`DA] <= wdata[`DA]; - csr_crmd[`PG] <= wdata[`PG]; - csr_crmd[`DATF] <= wdata[`DATF]; - csr_crmd[`DATM] <= wdata[`DATM]; - end -end - -//prmd -always @(posedge clk) begin - if (rst) begin - csr_prmd[31:3] <= 29'b0; - end - else if (excp_flush) begin - csr_prmd[`PPLV] <= csr_crmd[`PLV]; - csr_prmd[`PIE] <= csr_crmd[`IE]; - end - else if (we == 1'b1 && waddr == `PRMD) begin - csr_prmd[`PPLV] <= wdata[`PPLV]; - csr_prmd[`PIE] <= wdata[`PIE]; - end -end - -//ectl -always @(posedge clk) begin - if (rst) - csr_ectl <= 32'b0; - else if(we == 1'b1 && waddr == `ECTL) - csr_ectl[`LIE] <= wdata[`LIE]; -end - -always @(posedge clk) begin - -end - -//estate -always @(posedge clk) begin - if(rst)begin - csr_estat[1:0] <= 2'b0; - csr_estat[15:13] <= 3'b0; - csr_estat[31] <= 1'b0; - timer_en <= 1'b0; - end - else begin - if (we == 1'b1 && waddr == `TICLR && wdata[`CLR]) - csr_estat[11] <= 1'b0; - else if (we == 1'b1 && waddr == `TCFG) - timer_en <= wdata[`EN]; - else if (timer_en && (csr_tval == 32'b0)) begin - csr_estat[11] <= 1'b1; - timer_en <= csr_tcfg[`PERIODIC]; + end + + //ectl + always @(posedge clk) begin + if (rst) csr_ectl <= 32'b0; + else if (we == 1'b1 && waddr == `ECTL) csr_ectl[`LIE] <= wdata[`LIE]; + end + + always @(posedge clk) begin + + end + + //estate + always @(posedge clk) begin + if (rst) begin + csr_estat[1:0] <= 2'b0; + csr_estat[15:13] <= 3'b0; + csr_estat[31] <= 1'b0; + timer_en <= 1'b0; + end else begin + if (we == 1'b1 && waddr == `TICLR && wdata[`CLR]) csr_estat[11] <= 1'b0; + else if (we == 1'b1 && waddr == `TCFG) timer_en <= wdata[`EN]; + else if (timer_en && (csr_tval == 32'b0)) begin + csr_estat[11] <= 1'b1; + timer_en <= csr_tcfg[`PERIODIC]; + end + csr_estat[10:2] <= interrupt_i; + if (excp_flush) begin + csr_estat[`ECODE] <= ecode_i; + csr_estat[`ESUBCODE] <= esubcode_i; + end else if (we == 1'b1 && waddr == `ESTAT) begin + csr_estat[1:0] <= wdata[1:0]; + end end - csr_estat[10:2] <= interrupt_i; + end + + //era + always @(posedge clk) begin if (excp_flush) begin - csr_estat[`ECODE] <= ecode_i; - csr_estat[`ESUBCODE] <= esubcode_i; + csr_era <= era_i; + end else if (we == 1'b1 && waddr == `ERA) begin + csr_era <= wdata; end - else if (we == 1'b1 && waddr == `ESTAT) begin - csr_estat[ 1:0] <= wdata[ 1:0]; + end + + //badv + always @(posedge clk) begin + if (we == 1'b1 && waddr == `BADV) begin + csr_badv <= wdata; + end else if (va_error_i) begin + csr_badv <= bad_va_i; end end -end - -//era -always @(posedge clk) begin - if (excp_flush) begin - csr_era <= era_i; - end - else if (we == 1'b1 && waddr == `ERA) begin - csr_era <= wdata; - end -end - -//badv -always @(posedge clk) begin - if (we == 1'b1 && waddr == `BADV) begin - csr_badv <= wdata; - end - else if (va_error_i) begin - csr_badv <= bad_va_i; - end -end - -//eentry -always @(posedge clk) begin - if (rst) begin - csr_eentry[5:0] <= 6'b0; - end - else if (we == 1'b1 && waddr == `EENTRY) begin - csr_eentry[31:6] <= wdata[31:6]; - end -end - -//cpuid -always @(posedge clk) begin - if (rst) begin - csr_cpuid <= 32'b0; - end -end - -//save0 -always @(posedge clk) begin - if (we == 1'b1 && waddr == `SAVE0) csr_save0 <= wdata; -end - -//save1 -always @(posedge clk) begin - if (we == 1'b1 && waddr == `SAVE1) csr_save1 <= wdata; -end - -//save2 -always @(posedge clk) begin - if (we == 1'b1 && waddr == `SAVE2) csr_save2 <= wdata; -end - -//save3 -always @(posedge clk) begin - if (we == 1'b1 && waddr == `SAVE3) csr_save3 <= wdata; -end - -//pgdl -always @(posedge clk) begin - if (we == 1'b1 && waddr == `PGDL) csr_pgdl[`BASE] <= wdata[`BASE]; -end - -//pgdh -always @(posedge clk) begin - if (we == 1'b1 && waddr == `PGDH) csr_pgdh[`BASE] <= wdata[`BASE]; -end - -//tlbidx -always @(posedge clk) begin - if(rst)begin - csr_tlbidx[23:5] <= 19'b0; - csr_tlbidx[30] <= 1'b0; - end - else if (we == 1'b1 && waddr == `TLBIDX) begin - csr_tlbidx[`INDEX] <= wdata[`INDEX]; - csr_tlbidx[`PS] <= wdata[`PS]; - csr_tlbidx[`NE] <= wdata[`NE]; - end - else if (tlbsrch_en) begin - if (tlbsrch_found) begin - csr_tlbidx[`INDEX] <= tlbsrch_index; - csr_tlbidx[`NE] <= 1'b0; + + //eentry + always @(posedge clk) begin + if (rst) begin + csr_eentry[5:0] <= 6'b0; + end else if (we == 1'b1 && waddr == `EENTRY) begin + csr_eentry[31:6] <= wdata[31:6]; end - else begin - csr_tlbidx[`NE] <= 1'b1; + end + + //cpuid + always @(posedge clk) begin + if (rst) begin + csr_cpuid <= 32'b0; end end - else if (tlbrd_en && !tlbidx_in[`NE]) begin - csr_tlbidx[`PS] <= tlbidx_in[`PS]; - csr_tlbidx[`NE] <= tlbidx_in[`NE]; - end - else if (tlbrd_en && tlbidx_in[`NE]) begin - csr_tlbidx[`NE] <= tlbidx_in[`NE]; - end -end - -//tlbehi -always @(posedge clk) begin - if(rst) - csr_tlbehi[12:0] <= 13'b0; - else if(we == 1'b1 && waddr == `TLBEHI) - csr_tlbehi[`VPPN] <= wdata[`VPPN]; - else if(excp_tlb) - csr_tlbehi[`VPPN] <= excp_tlb_vppn; -end - -//tlbelo0 -always @(posedge clk) begin - if(rst) - csr_tlbelo0[7] <= 1'b0; - else if(we == 1'b1 && waddr == `TLBELO0)begin - csr_tlbelo0[`TLB_V] <= wdata[`TLB_V]; - csr_tlbelo0[`TLB_D] <= wdata[`TLB_D]; - csr_tlbelo0[`TLB_PLV] <= wdata[`TLB_PLV]; - csr_tlbelo0[`TLB_MAT] <= wdata[`TLB_MAT]; - csr_tlbelo0[`TLB_G] <= wdata[`TLB_G]; - csr_tlbelo0[`TLB_PPN] <= wdata[`TLB_PPN]; - end - else if (tlbrd_valid_wr_en) begin - csr_tlbelo0[`TLB_V] <= tlbelo0_in[`TLB_V]; - csr_tlbelo0[`TLB_D] <= tlbelo0_in[`TLB_D]; - csr_tlbelo0[`TLB_PLV] <= tlbelo0_in[`TLB_PLV]; - csr_tlbelo0[`TLB_MAT] <= tlbelo0_in[`TLB_MAT]; - csr_tlbelo0[`TLB_G] <= tlbelo0_in[`TLB_G]; - csr_tlbelo0[`TLB_PPN] <= tlbelo0_in[`TLB_PPN]; - end -end - -//tlbelo1 -always @(posedge clk) begin - if(rst) - csr_tlbelo1[7] <= 1'b0; - else if(we == 1'b1 && waddr == `TLBELO1)begin - csr_tlbelo1[`TLB_V] <= wdata[`TLB_V]; - csr_tlbelo1[`TLB_D] <= wdata[`TLB_D]; - csr_tlbelo1[`TLB_PLV] <= wdata[`TLB_PLV]; - csr_tlbelo1[`TLB_MAT] <= wdata[`TLB_MAT]; - csr_tlbelo1[`TLB_G] <= wdata[`TLB_G]; - csr_tlbelo1[`TLB_PPN] <= wdata[`TLB_PPN]; - end - else if (tlbrd_valid_wr_en) begin - csr_tlbelo1[`TLB_V] <= tlbelo1_in[`TLB_V]; - csr_tlbelo1[`TLB_D] <= tlbelo1_in[`TLB_D]; - csr_tlbelo1[`TLB_PLV] <= tlbelo1_in[`TLB_PLV]; - csr_tlbelo1[`TLB_MAT] <= tlbelo1_in[`TLB_MAT]; - csr_tlbelo1[`TLB_G] <= tlbelo1_in[`TLB_G]; - csr_tlbelo1[`TLB_PPN] <= tlbelo1_in[`TLB_PPN]; - end -end - -//asid -always @(posedge clk) begin - if(rst) - csr_asid[31:10] <= 22'h280; - else if(we == 1'b1 && waddr == `ASID) - csr_asid[`TLB_ASID] <= wdata[`TLB_ASID]; - else if(tlbrd_valid_wr_en) - csr_asid[`TLB_ASID] <= asid_in; -end - -//pgdl -always @(posedge clk) begin - if (we == 1'b1 && waddr == `PGDL) begin - csr_pgdl[`BASE] <= wdata[`BASE]; - end -end - -//pgdh -always @(posedge clk) begin - if (we == 1'b1 && waddr == `PGDH) begin - csr_pgdh[`BASE] <= wdata[`BASE]; - end -end - -//llbctl -always @(posedge clk) begin - if (rst) begin - csr_llbctl[`KLO] <= 1'b0; - csr_llbctl[31:3] <= 29'b0; - llbit <= 1'b0; - end - else if (ertn_flush) begin - if (csr_llbctl[`KLO]) begin - csr_llbctl[`KLO] <= 1'b0; + + //save0 + always @(posedge clk) begin + if (we == 1'b1 && waddr == `SAVE0) csr_save0 <= wdata; + end + + //save1 + always @(posedge clk) begin + if (we == 1'b1 && waddr == `SAVE1) csr_save1 <= wdata; + end + + //save2 + always @(posedge clk) begin + if (we == 1'b1 && waddr == `SAVE2) csr_save2 <= wdata; + end + + //save3 + always @(posedge clk) begin + if (we == 1'b1 && waddr == `SAVE3) csr_save3 <= wdata; + end + + //pgdl + always @(posedge clk) begin + if (we == 1'b1 && waddr == `PGDL) csr_pgdl[`BASE] <= wdata[`BASE]; + end + + //pgdh + always @(posedge clk) begin + if (we == 1'b1 && waddr == `PGDH) csr_pgdh[`BASE] <= wdata[`BASE]; + end + + //tlbidx + always @(posedge clk) begin + if (rst) begin + csr_tlbidx[23:5] <= 19'b0; + csr_tlbidx[30] <= 1'b0; + end else if (we == 1'b1 && waddr == `TLBIDX) begin + csr_tlbidx[`INDEX] <= wdata[`INDEX]; + csr_tlbidx[`PS] <= wdata[`PS]; + csr_tlbidx[`NE] <= wdata[`NE]; + end else if (tlbsrch_en) begin + if (tlbsrch_found) begin + csr_tlbidx[`INDEX] <= tlbsrch_index; + csr_tlbidx[`NE] <= 1'b0; + end else begin + csr_tlbidx[`NE] <= 1'b1; + end + end else if (tlbrd_en && !tlbidx_in[`NE]) begin + csr_tlbidx[`PS] <= tlbidx_in[`PS]; + csr_tlbidx[`NE] <= tlbidx_in[`NE]; + end else if (tlbrd_en && tlbidx_in[`NE]) begin + csr_tlbidx[`NE] <= tlbidx_in[`NE]; end - else begin - llbit <= 1'b0; + end + + //tlbehi + always @(posedge clk) begin + if (rst) csr_tlbehi[12:0] <= 13'b0; + else if (we == 1'b1 && waddr == `TLBEHI) csr_tlbehi[`VPPN] <= wdata[`VPPN]; + else if (excp_tlb) csr_tlbehi[`VPPN] <= excp_tlb_vppn; + end + + //tlbelo0 + always @(posedge clk) begin + if (rst) csr_tlbelo0[7] <= 1'b0; + else if (we == 1'b1 && waddr == `TLBELO0) begin + csr_tlbelo0[`TLB_V] <= wdata[`TLB_V]; + csr_tlbelo0[`TLB_D] <= wdata[`TLB_D]; + csr_tlbelo0[`TLB_PLV] <= wdata[`TLB_PLV]; + csr_tlbelo0[`TLB_MAT] <= wdata[`TLB_MAT]; + csr_tlbelo0[`TLB_G] <= wdata[`TLB_G]; + csr_tlbelo0[`TLB_PPN] <= wdata[`TLB_PPN]; + end else if (tlbrd_valid_wr_en) begin + csr_tlbelo0[`TLB_V] <= tlbelo0_in[`TLB_V]; + csr_tlbelo0[`TLB_D] <= tlbelo0_in[`TLB_D]; + csr_tlbelo0[`TLB_PLV] <= tlbelo0_in[`TLB_PLV]; + csr_tlbelo0[`TLB_MAT] <= tlbelo0_in[`TLB_MAT]; + csr_tlbelo0[`TLB_G] <= tlbelo0_in[`TLB_G]; + csr_tlbelo0[`TLB_PPN] <= tlbelo0_in[`TLB_PPN]; + end + end + + //tlbelo1 + always @(posedge clk) begin + if (rst) csr_tlbelo1[7] <= 1'b0; + else if (we == 1'b1 && waddr == `TLBELO1) begin + csr_tlbelo1[`TLB_V] <= wdata[`TLB_V]; + csr_tlbelo1[`TLB_D] <= wdata[`TLB_D]; + csr_tlbelo1[`TLB_PLV] <= wdata[`TLB_PLV]; + csr_tlbelo1[`TLB_MAT] <= wdata[`TLB_MAT]; + csr_tlbelo1[`TLB_G] <= wdata[`TLB_G]; + csr_tlbelo1[`TLB_PPN] <= wdata[`TLB_PPN]; + end else if (tlbrd_valid_wr_en) begin + csr_tlbelo1[`TLB_V] <= tlbelo1_in[`TLB_V]; + csr_tlbelo1[`TLB_D] <= tlbelo1_in[`TLB_D]; + csr_tlbelo1[`TLB_PLV] <= tlbelo1_in[`TLB_PLV]; + csr_tlbelo1[`TLB_MAT] <= tlbelo1_in[`TLB_MAT]; + csr_tlbelo1[`TLB_G] <= tlbelo1_in[`TLB_G]; + csr_tlbelo1[`TLB_PPN] <= tlbelo1_in[`TLB_PPN]; + end + end + + //asid + always @(posedge clk) begin + if (rst) csr_asid[31:10] <= 22'h280; + else if (we == 1'b1 && waddr == `ASID) csr_asid[`TLB_ASID] <= wdata[`TLB_ASID]; + else if (tlbrd_valid_wr_en) csr_asid[`TLB_ASID] <= asid_in; + end + + //pgdl + always @(posedge clk) begin + if (we == 1'b1 && waddr == `PGDL) begin + csr_pgdl[`BASE] <= wdata[`BASE]; end end - else if (we == 1'b1 && waddr == `LLBCTL) begin - csr_llbctl[ `KLO] <= wdata[ `KLO]; - if (wdata[`WCLLB] == 1'b1) begin + + //pgdh + always @(posedge clk) begin + if (we == 1'b1 && waddr == `PGDH) begin + csr_pgdh[`BASE] <= wdata[`BASE]; + end + end + + //llbctl + always @(posedge clk) begin + if (rst) begin + csr_llbctl[`KLO] <= 1'b0; + csr_llbctl[31:3] <= 29'b0; llbit <= 1'b0; + end else if (ertn_flush) begin + if (csr_llbctl[`KLO]) begin + csr_llbctl[`KLO] <= 1'b0; + end else begin + llbit <= 1'b0; + end + end else if (we == 1'b1 && waddr == `LLBCTL) begin + csr_llbctl[`KLO] <= wdata[`KLO]; + if (wdata[`WCLLB] == 1'b1) begin + llbit <= 1'b0; + end + end else if (llbit_set_i) begin + llbit <= llbit_i; + end + end + + //tlbrentry + always @(posedge clk) begin + if (rst) csr_tlbrentry[5:0] <= 6'b0; + else if (we == 1'b1 && waddr == `TLBRENTRY) + csr_tlbrentry[`TLBRENTRY] <= wdata[`TLBRENTRY_PA]; + end + + + //dmw0 + always @(posedge clk) begin + if (rst) begin + csr_dmw0[2:1] <= 2'b0; + csr_dmw0[24:6] <= 19'b0; + csr_dmw0[28] <= 1'b0; + end else if (we == 1'b1 && waddr == `DMW0) begin + csr_dmw0[`PLV0] <= wdata[`PLV0]; + csr_dmw0[`PLV3] <= wdata[`PLV3]; + csr_dmw0[`DMW_MAT] <= wdata[`DMW_MAT]; + csr_dmw0[`PSEG] <= wdata[`PSEG]; + csr_dmw0[`VSEG] <= wdata[`VSEG]; + end + end + + //dmw1 + always @(posedge clk) begin + if (rst) begin + csr_dmw1[2:1] <= 2'b0; + csr_dmw1[24:6] <= 19'b0; + csr_dmw1[28] <= 1'b0; + end else if (we == 1'b1 && waddr == `DMW0) begin + csr_dmw1[`PLV0] <= wdata[`PLV0]; + csr_dmw1[`PLV3] <= wdata[`PLV3]; + csr_dmw1[`DMW_MAT] <= wdata[`DMW_MAT]; + csr_dmw1[`PSEG] <= wdata[`PSEG]; + csr_dmw1[`VSEG] <= wdata[`VSEG]; + end + end + + + //tid + always @(posedge clk) begin + if (rst) csr_tid <= 32'b0; + else if (we == 1 && waddr == `TID) csr_tid <= wdata; + end + + //tcfg + always @(posedge clk) begin + if (rst) csr_tcfg[`EN] <= 1'b0; + else if (we == 1'b1 && waddr == `TCFG) begin + csr_tcfg[`EN] <= wdata[`EN]; + csr_tcfg[`PERIODIC] <= wdata[`PERIODIC]; + csr_tcfg[`INITVAL] <= wdata[`INITVAL]; end end - else if (llbit_set_i) begin - llbit <= llbit_i; - end -end - -//tlbrentry -always @(posedge clk) begin - if(rst) - csr_tlbrentry[5:0] <= 6'b0; - else if(we == 1'b1 && waddr == `TLBRENTRY) - csr_tlbrentry[`TLBRENTRY] <= wdata[`TLBRENTRY_PA]; -end - - -//dmw0 -always @(posedge clk) begin - if(rst)begin - csr_dmw0[2:1] <= 2'b0; - csr_dmw0[24:6] <= 19'b0; - csr_dmw0[28] <= 1'b0; - end - else if(we == 1'b1 && waddr == `DMW0)begin - csr_dmw0[`PLV0] <= wdata[`PLV0]; - csr_dmw0[`PLV3] <= wdata[`PLV3]; - csr_dmw0[`DMW_MAT] <= wdata[`DMW_MAT]; - csr_dmw0[`PSEG] <= wdata[`PSEG]; - csr_dmw0[`VSEG] <= wdata[`VSEG]; - end -end - -//dmw1 -always @(posedge clk) begin - if(rst)begin - csr_dmw1[2:1] <= 2'b0; - csr_dmw1[24:6] <= 19'b0; - csr_dmw1[28] <= 1'b0; - end - else if(we == 1'b1 && waddr == `DMW0)begin - csr_dmw1[`PLV0] <= wdata[`PLV0]; - csr_dmw1[`PLV3] <= wdata[`PLV3]; - csr_dmw1[`DMW_MAT] <= wdata[`DMW_MAT]; - csr_dmw1[`PSEG] <= wdata[`PSEG]; - csr_dmw1[`VSEG] <= wdata[`VSEG]; - end -end - - -//tid -always @(posedge clk) begin - if(rst) - csr_tid <= 32'b0; - else if(we == 1 && waddr == `TID) - csr_tid <= wdata; -end - -//tcfg -always @(posedge clk) begin - if(rst) - csr_tcfg[`EN] <= 1'b0; - else if(we == 1'b1 && waddr == `TCFG)begin - csr_tcfg[`EN] <= wdata[`EN]; - csr_tcfg[`PERIODIC] <= wdata[`PERIODIC]; - csr_tcfg[ `INITVAL] <= wdata[ `INITVAL]; - end -end - -//cntc -always @(posedge clk) begin - if (rst) begin - csr_cntc <= 32'b0; - end - else if (we == 1'b1 && waddr == `CNTC) begin - csr_cntc <= wdata; - end -end - -//tval -always @(posedge clk) begin - if(rst) - csr_ticlr <= 32'b0; -end - -//llbitc -always @(posedge clk) begin - if(rst)begin - csr_llbctl[`KLO] <= 1'b0; - csr_llbctl[31:3] <= 29'b0; - llbit <= 1'b0; - end - else if (ertn_flush) begin - if (csr_llbctl[`KLO]) csr_llbctl[`KLO] <= 1'b0; - else llbit <= 1'b0; - end - else if (we == 1'b1 && waddr == `LLBCTL) begin - csr_llbctl[`KLO] <= wdata[`KLO]; - if (wdata[`WCLLB] == 1'b1)llbit <= 1'b0; - end - else if (llbit_set_i) llbit <= llbit_i; - -end - - - -endmodule \ No newline at end of file + + //cntc + always @(posedge clk) begin + if (rst) begin + csr_cntc <= 32'b0; + end else if (we == 1'b1 && waddr == `CNTC) begin + csr_cntc <= wdata; + end + end + + //tval + always @(posedge clk) begin + if (rst) csr_ticlr <= 32'b0; + end + + //llbitc + always @(posedge clk) begin + if (rst) begin + csr_llbctl[`KLO] <= 1'b0; + csr_llbctl[31:3] <= 29'b0; + llbit <= 1'b0; + end else if (ertn_flush) begin + if (csr_llbctl[`KLO]) csr_llbctl[`KLO] <= 1'b0; + else llbit <= 1'b0; + end else if (we == 1'b1 && waddr == `LLBCTL) begin + csr_llbctl[`KLO] <= wdata[`KLO]; + if (wdata[`WCLLB] == 1'b1) llbit <= 1'b0; + end else if (llbit_set_i) llbit <= llbit_i; + + end + + + +endmodule diff --git a/src/vsrc/pipeline/1_decode/id.sv b/src/vsrc/pipeline/1_decode/id.sv index 388da9c..cfeeb3c 100644 --- a/src/vsrc/pipeline/1_decode/id.sv +++ b/src/vsrc/pipeline/1_decode/id.sv @@ -5,8 +5,13 @@ `include "pipeline/1_decode/decoder_2R.sv" `include "pipeline/1_decode/decoder_3R.sv" +`include "pipeline/1_decode/decoder_2RI8.sv" `include "pipeline/1_decode/decoder_2RI12.sv" `include "pipeline/1_decode/decoder_2RI16.sv" +`include "pipeline/1_decode/decoder_1RI20.sv" +`include "pipeline/1_decode/decoder_2RI14.sv" +`include "pipeline/1_decode/decoder_CSR.sv" +`include "pipeline/1_decode/decoder_I26.sv" // ID stage @@ -30,11 +35,6 @@ module id #( input logic excp_i, input logic [3:0] excp_num_i, - // <-> Regfile - output logic [1:0] regfile_reg_read_valid_o, // Read valid for 2 regs - output logic [`RegNumLog2*2-1:0] regfile_reg_read_addr_o, // Read addr, {reg2, reg1} - input logic [`RegBus][1:0] regfile_reg_read_data_i, // Read result - // <- EXE // Data forwarding input logic ex_write_reg_valid_i[EXE_STAGE_WIDTH], @@ -101,7 +101,7 @@ module id #( .instr_break (instr_break), .instr_syscall (instr_syscall) ); - decoder_2RI8 U_decoder_2RI8( + decoder_2RI8 U_decoder_2RI8 ( .instr_info_i (instr_buffer_i), .decode_result_valid_o(sub_decoder_valid[2]), .reg_read_valid_o (sub_decoder_reg_read_valid[2]), @@ -135,7 +135,7 @@ module id #( .alusel_o (sub_decoder_alusel[4]) ); - decoder_1RI20 U_decoder_1RI20( + decoder_1RI20 U_decoder_1RI20 ( .instr_info_i (instr_buffer_i), .decode_result_valid_o(sub_decoder_valid[5]), .reg_read_valid_o (sub_decoder_reg_read_valid[5]), @@ -146,7 +146,7 @@ module id #( .aluop_o (sub_decoder_aluop[5]), .alusel_o (sub_decoder_alusel[5]) ); - decoder_2RI14 U_decoder_2RI14( + decoder_2RI14 U_decoder_2RI14 ( .instr_info_i (instr_buffer_i), .decode_result_valid_o(sub_decoder_valid[6]), .reg_read_valid_o (sub_decoder_reg_read_valid[6]), @@ -157,7 +157,7 @@ module id #( .aluop_o (sub_decoder_aluop[6]), .alusel_o (sub_decoder_alusel[6]) ); - decoder_I26 U_decoder_I26( + decoder_I26 U_decoder_I26 ( .instr_info_i (instr_buffer_i), .decode_result_valid_o(sub_decoder_valid[7]), .imm_o (sub_decoder_imm[7]), @@ -166,7 +166,7 @@ module id #( .aluop_o (sub_decoder_aluop[7]), .alusel_o (sub_decoder_alusel[7]) ); - decoder_CSR u_decoder_CSR( + decoder_CSR u_decoder_CSR ( .instr_info_i (instr_buffer_i), .decode_result_valid_o(sub_decoder_valid[8]), .reg_read_valid_o (sub_decoder_reg_read_valid[8]), @@ -176,12 +176,12 @@ module id #( .reg_write_addr_o (sub_decoder_reg_write_addr[8]), .aluop_o (sub_decoder_aluop[8]) ); - // FIXME: I16 and Special not implemented - // Sub-decoder END // Generate imm, using OR logic [`RegBus] imm; + assign dispatch_o.use_imm = imm != 0; // HACK: works for now + assign dispatch_o.imm = imm; always_comb begin imm = 0; for (integer i = 0; i < SUB_DECODER_NUM; i++) begin @@ -211,11 +211,11 @@ module id #( end // Generate output to Regfile always_comb begin - regfile_reg_read_valid_o = 0; - regfile_reg_read_addr_o = 0; + dispatch_o.reg_read_valid = 0; + dispatch_o.reg_read_addr = 0; for (integer i = 0; i < SUB_DECODER_NUM; i++) begin - regfile_reg_read_valid_o = regfile_reg_read_valid_o | sub_decoder_reg_read_valid[i]; - regfile_reg_read_addr_o = regfile_reg_read_addr_o | sub_decoder_reg_read_addr[i]; + dispatch_o.reg_read_valid = dispatch_o.reg_read_valid | sub_decoder_reg_read_valid[i]; + dispatch_o.reg_read_addr = dispatch_o.reg_read_addr | sub_decoder_reg_read_addr[i]; end end diff --git a/src/vsrc/pipeline/2_dispatch/dispatch.sv b/src/vsrc/pipeline/2_dispatch/dispatch.sv index 3769016..401a597 100644 --- a/src/vsrc/pipeline/2_dispatch/dispatch.sv +++ b/src/vsrc/pipeline/2_dispatch/dispatch.sv @@ -10,8 +10,41 @@ module dispatch #( // <- ID input id_dispatch_struct [DECODE_WIDTH-1:0] id_i, + // <-> Regfile + output logic [DECODE_WIDTH-1:0][1:0] regfile_reg_read_valid_o, // Read valid for 2 regs + output logic [DECODE_WIDTH-1:0][`RegNumLog2*2-1:0] regfile_reg_read_addr_o, // Read addr, {reg2, reg1} + input logic [DECODE_WIDTH-1:0][1:0][`RegBus] regfile_reg_read_data_i, // Read result + // Dispatch Port - output logic ex_aluop_o + output dispatch_ex_struct [DECODE_WIDTH-1:0] exe_o ); + // Reset signal + logic rst_n; + assign rst_n = ~rst; + + generate + for (genvar i = 0; i < DECODE_WIDTH; i++) begin + always_ff @(posedge clk or negedge rst_n) begin : dispatch_ff + + // Pass through to EXE + // TODO: add dispatch logic + exe_o[i].instr_valid <= id_i[i].instr_valid; + exe_o[i].instr_info <= id_i[i].instr_info; + exe_o[i].aluop <= id_i[i].aluop; + exe_o[i].alusel <= id_i[i].alusel; + exe_o[i].reg_write_addr <= id_i[i].reg_write_addr; + exe_o[i].reg_write_valid <= id_i[i].reg_write_valid; + exe_o[i].csr_we <= id_i[i].csr_we; + exe_o[i].csr_signal <= id_i[i].csr_signal; + + // Reg read + regfile_reg_read_valid_o[i] <= id_i[i].reg_read_valid; + regfile_reg_read_addr_o[i] <= id_i[i].reg_read_addr; + exe_o[i].oprand1 <= regfile_reg_read_data_i[i][0]; + exe_o[i].oprand2 <= id_i[i].use_imm ? id_i[i].imm : regfile_reg_read_data_i[i][1]; + end + end + endgenerate + endmodule diff --git a/src/vsrc/pipeline/3_execution/ex.sv b/src/vsrc/pipeline/3_execution/ex.sv index ded777d..941fc91 100644 --- a/src/vsrc/pipeline/3_execution/ex.sv +++ b/src/vsrc/pipeline/3_execution/ex.sv @@ -1,22 +1,15 @@ `include "defines.sv" `include "csr_defines.sv" +`include "pipeline_defines.sv" module ex ( input logic rst, - input logic [`AluOpBus] aluop_i, - input logic [`AluSelBus] alusel_i, - input logic [`RegBus] reg1_i, - input logic [`RegBus] reg2_i, - input logic [`RegAddrBus] wd_i, - input logic wreg_i, - input logic inst_valid_i, - input logic [`InstAddrBus] inst_pc_i, - input logic [`RegBus] inst_i, - input logic [`RegBus] link_addr_i, input logic [1:0] excepttype_i, - input logic [`RegBus] current_inst_address_i, - input csr_write_signal csr_signal_i, + + // <- Dispatch + // Information from dispatch + input dispatch_ex_struct dispatch_i, input logic [18:0] csr_vppn, @@ -29,7 +22,6 @@ module ex ( output logic [`RegBus] mem_addr_o, output logic [`RegBus] reg2_o, output logic [1:0] excepttype_o, - output logic [`RegBus] current_inst_address_o, output csr_write_signal csr_signal_o, output logic stallreq, @@ -45,14 +37,35 @@ module ex ( reg [`RegBus] moveout; reg [`RegBus] arithout; + // Assign input + logic [`AluOpBus] aluop_i; + logic [`AluSelBus] alusel_i; + assign aluop_i = dispatch_i.aluop; + assign alusel_i = dispatch_i.alusel; + + logic [`RegBus] reg1_i, reg2_i; + assign reg1_i = dispatch_i.oprand1; + assign reg2_i = dispatch_i.oprand2; + + logic [`RegBus] inst_i, inst_pc_i; + assign inst_i = dispatch_i.instr_info.instr; + assign inst_pc_i = dispatch_i.instr_info.pc; + logic inst_valid_i; + assign inst_valid_i = dispatch_i.instr_valid; + + logic wreg_i; + logic [`RegAddrBus] wd_i; + assign wd_i = dispatch_i.reg_write_addr; + assign wreg_i = dispatch_i.reg_write_valid; + assign aluop_o = aluop_i; assign mem_addr_o = reg1_i + {{20{inst_i[21]}}, inst_i[21:10]}; assign reg2_o = reg2_i; assign excepttype_o = excepttype_i; - assign current_inst_address_o = current_inst_address_i; - + csr_write_signal csr_signal_i; + assign csr_signal_i = dispatch_i.csr_signal; //写入csr的数据,对csrxchg指令进行掩码处理 assign csr_signal_o.we = csr_signal_i.we; assign csr_signal_o.addr = csr_signal_i.addr; @@ -201,7 +214,7 @@ module ex ( wdata_o = arithout; end `EXE_RES_JUMP: begin - wdata_o = link_addr_i; + wdata_o = 0; // FIXME: add link addr end default: begin wdata_o = `ZeroWord; diff --git a/src/vsrc/pipeline_defines.sv b/src/vsrc/pipeline_defines.sv index a57de45..da0ad4f 100644 --- a/src/vsrc/pipeline_defines.sv +++ b/src/vsrc/pipeline_defines.sv @@ -6,14 +6,37 @@ `define DECODE_WIDTH 2 typedef struct packed { + logic instr_valid; + instr_buffer_info_t instr_info; + + // Reg read info + logic use_imm; + logic [`RegBus] imm; + logic [1:0] reg_read_valid; // Read valid for 2 regs + logic [`RegNumLog2*2-1:0] reg_read_addr; // Read addr, {reg2, reg1} + logic [`AluOpBus] aluop; logic [`AluSelBus] alusel; logic [`RegAddrBus] reg_write_addr; logic reg_write_valid; + logic csr_we; + csr_write_signal csr_signal; +} id_dispatch_struct; + + +typedef struct packed { logic instr_valid; instr_buffer_info_t instr_info; + + logic [`RegBus] oprand1; + logic [`RegBus] oprand2; + logic [`AluOpBus] aluop; + logic [`AluSelBus] alusel; + logic [`RegAddrBus] reg_write_addr; + logic reg_write_valid; + logic csr_we; csr_write_signal csr_signal; -} id_dispatch_struct; +} dispatch_ex_struct; `endif From 4e8a90f444a0e2e9de24a28347455c049aa6c71c Mon Sep 17 00:00:00 2001 From: Easton Man Date: Sat, 7 May 2022 15:17:33 +0800 Subject: [PATCH 080/114] fix: fix include error --- src/vsrc/AXI/axi_master.sv | 1020 ++++++++++++++++-------------------- 1 file changed, 463 insertions(+), 557 deletions(-) diff --git a/src/vsrc/AXI/axi_master.sv b/src/vsrc/AXI/axi_master.sv index f51bfed..1342d02 100644 --- a/src/vsrc/AXI/axi_master.sv +++ b/src/vsrc/AXI/axi_master.sv @@ -1,5 +1,5 @@ -`include "axi_defines.sv" -module axi_Master ( +`include "AXI/axi_defines.sv" +module axi_master ( input wire aclk, input wire aresetn, //low is valid @@ -16,347 +16,311 @@ module axi_Master ( // input wire [3:0]id,//决定是读数据还是取指令 //inst - input wire [`ADDR]inst_cpu_addr_i, + input wire [`ADDR] inst_cpu_addr_i, input wire inst_cpu_ce_i, - input wire [`Data]inst_cpu_data_i, - input wire inst_cpu_we_i , - input wire [3:0]inst_cpu_sel_i, + input wire [`Data] inst_cpu_data_i, + input wire inst_cpu_we_i, + input wire [3:0] inst_cpu_sel_i, input wire inst_stall_i, input wire inst_flush_i, - output reg [`Data]inst_cpu_data_o, + output reg [`Data] inst_cpu_data_o, output wire inst_stallreq, - input wire [3:0]inst_id,//决定是读数据还是取指令 + input wire [3:0] inst_id, //决定是读数据还是取指令 //data - input wire [`ADDR]data_cpu_addr_i, + input wire [`ADDR] data_cpu_addr_i, input wire data_cpu_ce_i, - input wire [`Data]data_cpu_data_i, - input wire data_cpu_we_i , - input wire [3:0]data_cpu_sel_i, + input wire [`Data] data_cpu_data_i, + input wire data_cpu_we_i, + input wire [3:0] data_cpu_sel_i, input wire data_stall_i, input wire data_flush_i, - output reg [`Data]data_cpu_data_o, + output reg [`Data] data_cpu_data_o, output wire data_stallreq, - input wire [3:0]data_id,//决定是读数据还是取指令 - + input wire [3:0] data_id, //决定是读数据还是取指令 + //Slave //ar - output wire [`ID]s_arid, //arbitration - output wire [`ADDR]s_araddr, - output wire [`Len]s_arlen, - output wire [`Size]s_arsize, - output wire [`Burst]s_arburst, - output wire [`Lock]s_arlock, - output wire [`Cache]s_arcache, - output wire [`Prot]s_arprot, + output wire [`ID] s_arid, //arbitration + output wire [`ADDR] s_araddr, + output wire [`Len] s_arlen, + output wire [`Size] s_arsize, + output wire [`Burst] s_arburst, + output wire [`Lock] s_arlock, + output wire [`Cache] s_arcache, + output wire [`Prot] s_arprot, output wire s_arvalid, input wire s_arready, //r - input wire [`ID]s_rid, - input wire [`Data]s_rdata, - input wire [`Resp]s_rresp, - input wire s_rlast,//the last read data + input wire [`ID] s_rid, + input wire [`Data] s_rdata, + input wire [`Resp] s_rresp, + input wire s_rlast, //the last read data input wire s_rvalid, output wire s_rready, //aw - output wire [`ID]s_awid, - output reg [`ADDR]s_awaddr, - output wire [`Len]s_awlen, - output reg [`Size]s_awsize, - output wire [`Burst]s_awburst, - output wire [`Lock]s_awlock, - output wire [`Cache]s_awcache, - output wire [`Prot]s_awprot, + output wire [`ID] s_awid, + output reg [`ADDR] s_awaddr, + output wire [`Len] s_awlen, + output reg [`Size] s_awsize, + output wire [`Burst] s_awburst, + output wire [`Lock] s_awlock, + output wire [`Cache] s_awcache, + output wire [`Prot] s_awprot, output reg s_awvalid, input wire s_awready, //w - output wire [`ID]s_wid, - output reg [`Data]s_wdata, - output wire [3:0]s_wstrb,//字节选通位和sel差不多 - output wire s_wlast, + output wire [`ID] s_wid, + output reg [`Data] s_wdata, + output wire [3:0] s_wstrb, //字节选通位和sel差不多 + output wire s_wlast, output reg s_wvalid, input wire s_wready, //b - input wire [`ID]s_bid, - input wire [`Resp]s_bresp, + input wire [`ID] s_bid, + input wire [`Resp] s_bresp, input wire s_bvalid, output reg s_bready -); +); reg write_wait_enable; //read instruction stall reg inst_stall_req_r; - assign inst_stallreq=inst_stall_req_r; - reg [31:0]inst_buffer; + assign inst_stallreq = inst_stall_req_r; + reg [31:0] inst_buffer; //read and write data stall reg stall_req_w; reg data_stall_req_r; - reg [31:0]data_buffer; - assign data_stallreq=data_stall_req_r||stall_req_w; - - reg [3:0]inst_r_state; - reg [3:0]data_r_state; + reg [31:0] data_buffer; + assign data_stallreq = data_stall_req_r || stall_req_w; + + reg [3:0] inst_r_state; + reg [3:0] data_r_state; //fetch instruction before fetch data reg is_fetching_inst; reg is_fetch_inst_OK; //read instruction signal to slave - reg [`ID]inst_s_arid; //arbitration - reg [`ADDR]inst_s_araddr; - reg [`Size]inst_s_arsize; - reg inst_s_arvalid; + reg [`ID] inst_s_arid; //arbitration + reg [`ADDR] inst_s_araddr; + reg [`Size] inst_s_arsize; + reg inst_s_arvalid; //r - reg inst_s_rready; + reg inst_s_rready; -/** + /** **read state machine for fetch instruction **/ //改变输出 - always @(*) - begin - if(!aresetn)begin - inst_stall_req_r=0; - inst_cpu_data_o=0; - is_fetching_inst=0; - end - else - begin - case(inst_r_state) - `R_FREE:begin - if(inst_cpu_ce_i&&inst_cpu_we_i==0) - begin - inst_stall_req_r=1; - inst_cpu_data_o=0; - //is_fetching_inst=1; - is_fetching_inst=0; - end - else - begin - inst_stall_req_r=0; - inst_cpu_data_o=0; - is_fetching_inst=0; - end - end - `R_ADDR:begin - inst_stall_req_r=1; - inst_cpu_data_o=0; - is_fetching_inst=1; + always @(*) begin + if (!aresetn) begin + inst_stall_req_r = 0; + inst_cpu_data_o = 0; + is_fetching_inst = 0; + end else begin + case (inst_r_state) + `R_FREE: begin + if (inst_cpu_ce_i && inst_cpu_we_i == 0) begin + inst_stall_req_r = 1; + inst_cpu_data_o = 0; + //is_fetching_inst=1; + is_fetching_inst = 0; + end else begin + inst_stall_req_r = 0; + inst_cpu_data_o = 0; + is_fetching_inst = 0; end - `R_DATA:begin - if(s_rvalid&&s_rlast) - begin - inst_stall_req_r=0; - inst_cpu_data_o=s_rdata; - is_fetching_inst=0; - end - else - begin - inst_stall_req_r=1; - inst_cpu_data_o=0; - is_fetching_inst=1; - end - end - `STALL:begin - inst_stall_req_r=0; - inst_cpu_data_o=inst_buffer; - is_fetching_inst=0; - end - default:begin - end + end + `R_ADDR: begin + inst_stall_req_r = 1; + inst_cpu_data_o = 0; + is_fetching_inst = 1; + end + `R_DATA: begin + if (s_rvalid && s_rlast) begin + inst_stall_req_r = 0; + inst_cpu_data_o = s_rdata; + is_fetching_inst = 0; + end else begin + inst_stall_req_r = 1; + inst_cpu_data_o = 0; + is_fetching_inst = 1; + end + end + `STALL: begin + inst_stall_req_r = 0; + inst_cpu_data_o = inst_buffer; + is_fetching_inst = 0; + end + default: begin + end endcase end end //read //state machine - always @(posedge aclk) - begin - if(!aresetn) - begin - inst_r_state<=`R_FREE; - inst_s_arid<=0; - inst_s_araddr<=0; - inst_s_arsize<=0; - inst_buffer<=0; - inst_s_rready<=0; - - inst_s_arvalid<=0; - end - else - begin - case(inst_r_state) - - `R_FREE:begin - if(write_wait_enable==0) - begin + always @(posedge aclk) begin + if (!aresetn) begin + inst_r_state <= `R_FREE; + inst_s_arid <= 0; + inst_s_araddr <= 0; + inst_s_arsize <= 0; + inst_buffer <= 0; + inst_s_rready <= 0; + + inst_s_arvalid <= 0; + end else begin + case (inst_r_state) + + `R_FREE: begin + if (write_wait_enable == 0) begin if((inst_cpu_ce_i&&(inst_cpu_we_i==0))&&(!(data_cpu_ce_i&&(data_cpu_we_i==0))))//fetch inst but don't fetch data begin - inst_r_state<=`R_ADDR; - inst_s_arid<=inst_id; - inst_s_araddr<=inst_cpu_addr_i; - inst_s_arsize<=3'b010; - inst_buffer<=0; - inst_s_rready<=0; - - inst_s_arvalid<=1; - + inst_r_state <= `R_ADDR; + inst_s_arid <= inst_id; + inst_s_araddr <= inst_cpu_addr_i; + inst_s_arsize <= 3'b010; + inst_buffer <= 0; + inst_s_rready <= 0; + + inst_s_arvalid <= 1; + end else if((inst_cpu_ce_i&&(inst_cpu_we_i==0))&&(data_cpu_ce_i&&(data_cpu_we_i==0)))//fetch inst and fetch data begin - //wait for fetch data request run into R_DATA state - if(data_r_state==`R_DATA) - begin - inst_r_state<=`R_ADDR; - inst_s_arid<=inst_id; - inst_s_araddr<=inst_cpu_addr_i; - inst_s_arsize<=3'b010; - inst_buffer<=0; - inst_s_rready<=0; - - inst_s_arvalid<=1; + //wait for fetch data request run into R_DATA state + if (data_r_state == `R_DATA) begin + inst_r_state <= `R_ADDR; + inst_s_arid <= inst_id; + inst_s_araddr <= inst_cpu_addr_i; + inst_s_arsize <= 3'b010; + inst_buffer <= 0; + inst_s_rready <= 0; + + inst_s_arvalid <= 1; + end else begin + inst_r_state <= `R_FREE; + inst_s_arid <= 0; + inst_s_araddr <= 0; + inst_s_arsize <= 0; + inst_buffer <= 0; + inst_s_rready <= 0; + + inst_s_arvalid <= 0; end - else - begin - inst_r_state<=`R_FREE; - inst_s_arid<=0; - inst_s_araddr<=0; - inst_s_arsize<=0; - inst_buffer<=0; - inst_s_rready<=0; - - inst_s_arvalid<=0; - end - end - else - begin - inst_r_state<=inst_r_state; - inst_s_arid<=0; - inst_s_araddr<=0; - inst_s_arsize<=0; - inst_buffer<=0; - inst_s_rready<=0; - - inst_s_arvalid<=0; + end else begin + inst_r_state <= inst_r_state; + inst_s_arid <= 0; + inst_s_araddr <= 0; + inst_s_arsize <= 0; + inst_buffer <= 0; + inst_s_rready <= 0; + + inst_s_arvalid <= 0; end + end else begin + inst_r_state <= `R_FREE; + inst_s_arid <= 0; + inst_s_araddr <= 0; + inst_s_arsize <= 0; + inst_buffer <= 0; + inst_s_rready <= 0; + + inst_s_arvalid <= 0; end - else - begin - inst_r_state<=`R_FREE; - inst_s_arid<=0; - inst_s_araddr<=0; - inst_s_arsize<=0; - inst_buffer<=0; - inst_s_rready<=0; - - inst_s_arvalid<=0; - end - + end /** AR **/ - `R_ADDR:begin + `R_ADDR: begin - if(s_arready&&s_arvalid) - begin + if (s_arready && s_arvalid) begin //wait for fetch data request run into R_FREE state - if(data_cpu_ce_i&&data_cpu_we_i==0) - begin - if(data_r_state==`R_FREE) - begin - inst_r_state<=`R_DATA; - inst_s_arid<=0; - inst_s_araddr<=0; - inst_s_arsize<=0; - inst_buffer<=0; - inst_s_rready<=1; - - inst_s_arvalid<=0; - end - else - begin - inst_r_state<=inst_r_state; - inst_s_arid<=inst_s_arid; - inst_s_araddr<=inst_s_araddr; - inst_s_arsize<=inst_s_arsize; - inst_buffer<=0; - inst_s_rready<=inst_s_rready; - - inst_s_arvalid<=inst_s_arvalid; + if (data_cpu_ce_i && data_cpu_we_i == 0) begin + if (data_r_state == `R_FREE) begin + inst_r_state <= `R_DATA; + inst_s_arid <= 0; + inst_s_araddr <= 0; + inst_s_arsize <= 0; + inst_buffer <= 0; + inst_s_rready <= 1; + + inst_s_arvalid <= 0; + end else begin + inst_r_state <= inst_r_state; + inst_s_arid <= inst_s_arid; + inst_s_araddr <= inst_s_araddr; + inst_s_arsize <= inst_s_arsize; + inst_buffer <= 0; + inst_s_rready <= inst_s_rready; + + inst_s_arvalid <= inst_s_arvalid; end - end - else - begin - inst_r_state<=`R_DATA; - inst_s_arid<=0; - inst_s_araddr<=0; - inst_s_arsize<=0; - inst_buffer<=0; - inst_s_rready<=1; - - inst_s_arvalid<=0; + end else begin + inst_r_state <= `R_DATA; + inst_s_arid <= 0; + inst_s_araddr <= 0; + inst_s_arsize <= 0; + inst_buffer <= 0; + inst_s_rready <= 1; + + inst_s_arvalid <= 0; end - end - else - begin - inst_r_state<=inst_r_state; - inst_s_arid<=inst_s_arid; - inst_s_araddr<=inst_s_araddr; - inst_s_arsize<=inst_s_arsize; - inst_buffer<=0; - inst_s_rready<=inst_s_rready; + end else begin + inst_r_state <= inst_r_state; + inst_s_arid <= inst_s_arid; + inst_s_araddr <= inst_s_araddr; + inst_s_arsize <= inst_s_arsize; + inst_buffer <= 0; + inst_s_rready <= inst_s_rready; - inst_s_arvalid<=inst_s_arvalid; + inst_s_arvalid <= inst_s_arvalid; end - + end /** R **/ - `R_DATA:begin - if(s_rvalid&&s_rlast) - begin - if(!(data_cpu_ce_i&&(data_cpu_we_i==0))) - begin - inst_r_state<=`R_FREE; - inst_buffer<=s_rdata; - inst_s_rready<=0; - - inst_s_arid<=0; - inst_s_araddr<=0; - inst_s_arsize<=0; + `R_DATA: begin + if (s_rvalid && s_rlast) begin + if (!(data_cpu_ce_i && (data_cpu_we_i == 0))) begin + inst_r_state <= `R_FREE; + inst_buffer <= s_rdata; + inst_s_rready <= 0; + + inst_s_arid <= 0; + inst_s_araddr <= 0; + inst_s_arsize <= 0; + end else begin + inst_r_state <= `STALL; + inst_buffer <= s_rdata; + inst_s_rready <= 0; + + inst_s_arid <= 0; + inst_s_araddr <= 0; + inst_s_arsize <= 0; end - else - begin - inst_r_state<=`STALL; - inst_buffer<=s_rdata; - inst_s_rready<=0; - inst_s_arid<=0; - inst_s_araddr<=0; - inst_s_arsize<=0; - end + end else begin + inst_r_state <= inst_r_state; + inst_buffer <= 0; + inst_s_rready <= inst_s_rready; - end - else - begin - inst_r_state<=inst_r_state; - inst_buffer<=0; - inst_s_rready<=inst_s_rready; - - inst_s_arid<=inst_s_arid; - inst_s_araddr<=inst_s_araddr; - inst_s_arsize<=inst_s_arsize; + inst_s_arid <= inst_s_arid; + inst_s_araddr <= inst_s_araddr; + inst_s_arsize <= inst_s_arsize; end // //set s_rready @@ -367,7 +331,7 @@ module axi_Master ( // else if(s_rready&&s_rvalid) // begin // s_rready<=0; - + // end // else // begin @@ -376,15 +340,13 @@ module axi_Master ( end /**STALL**/ - `STALL: - begin - if(data_stall_req_r==0) inst_r_state<=`R_FREE; - else inst_r_state<=inst_r_state; + `STALL: begin + if (data_stall_req_r == 0) inst_r_state <= `R_FREE; + else inst_r_state <= inst_r_state; end - default: - begin - + default: begin + end endcase @@ -392,157 +354,135 @@ module axi_Master ( end //read data signal to slave - reg [`ID]data_s_arid; //arbitration - reg [`ADDR]data_s_araddr; - reg [`Size]data_s_arsize; - reg data_s_arvalid; + reg [`ID] data_s_arid; //arbitration + reg [`ADDR] data_s_araddr; + reg [`Size] data_s_arsize; + reg data_s_arvalid; //r - reg data_s_rready; -/** + reg data_s_rready; + /** **read state machine for fetch data **/ //改变输出 - always @(*) - begin - if(!aresetn)begin - data_stall_req_r=0; - data_cpu_data_o=0; - end - else - begin - case(data_r_state) - `R_FREE:begin - if(data_cpu_ce_i&&data_cpu_we_i==0) - begin - data_stall_req_r=1; - data_cpu_data_o=0; - end - else - begin - data_stall_req_r=0; - data_cpu_data_o=0; - end - end - `R_ADDR:begin - data_stall_req_r=1; - data_cpu_data_o=0; + always @(*) begin + if (!aresetn) begin + data_stall_req_r = 0; + data_cpu_data_o = 0; + end else begin + case (data_r_state) + `R_FREE: begin + if (data_cpu_ce_i && data_cpu_we_i == 0) begin + data_stall_req_r = 1; + data_cpu_data_o = 0; + end else begin + data_stall_req_r = 0; + data_cpu_data_o = 0; end - `R_DATA:begin - if(s_rvalid&&s_rlast) - begin - data_stall_req_r=0; - data_cpu_data_o=s_rdata; - end - else - begin - data_stall_req_r=1; - data_cpu_data_o=0; - end - end - default:begin - end + end + `R_ADDR: begin + data_stall_req_r = 1; + data_cpu_data_o = 0; + end + `R_DATA: begin + if (s_rvalid && s_rlast) begin + data_stall_req_r = 0; + data_cpu_data_o = s_rdata; + end else begin + data_stall_req_r = 1; + data_cpu_data_o = 0; + end + end + default: begin + end endcase end end //read //state machine - always @(posedge aclk) - begin - if(!aresetn) - begin - data_r_state<=`R_FREE; - data_s_arid<=0; - data_s_araddr<=0; - data_s_arsize<=0; - data_buffer<=0; - data_s_rready<=0; - - data_s_arvalid<=0; - end - else - begin - case(data_r_state) - - `R_FREE:begin - - if(data_cpu_ce_i&&(data_cpu_we_i==0)&&(is_fetching_inst==0)) - begin - data_r_state<=`R_ADDR; - data_s_arid<=data_id; - data_s_araddr<=data_cpu_addr_i; - data_s_arsize<=3'b010; - data_buffer<=0; - data_s_rready<=0; - - data_s_arvalid<=1; - end - else - begin - data_r_state<=data_r_state; - data_s_arid<=0; - data_s_araddr<=0; - data_s_arsize<=0; - data_buffer<=0; - data_s_rready<=0; - - data_s_arvalid<=0; + always @(posedge aclk) begin + if (!aresetn) begin + data_r_state <= `R_FREE; + data_s_arid <= 0; + data_s_araddr <= 0; + data_s_arsize <= 0; + data_buffer <= 0; + data_s_rready <= 0; + + data_s_arvalid <= 0; + end else begin + case (data_r_state) + + `R_FREE: begin + + if (data_cpu_ce_i && (data_cpu_we_i == 0) && (is_fetching_inst == 0)) begin + data_r_state <= `R_ADDR; + data_s_arid <= data_id; + data_s_araddr <= data_cpu_addr_i; + data_s_arsize <= 3'b010; + data_buffer <= 0; + data_s_rready <= 0; + + data_s_arvalid <= 1; + end else begin + data_r_state <= data_r_state; + data_s_arid <= 0; + data_s_araddr <= 0; + data_s_arsize <= 0; + data_buffer <= 0; + data_s_rready <= 0; + + data_s_arvalid <= 0; end end /** AR **/ - `R_ADDR:begin - - if(s_arready&&s_arvalid) - begin - data_r_state<=`R_DATA; - data_s_arid<=0; - data_s_araddr<=0; - data_s_arsize<=0; - data_buffer<=0; - data_s_rready<=1; - - data_s_arvalid<=0; - end - else - begin - data_r_state<=data_r_state; - data_s_arid<=data_s_arid; - data_s_araddr<=data_s_araddr; - data_s_arsize<=data_s_arsize; - data_buffer<=0; - data_s_rready<=data_s_rready; - - data_s_arvalid<=data_s_arvalid; + `R_ADDR: begin + + if (s_arready && s_arvalid) begin + data_r_state <= `R_DATA; + data_s_arid <= 0; + data_s_araddr <= 0; + data_s_arsize <= 0; + data_buffer <= 0; + data_s_rready <= 1; + + data_s_arvalid <= 0; + end else begin + data_r_state <= data_r_state; + data_s_arid <= data_s_arid; + data_s_araddr <= data_s_araddr; + data_s_arsize <= data_s_arsize; + data_buffer <= 0; + data_s_rready <= data_s_rready; + + data_s_arvalid <= data_s_arvalid; end - + end /** R **/ - `R_DATA:begin - if(s_rvalid&&s_rlast) - begin - data_r_state<=`R_FREE; - data_buffer<=s_rdata; - data_s_rready<=0; - - data_s_arid<=0; - data_s_araddr<=0; - data_s_arsize<=0; - end - else - begin - data_r_state<=data_r_state; - data_buffer<=0; - data_s_rready<=data_s_rready; - - data_s_arid<=0; - data_s_araddr<=0; - data_s_arsize<=0; + `R_DATA: begin + if (s_rvalid && s_rlast) begin + data_r_state <= `R_FREE; + data_buffer <= s_rdata; + data_s_rready <= 0; + + data_s_arid <= 0; + data_s_araddr <= 0; + data_s_arsize <= 0; + end else begin + data_r_state <= data_r_state; + data_buffer <= 0; + data_s_rready <= data_s_rready; + + data_s_arid <= 0; + data_s_araddr <= 0; + data_s_arsize <= 0; end // //set s_rready @@ -553,7 +493,7 @@ module axi_Master ( // else if(s_rready&&s_rvalid) // begin // s_rready<=0; - + // end // else // begin @@ -561,9 +501,8 @@ module axi_Master ( // end end - default: - begin - + default: begin + end endcase @@ -573,178 +512,145 @@ module axi_Master ( //set default //ar - assign s_arlen=0; - assign s_arburst=`INCR; - assign s_arlock=0; - assign s_arcache=4'b0000; - assign s_arprot=3'b000; + assign s_arlen = 0; + assign s_arburst = `INCR; + assign s_arlock = 0; + assign s_arcache = 4'b0000; + assign s_arprot = 3'b000; //write //state machine - reg [3:0]w_state; + reg [3:0] w_state; //改变输出 always @(*) begin - if(!aresetn) - begin - stall_req_w=0; - write_wait_enable=0; - end - - else - begin - case(w_state) - `W_FREE:begin - if(data_cpu_ce_i&&(data_cpu_we_i)) - begin - stall_req_w=1; - write_wait_enable=1; - end - else - begin - stall_req_w=0; - write_wait_enable=0; + if (!aresetn) begin + stall_req_w = 0; + write_wait_enable = 0; + end else begin + case (w_state) + `W_FREE: begin + if (data_cpu_ce_i && (data_cpu_we_i)) begin + stall_req_w = 1; + write_wait_enable = 1; + end else begin + stall_req_w = 0; + write_wait_enable = 0; end end - `W_ADDR,`W_DATA: - begin - stall_req_w=1; - write_wait_enable=1; + `W_ADDR, `W_DATA: begin + stall_req_w = 1; + write_wait_enable = 1; end - `W_RESP:begin - if(s_bvalid&&s_bready) - begin - stall_req_w=0; - write_wait_enable=0; - end - else - begin - stall_req_w=1; - write_wait_enable=1; - end - end - default: - begin + `W_RESP: begin + if (s_bvalid && s_bready) begin + stall_req_w = 0; + write_wait_enable = 0; + end else begin + stall_req_w = 1; + write_wait_enable = 1; + end + end + default: begin end endcase - end - + end + end always @(posedge aclk) begin - if(!aresetn) - begin - w_state<=`W_FREE; - s_awaddr<=0; - s_awsize<=0; - - s_awvalid<=0; - s_wdata<=0; - s_wvalid<=0; - s_bready<=0; - end - else - begin - case(w_state) - - `W_FREE:begin - - if(data_cpu_ce_i&&(data_cpu_we_i)) - begin - w_state<=`W_ADDR; - s_awaddr<=data_cpu_addr_i; - s_awsize<=3'b010; - - s_awvalid<=1; - s_wdata<=0; - s_wvalid<=0; - s_bready<=0; - end - else - begin - w_state<=w_state; - s_awaddr<=0; - s_awsize<=0; - - s_awvalid<=0; - s_wdata<=0; - s_wvalid<=0; - s_bready<=0; + if (!aresetn) begin + w_state <= `W_FREE; + s_awaddr <= 0; + s_awsize <= 0; + + s_awvalid <= 0; + s_wdata <= 0; + s_wvalid <= 0; + s_bready <= 0; + end else begin + case (w_state) + + `W_FREE: begin + + if (data_cpu_ce_i && (data_cpu_we_i)) begin + w_state <= `W_ADDR; + s_awaddr <= data_cpu_addr_i; + s_awsize <= 3'b010; + + s_awvalid <= 1; + s_wdata <= 0; + s_wvalid <= 0; + s_bready <= 0; + end else begin + w_state <= w_state; + s_awaddr <= 0; + s_awsize <= 0; + + s_awvalid <= 0; + s_wdata <= 0; + s_wvalid <= 0; + s_bready <= 0; end end /** AW **/ - `W_ADDR:begin - - if(s_awvalid&&s_awready) - begin - w_state<=`W_DATA; - s_awaddr<=0; - s_awsize<=0; - - s_awvalid<=0; - s_wvalid<=1; - s_bready<=1; - s_wdata<=data_cpu_data_i; - end - else - begin - w_state<=w_state; - s_awaddr<=s_awaddr; - s_awsize<=s_awsize; - - s_awvalid<=s_awvalid; - s_wvalid<=s_wvalid; - s_bready<=s_bready; - s_wdata<=0; + `W_ADDR: begin + + if (s_awvalid && s_awready) begin + w_state <= `W_DATA; + s_awaddr <= 0; + s_awsize <= 0; + + s_awvalid <= 0; + s_wvalid <= 1; + s_bready <= 1; + s_wdata <= data_cpu_data_i; + end else begin + w_state <= w_state; + s_awaddr <= s_awaddr; + s_awsize <= s_awsize; + + s_awvalid <= s_awvalid; + s_wvalid <= s_wvalid; + s_bready <= s_bready; + s_wdata <= 0; end end /** W **/ - `W_DATA:begin - - if(s_wvalid&&s_wready) - begin - w_state<=`W_RESP; - s_wdata<=0; - end - else - begin - w_state<=w_state; - s_wdata<=s_wdata; + `W_DATA: begin + + if (s_wvalid && s_wready) begin + w_state <= `W_RESP; + s_wdata <= 0; + end else begin + w_state <= w_state; + s_wdata <= s_wdata; end //set wvalid - if(s_wvalid&&s_wready) - begin - s_wvalid<=0; - end - else if(~s_wvalid) - begin - s_wvalid<=1; - end - else - begin - s_wvalid<=s_wvalid; + if (s_wvalid && s_wready) begin + s_wvalid <= 0; + end else if (~s_wvalid) begin + s_wvalid <= 1; + end else begin + s_wvalid <= s_wvalid; end end /** B **/ - `W_RESP:begin - - if(s_bvalid&&s_bready) - begin - w_state<=`W_FREE; - s_bready<=0; - end - else - begin - w_state<=w_state; - s_bready<=s_bready; + `W_RESP: begin + + if (s_bvalid && s_bready) begin + w_state <= `W_FREE; + s_bready <= 0; + end else begin + w_state <= w_state; + s_bready <= s_bready; end end - default: - begin - + default: begin + end endcase @@ -753,22 +659,22 @@ module axi_Master ( //set default //aw - assign s_awid=1; - assign s_awlen=0; - assign s_awburst=`INCR; - assign s_awlock=0; - assign s_awcache=0; - assign s_awprot=0; - assign s_wid=0; - assign s_wstrb={4{data_cpu_we_i}}&data_cpu_sel_i; - assign s_wlast=1; - - + assign s_awid = 1; + assign s_awlen = 0; + assign s_awburst = `INCR; + assign s_awlock = 0; + assign s_awcache = 0; + assign s_awprot = 0; + assign s_wid = 0; + assign s_wstrb = {4{data_cpu_we_i}} & data_cpu_sel_i; + assign s_wlast = 1; + + //set axi signal - assign s_arid=inst_s_arid|data_s_arid; - assign s_araddr=inst_s_araddr|data_s_araddr; - assign s_arsize=inst_s_arsize|data_s_arsize; - assign s_arvalid=inst_s_arvalid|data_s_arvalid; - assign s_rready=inst_s_rready|data_s_rready; + assign s_arid = inst_s_arid | data_s_arid; + assign s_araddr = inst_s_araddr | data_s_araddr; + assign s_arsize = inst_s_arsize | data_s_arsize; + assign s_arvalid = inst_s_arvalid | data_s_arvalid; + assign s_rready = inst_s_rready | data_s_rready; -endmodule \ No newline at end of file +endmodule From 99993f9b2347c5983c66882f48e650ff4ebecc03 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Sat, 7 May 2022 15:45:28 +0800 Subject: [PATCH 081/114] refactor: remove id_old & id_bak --- src/vsrc/pipeline/1_decode/id_bak.sv | 928 --------------------------- src/vsrc/pipeline/1_decode/id_old.sv | 316 --------- 2 files changed, 1244 deletions(-) delete mode 100644 src/vsrc/pipeline/1_decode/id_bak.sv delete mode 100644 src/vsrc/pipeline/1_decode/id_old.sv diff --git a/src/vsrc/pipeline/1_decode/id_bak.sv b/src/vsrc/pipeline/1_decode/id_bak.sv deleted file mode 100644 index e42f483..0000000 --- a/src/vsrc/pipeline/1_decode/id_bak.sv +++ /dev/null @@ -1,928 +0,0 @@ -`timescale 1ns / 1ns - -`include "defines.sv" -`include "instr_info.sv" -`include "csr_defines.sv" - - - -module id ( - input logic rst, - - // <- Instruction Buffer - input instr_buffer_info_t instr_buffer_i, - - - input logic excp_i, - input logic [3:0] excp_num_i, - - // <- Regfile - input logic [`RegBus] reg1_data_i, - input logic [`RegBus] reg2_data_i, - - input instr_buffer_info_t instr_buffer_i_other, - - // <- EXE - input logic ex_wreg_i_1, - input logic [`RegAddrBus] ex_waddr_i_1, - input logic [`RegBus] ex_wdata_i_1, - input logic [`AluOpBus] ex_aluop_i_1, - - - // <- ANOTHER_EXE - input logic ex_wreg_i_2, - input logic [`RegAddrBus] ex_waddr_i_2, - input logic [`RegBus] ex_wdata_i_2, - input logic [`AluOpBus] ex_aluop_i_2, - - // <- Mem - input logic mem_wreg_i_1, - input logic [`RegAddrBus] mem_waddr_i_1, - input logic [`RegBus] mem_wdata_i_1, - - // <- ANOTHER_Mem - input logic mem_wreg_i_2, - input logic [`RegAddrBus] mem_waddr_i_2, - input logic [`RegBus] mem_wdata_i_2, - - // -> Regfile - output reg reg1_read_o, - output reg reg2_read_o, - - // -> EXE - output reg [`RegAddrBus] reg1_addr_o, - output reg [`RegAddrBus] reg2_addr_o, - output reg [`AluOpBus] aluop_o, - output reg [`AluSelBus] alusel_o, - output reg [`RegBus] reg1_o, - output reg [`RegBus] reg2_o, - output reg [`RegAddrBus] reg_waddr_o, - output reg wreg_o, - output reg inst_valid, - output reg [`InstAddrBus] inst_pc, - output logic [`RegBus] inst_o, - output logic [`RegBus] current_inst_address_o, - output reg csr_we, - output csr_write_signal csr_signal_o, - output logic excp_o, - output logic [8:0] excp_num_o, - - // <- CSR - input logic has_int, - input logic [`RegBus] csr_data_i, - input logic [1:0] csr_plv, - - // -> CSR - output reg [13:0] csr_read_addr_o, - - // -> PC - output reg branch_flag_o, - output reg [`RegBus] branch_target_address_o, - output reg [`RegBus] link_addr_o, - output reg [`InstAddrBus] idle_pc, - - // ->Ctrl - output logic stallreq, - output reg idle_stallreq -); - - logic [`InstAddrBus] pc_i; - assign pc_i = instr_buffer_i.valid ? instr_buffer_i.pc : `ZeroWord; - logic [`InstBus] inst_i; - assign inst_i = instr_buffer_i.valid ? instr_buffer_i.instr : `ZeroWord; - - - logic [ 5:0] opcode_6 = inst_i[31:26]; - logic [ 6:0] opcode_7 = inst_i[31:25]; - logic [ 7:0] opcode_8 = inst_i[31:24]; - logic [ 9:0] opcode_10 = inst_i[31:22]; - logic [13:0] opcode_14 = inst_i[31:18]; - logic [16:0] opcode_17 = inst_i[31:15]; - logic [21:0] opcode_22 = inst_i[31:10]; - logic [ 4:0] imm_5 = inst_i[14:10]; - logic [ 9:0] imm_10 = inst_i[9:0]; - logic [13:0] imm_14 = inst_i[23:10]; - logic [15:0] imm_16 = inst_i[25:10]; - logic [11:0] imm_12 = inst_i[21:10]; - logic [19:0] imm_20 = inst_i[24:5]; - logic [ 4:0] op1; - assign op1 = inst_i[4:0]; - logic [4:0] op2 = inst_i[9:5]; - logic [4:0] op3 = inst_i[14:10]; - logic [4:0] op4 = inst_i[19:15]; - - logic [5:0] opcode_1 = inst_i[31:26]; - logic [5:0] opcode_2 = inst_i[25:20]; - logic [4:0] opcode_3 = inst_i[19:15]; - logic [4:0] opcode_4 = inst_i[14:10]; - - logic [`RegBus] pc_plus_4; - - assign pc_plus_4 = pc_i + 4; - assign inst_o = inst_i; - - reg [`RegBus] imm; - - reg stallreq_for_reg1_loadrelate; - reg stallreq_for_reg2_loadrelate; - logic pre_inst_is_load; - - - logic res_from_csr; - logic excp_ine; - logic excp_ipe; - - assign pre_inst_is_load = (((ex_aluop_i_1 == `EXE_LD_B_OP) || - (ex_aluop_i_1 == `EXE_LD_H_OP) || - (ex_aluop_i_1 == `EXE_LD_W_OP) || - (ex_aluop_i_1 == `EXE_LD_BU_OP) || - (ex_aluop_i_1 == `EXE_LD_HU_OP) || - (ex_aluop_i_1 == `EXE_ST_B_OP) || - (ex_aluop_i_1 == `EXE_ST_H_OP) || - (ex_aluop_i_1 == `EXE_ST_W_OP))||( - (ex_aluop_i_2 == `EXE_LD_B_OP) || - (ex_aluop_i_2 == `EXE_LD_H_OP) || - (ex_aluop_i_2 == `EXE_LD_W_OP) || - (ex_aluop_i_2 == `EXE_LD_BU_OP) || - (ex_aluop_i_2 == `EXE_LD_HU_OP) || - (ex_aluop_i_2 == `EXE_ST_B_OP) || - (ex_aluop_i_2 == `EXE_ST_H_OP) || - (ex_aluop_i_2 == `EXE_ST_W_OP)) && (pc_i == instr_buffer_i_other.pc + 4)) ? 1'b1 : 1'b0; - - reg inst_syscall; - reg inst_break; - reg kernel_inst; - - - - assign current_inst_address_o = pc_i; - - - assign excp_ine = (inst_valid == `InstInvalid) && instr_buffer_i.valid; - assign excp_ipe = kernel_inst && (csr_plv == 2'b11); - - assign excp_o = excp_ipe | inst_syscall | inst_break | excp_i | excp_ine | has_int; - assign excp_num_o = {excp_ipe, excp_ine, inst_break, inst_syscall, excp_num_i, has_int}; - - - always @(*) begin - if (rst == `RstEnable) stallreq_for_reg1_loadrelate = `NoStop; - else if (pre_inst_is_load == 1'b1 && ex_waddr_i_1 == reg1_addr_o && reg1_read_o == 1'b1) - stallreq_for_reg1_loadrelate = `Stop; - end - - always @(*) begin - - if (rst == `RstEnable) stallreq_for_reg2_loadrelate = `NoStop; - else if (pre_inst_is_load == 1'b1 && ex_waddr_i_1 == reg2_addr_o && reg2_read_o == 1'b1) - stallreq_for_reg2_loadrelate = `Stop; - end - - //如果这条指令与另一条相邻且存在依赖就直接暂停 - assign stallreq = stallreq_for_reg1_loadrelate | stallreq_for_reg2_loadrelate; - - always @(*) begin - inst_pc = pc_i; - end - - always @(*) begin - if (rst == `RstEnable) begin - aluop_o = `EXE_NOP_OP; - alusel_o = `EXE_RES_NOP; - reg_waddr_o = `NOPRegAddr; - wreg_o = `WriteDisable; - inst_valid = `InstInvalid; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - reg1_addr_o = `NOPRegAddr; - reg2_addr_o = `NOPRegAddr; - imm = 32'h0; - branch_flag_o = `NotBranch; - branch_target_address_o = `ZeroWord; - link_addr_o = `ZeroWord; - inst_break = `False_v; - inst_syscall = `False_v; - idle_stallreq = 1'b0; - end else begin - aluop_o = `EXE_NOP_OP; - alusel_o = `EXE_RES_NOP; - reg_waddr_o = op1; - wreg_o = `WriteDisable; - inst_valid = `InstInvalid; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - reg1_addr_o = op2; - reg2_addr_o = op3; - imm = `ZeroWord; - branch_flag_o = `NotBranch; - branch_target_address_o = `ZeroWord; - link_addr_o = `ZeroWord; - idle_stallreq = 1'b0; - case (opcode_1) - `EXE_JIRL: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_JIRL_OP; - alusel_o = `EXE_RES_JUMP; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - link_addr_o = pc_plus_4; - branch_flag_o = `Branch; - branch_target_address_o = reg1_o + {{14{imm_16[15]}}, imm_16, 2'b0}; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_B: begin - wreg_o = `WriteDisable; - aluop_o = `EXE_B_OP; - alusel_o = `EXE_RES_JUMP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - branch_flag_o = `Branch; - branch_target_address_o = pc_i + {{4{imm_10[9]}}, imm_10, imm_16, 2'b0}; - inst_valid = `InstValid; - end - `EXE_BL: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_BL_OP; - alusel_o = `EXE_RES_JUMP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - branch_flag_o = `Branch; - link_addr_o = pc_plus_4; - branch_target_address_o = pc_i + {{4{imm_10[9]}}, imm_10, imm_16, 2'b0}; - reg_waddr_o = 5'b1; - inst_valid = `InstValid; - end - `EXE_BEQ: begin - wreg_o = `WriteDisable; - aluop_o = `EXE_BEQ_OP; - alusel_o = `EXE_RES_JUMP; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg1_addr_o = op2; - reg2_addr_o = op1; - if (reg1_o == reg2_o) begin - branch_flag_o = `Branch; - branch_target_address_o = pc_i + {{14{imm_16[15]}}, imm_16, 2'b0}; - end - inst_valid = `InstValid; - end - `EXE_BNE: begin - wreg_o = `WriteDisable; - aluop_o = `EXE_BNE_OP; - alusel_o = `EXE_RES_JUMP; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg1_addr_o = op2; - reg2_addr_o = op1; - if (reg1_o != reg2_o) begin - branch_flag_o = `Branch; - branch_target_address_o = pc_i + {{14{imm_16[15]}}, imm_16, 2'b0}; - end - inst_valid = `InstValid; - end - `EXE_BLT: begin - wreg_o = `WriteDisable; - aluop_o = `EXE_BLT_OP; - alusel_o = `EXE_RES_JUMP; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg1_addr_o = op2; - reg2_addr_o = op1; - if ({~reg1_o[31], reg1_o[30:0]} < {~reg2_o[31], reg2_o[30:0]}) begin - branch_flag_o = `Branch; - branch_target_address_o = pc_i + {{14{imm_16[15]}}, imm_16, 2'b0}; - end - inst_valid = `InstValid; - end - `EXE_BGE: begin - wreg_o = `WriteDisable; - aluop_o = `EXE_BGE_OP; - alusel_o = `EXE_RES_JUMP; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg1_addr_o = op2; - reg2_addr_o = op1; - if ({~reg1_o[31], reg1_o[30:0]} >= {~reg2_o[31], reg2_o[30:0]}) begin - branch_flag_o = `Branch; - branch_target_address_o = pc_i + {{14{imm_16[15]}}, imm_16, 2'b0}; - end - inst_valid = `InstValid; - end - `EXE_BLTU: begin - wreg_o = `WriteDisable; - aluop_o = `EXE_BLTU_OP; - alusel_o = `EXE_RES_JUMP; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg1_addr_o = op2; - reg2_addr_o = op1; - if (reg1_o < reg2_o) begin - branch_flag_o = `Branch; - branch_target_address_o = pc_i + {{14{imm_16[15]}}, imm_16, 2'b0}; - end - inst_valid = `InstValid; - end - `EXE_BGEU: begin - wreg_o = `WriteDisable; - aluop_o = `EXE_BGEU_OP; - alusel_o = `EXE_RES_JUMP; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg1_addr_o = op2; - reg2_addr_o = op1; - if (reg1_o >= reg2_o) begin - branch_flag_o = `Branch; - branch_target_address_o = pc_i + {{14{imm_16[15]}}, imm_16, 2'b0}; - end - inst_valid = `InstValid; - end - `EXE_LU12I_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_LUI_OP; - alusel_o = `EXE_RES_MOVE; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - imm = {imm_20, 12'b0}; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_PCADDU12I: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_PCADD_OP; - alusel_o = `EXE_RES_MOVE; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - imm = {imm_20, 12'b0}; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_ATOMIC_MEM: begin - casez (opcode_2) - `EXE_LL_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_LL_OP; - alusel_o = `EXE_RES_LOAD_STORE; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_SC_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SC_OP; - alusel_o = `EXE_RES_LOAD_STORE; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg2_addr_o = op1; - inst_valid = `InstValid; - end - default: begin - end - endcase - end - `EXE_MEM_RELATED: begin - casez (opcode_2) - `EXE_LD_B: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_LD_B_OP; - alusel_o = `EXE_RES_LOAD_STORE; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_LD_H: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_LD_H_OP; - alusel_o = `EXE_RES_LOAD_STORE; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_LD_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_LD_W_OP; - alusel_o = `EXE_RES_LOAD_STORE; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_ST_B: begin - wreg_o = `WriteDisable; - aluop_o = `EXE_ST_B_OP; - alusel_o = `EXE_RES_LOAD_STORE; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg2_addr_o = op1; - inst_valid = `InstValid; - end - `EXE_ST_H: begin - wreg_o = `WriteDisable; - aluop_o = `EXE_ST_H_OP; - alusel_o = `EXE_RES_LOAD_STORE; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg2_addr_o = op1; - inst_valid = `InstValid; - end - `EXE_ST_W: begin - wreg_o = `WriteDisable; - aluop_o = `EXE_ST_W_OP; - alusel_o = `EXE_RES_LOAD_STORE; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg2_addr_o = op1; - inst_valid = `InstValid; - end - `EXE_LD_BU: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_LD_BU_OP; - alusel_o = `EXE_RES_LOAD_STORE; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_LD_HU: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_LD_HU_OP; - alusel_o = `EXE_RES_LOAD_STORE; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - default: begin - end - endcase - end - - `EXE_SPECIAL: begin - case (opcode_2) - `EXE_CSR_RELATED: begin - case (op2) - `EXE_CSRRD: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_CSRRD_OP; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - imm = {18'b0, imm_14}; - csr_signal_o.we = 1'b1; - csr_signal_o.addr = imm_14; - csr_signal_o.data = `ZeroWord; - reg_waddr_o = op1; - inst_valid = `InstValid; - res_from_csr = 1'b1; - kernel_inst = 1'b1; - end - `EXE_CSRWR: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_CSRWR_OP; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - imm = {18'b0, imm_14}; - csr_signal_o.we = 1'b1; - csr_signal_o.addr = imm_14; - csr_signal_o.data = reg1_data_i; - reg1_addr_o = op1; - reg_waddr_o = op1; - inst_valid = `InstValid; - res_from_csr = 1'b1; - kernel_inst = 1'b1; - end - default: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_CSRXCHG_OP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - imm = {18'b0, imm_14}; - csr_signal_o.we = 1'b1; - csr_signal_o.addr = imm_14; - csr_signal_o.data = reg1_data_i; - reg_waddr_o = op1; - inst_valid = `InstValid; - res_from_csr = 1'b1; - kernel_inst = 1'b1; - end - endcase - end - `EXE_OTHER: begin - case (opcode_3) - `EXE_TLB_RELATED: begin - case (opcode_22) - `EXE_TLBFILL: begin - wreg_o = `WriteDisable; - aluop_o = `EXE_TLBFILL_OP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - inst_valid = `InstValid; - kernel_inst = 1'b1; - end - `EXE_TLBRD: begin - wreg_o = `WriteDisable; - aluop_o = `EXE_TLBRD_OP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - inst_valid = `InstValid; - kernel_inst = 1'b1; - end - `EXE_TLBSRCH: begin - wreg_o = `WriteDisable; - aluop_o = `EXE_TLBSRCH_OP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - inst_valid = `InstValid; - kernel_inst = 1'b1; - end - `EXE_TLBWR: begin - wreg_o = `WriteDisable; - aluop_o = `EXE_TLBWR_OP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - inst_valid = `InstValid; - kernel_inst = 1'b1; - end - `EXE_ERTN: begin - wreg_o = `WriteDisable; - aluop_o = `EXE_ERTN_OP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - inst_valid = `InstValid; - kernel_inst = 1'b1; - end - default: begin - end - endcase - end - default: begin - case (opcode_17) - `EXE_IDLE: begin - wreg_o = `WriteDisable; - aluop_o = `EXE_IDLE_OP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - idle_stallreq = 1; - idle_pc = pc_i + 32'h4; - inst_valid = `InstValid; - kernel_inst = 1'b1; - end - `EXE_INVTLB: begin - wreg_o = `WriteDisable; - aluop_o = `EXE_INVTLB_OP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - inst_valid = `InstValid; - kernel_inst = 1'b1; - end - default: begin - end - endcase - end - endcase - end - default: begin - end - endcase - end - - `EXE_ARITHMETIC: begin - casez (opcode_2) - `EXE_SLTI: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SLT_OP; - alusel_o = `EXE_RES_ARITH; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - imm = {{20{imm_12[11]}}, imm_12}; // Signed Extension - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_SLTUI: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SLTU_OP; - alusel_o = `EXE_RES_ARITH; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - imm = {{20{imm_12[11]}}, imm_12}; // Signed Extension - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_ADDI_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_ADD_OP; - alusel_o = `EXE_RES_ARITH; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - imm = {{20{imm_12[11]}}, imm_12}; // Signed Extension - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_ANDI: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_AND_OP; - alusel_o = `EXE_RES_LOGIC; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - imm = {20'h0, imm_12}; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_ORI: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_OR_OP; - alusel_o = `EXE_RES_LOGIC; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - imm = {20'h0, imm_12}; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_XORI: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_XOR_OP; - alusel_o = `EXE_RES_LOGIC; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - imm = {20'h0, imm_12}; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_LONG_ARITH: begin - case (opcode_3) - `EXE_ADD_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_ADD_OP; - alusel_o = `EXE_RES_ARITH; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_SUB_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SUB_OP; - alusel_o = `EXE_RES_ARITH; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_SLT: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SLT_OP; - alusel_o = `EXE_RES_ARITH; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_SLTU: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SLTU_OP; - alusel_o = `EXE_RES_ARITH; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_NOR: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_NOR_OP; - alusel_o = `EXE_RES_LOGIC; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_AND: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_AND_OP; - alusel_o = `EXE_RES_LOGIC; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_OR: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_OR_OP; - alusel_o = `EXE_RES_LOGIC; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_XOR: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_XOR_OP; - alusel_o = `EXE_RES_LOGIC; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_SLL_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SLL_OP; - alusel_o = `EXE_RES_SHIFT; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_SRL_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SRL_OP; - alusel_o = `EXE_RES_SHIFT; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_SRA_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SRA_OP; - alusel_o = `EXE_RES_SHIFT; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_MUL_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_MUL_OP; - alusel_o = `EXE_RES_ARITH; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_MULH_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_MULH_OP; - alusel_o = `EXE_RES_ARITH; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_MULH_WU: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_MULHU_OP; - alusel_o = `EXE_RES_ARITH; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - default: begin - end - - endcase - end - `EXE_DIV_ARITH: begin - casez (opcode_3) - `EXE_DIV_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_DIV_OP; - alusel_o = `EXE_RES_ARITH; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_MOD_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_MOD_OP; - alusel_o = `EXE_RES_ARITH; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_DIV_WU: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_DIV_OP; - alusel_o = `EXE_RES_ARITH; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_MOD_WU: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_MOD_OP; - alusel_o = `EXE_RES_ARITH; - reg1_read_o = 1'b1; - reg2_read_o = 1'b1; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_BREAK: begin - wreg_o = `WriteDisable; - aluop_o = `EXE_BREAK_OP; - alusel_o = `EXE_RES_NOP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - inst_valid = `InstValid; - inst_break = `True_v; - end - `EXE_SYSCALL: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SYSCALL_OP; - alusel_o = `EXE_RES_NOP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - inst_valid = `InstValid; - inst_syscall = `True_v; - end - default: begin - end - endcase - end - `EXE_SHIFT_ARITH: begin - casez (opcode_3) - `EXE_SLLI_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SLL_OP; - alusel_o = `EXE_RES_SHIFT; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - imm = {27'b0, imm_5}; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_SRLI_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SRL_OP; - alusel_o = `EXE_RES_SHIFT; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - imm = {27'b0, imm_5}; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - `EXE_SRAI_W: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_SRA_OP; - alusel_o = `EXE_RES_SHIFT; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - imm = {27'b0, imm_5}; - reg_waddr_o = op1; - inst_valid = `InstValid; - end - default: begin - end - endcase - end - default: begin - - end - endcase - end - default: begin - end - endcase - end - end - - always @(*) begin - if (rst == `RstEnable) reg1_o = `ZeroWord; - else if (opcode_2[5:4] == 2'b00) - reg1_o = csr_data_i; // EXE_CSR_RELATED, TODO: replace magic number - else if ((reg1_read_o == 1'b1) && (reg1_addr_o == 0)) reg1_o = `ZeroWord; - else if ((reg1_read_o == 1'b1) && (ex_wreg_i_2 == 1'b1) && (ex_waddr_i_2 == reg1_addr_o)) - reg1_o = ex_wdata_i_2; - else if ((reg1_read_o == 1'b1) && (mem_wreg_i_2 == 1'b1) && (mem_waddr_i_2 == reg1_addr_o)) - reg1_o = mem_wdata_i_2; - else if ((reg1_read_o == 1'b1) && (ex_wreg_i_1 == 1'b1) && (ex_waddr_i_1 == reg1_addr_o)) - reg1_o = ex_wdata_i_1; - else if ((reg1_read_o == 1'b1) && (mem_wreg_i_1 == 1'b1) && (mem_waddr_i_1 == reg1_addr_o)) - reg1_o = mem_wdata_i_1; - else if (reg1_read_o == 1'b1) reg1_o = reg1_data_i; - else if (reg1_read_o == 1'b0) reg1_o = imm; - else reg1_o = `ZeroWord; - end - - always @(*) begin - if (rst == `RstEnable) reg2_o = `ZeroWord; - else if (opcode_2[5:4] == 2'b00) reg2_o = `ZeroWord; - else if ((reg2_read_o == 1'b1) && (reg2_addr_o == 0)) reg2_o = `ZeroWord; - else if ((reg2_read_o == 1'b1) && (ex_wreg_i_2 == 1'b1) && (ex_waddr_i_2 == reg2_addr_o)) - reg2_o = ex_wdata_i_2; - else if ((reg2_read_o == 1'b1) && (mem_wreg_i_2 == 1'b1) && (mem_waddr_i_2 == reg2_addr_o)) - reg2_o = mem_wdata_i_2; - else if ((reg2_read_o == 1'b1) && (ex_wreg_i_1 == 1'b1) && (ex_waddr_i_1 == reg2_addr_o)) - reg2_o = ex_wdata_i_1; - else if ((reg2_read_o == 1'b1) && (mem_wreg_i_1 == 1'b1) && (mem_waddr_i_1 == reg2_addr_o)) - reg2_o = mem_wdata_i_1; - else if (reg2_read_o == 1'b1) reg2_o = reg2_data_i; - else if (reg2_read_o == 1'b0) reg2_o = imm; - else reg2_o = `ZeroWord; - end - -endmodule diff --git a/src/vsrc/pipeline/1_decode/id_old.sv b/src/vsrc/pipeline/1_decode/id_old.sv deleted file mode 100644 index 5c58ee9..0000000 --- a/src/vsrc/pipeline/1_decode/id_old.sv +++ /dev/null @@ -1,316 +0,0 @@ -`timescale 1ns / 1ns - -`include "defines.sv" -`include "instr_info.sv" -`include "csr_defines.sv" - - - -module id ( - input logic rst, - - // <- Instruction Buffer - input instr_buffer_info_t instr_buffer_i, - - - input logic excp_i, - input logic [3:0] excp_num_i, - - // <- Regfile - input logic [`RegBus] reg1_data_i, - input logic [`RegBus] reg2_data_i, - - input instr_buffer_info_t instr_buffer_i_other, - - // <- EXE - input logic ex_wreg_i_1, - input logic [`RegAddrBus] ex_waddr_i_1, - input logic [`RegBus] ex_wdata_i_1, - input logic [`AluOpBus] ex_aluop_i_1, - - - // <- ANOTHER_EXE - input logic ex_wreg_i_2, - input logic [`RegAddrBus] ex_waddr_i_2, - input logic [`RegBus] ex_wdata_i_2, - input logic [`AluOpBus] ex_aluop_i_2, - - // <- Mem - input logic mem_wreg_i_1, - input logic [`RegAddrBus] mem_waddr_i_1, - input logic [`RegBus] mem_wdata_i_1, - - // <- ANOTHER_Mem - input logic mem_wreg_i_2, - input logic [`RegAddrBus] mem_waddr_i_2, - input logic [`RegBus] mem_wdata_i_2, - - // -> Regfile - output reg reg1_read_o, - output reg reg2_read_o, - - // -> EXE - output reg [`RegAddrBus] reg1_addr_o, - output reg [`RegAddrBus] reg2_addr_o, - output reg [`AluOpBus] aluop_o, - output reg [`AluSelBus] alusel_o, - output reg [`RegBus] reg1_o, - output reg [`RegBus] reg2_o, - output reg [`RegAddrBus] reg_waddr_o, - output reg wreg_o, - output reg inst_valid, - output reg [`InstAddrBus] inst_pc, - output logic [`RegBus] inst_o, - output logic [`RegBus] current_inst_address_o, - output reg csr_we, - output csr_write_signal csr_signal_o, - output logic excp_o, - output logic [8:0] excp_num_o, - - // <- CSR - input logic has_int, - input logic [`RegBus] csr_data_i, - input logic [1:0] csr_plv, - - // -> CSR - output reg [13:0] csr_read_addr_o, - - // -> PC - output reg branch_flag_o, - output reg [`RegBus] branch_target_address_o, - output reg [`RegBus] link_addr_o, - output reg [`InstAddrBus] idle_pc, - - // ->Ctrl - output logic stallreq, - output reg idle_stallreq -); - - logic [`InstAddrBus] pc_i; - assign pc_i = instr_buffer_i.valid ? instr_buffer_i.pc : `ZeroWord; - logic [`InstBus] inst_i; - assign inst_i = instr_buffer_i.valid ? instr_buffer_i.instr : `ZeroWord; - - - logic [ 5:0] opcode_6 = inst_i[31:26]; - logic [ 6:0] opcode_7 = inst_i[31:25]; - logic [ 7:0] opcode_8 = inst_i[31:24]; - logic [ 9:0] opcode_10 = inst_i[31:22]; - logic [13:0] opcode_14 = inst_i[31:18]; - logic [16:0] opcode_17 = inst_i[31:15]; - logic [21:0] opcode_22 = inst_i[31:10]; - logic [ 4:0] imm_5 = inst_i[14:10]; - logic [ 9:0] imm_10 = inst_i[9:0]; - logic [13:0] imm_14 = inst_i[23:10]; - logic [15:0] imm_16 = inst_i[25:10]; - logic [11:0] imm_12 = inst_i[21:10]; - logic [19:0] imm_20 = inst_i[24:5]; - logic [ 4:0] op1; - assign op1 = inst_i[4:0]; - logic [4:0] op2 = inst_i[9:5]; - logic [4:0] op3 = inst_i[14:10]; - logic [4:0] op4 = inst_i[19:15]; - - logic [5:0] opcode_1 = inst_i[31:26]; - logic [5:0] opcode_2 = inst_i[25:20]; - logic [4:0] opcode_3 = inst_i[19:15]; - logic [4:0] opcode_4 = inst_i[14:10]; - - logic [`RegBus] pc_plus_4; - - assign pc_plus_4 = pc_i + 4; - assign inst_o = inst_i; - - reg [`RegBus] imm; - - reg stallreq_for_reg1_loadrelate; - reg stallreq_for_reg2_loadrelate; - logic pre_inst_is_load; - - - logic res_from_csr; - logic excp_ine; - logic excp_ipe; - - assign pre_inst_is_load = (((ex_aluop_i_1 == `EXE_LD_B_OP) || - (ex_aluop_i_1 == `EXE_LD_H_OP) || - (ex_aluop_i_1 == `EXE_LD_W_OP) || - (ex_aluop_i_1 == `EXE_LD_BU_OP) || - (ex_aluop_i_1 == `EXE_LD_HU_OP) || - (ex_aluop_i_1 == `EXE_ST_B_OP) || - (ex_aluop_i_1 == `EXE_ST_H_OP) || - (ex_aluop_i_1 == `EXE_ST_W_OP))||( - (ex_aluop_i_2 == `EXE_LD_B_OP) || - (ex_aluop_i_2 == `EXE_LD_H_OP) || - (ex_aluop_i_2 == `EXE_LD_W_OP) || - (ex_aluop_i_2 == `EXE_LD_BU_OP) || - (ex_aluop_i_2 == `EXE_LD_HU_OP) || - (ex_aluop_i_2 == `EXE_ST_B_OP) || - (ex_aluop_i_2 == `EXE_ST_H_OP) || - (ex_aluop_i_2 == `EXE_ST_W_OP)) && (pc_i == instr_buffer_i_other.pc + 4)) ? 1'b1 : 1'b0; - - reg inst_syscall; - reg inst_break; - reg kernel_inst; - - - - assign current_inst_address_o = pc_i; - - - assign excp_ine = (inst_valid == `InstInvalid) && instr_buffer_i.valid; - assign excp_ipe = kernel_inst && (csr_plv == 2'b11); - - assign excp_o = excp_ipe | inst_syscall | inst_break | excp_i | excp_ine | has_int; - assign excp_num_o = {excp_ipe, excp_ine, inst_break, inst_syscall, excp_num_i, has_int}; - - - always @(*) begin - if (rst == `RstEnable) stallreq_for_reg1_loadrelate = `NoStop; - else if (pre_inst_is_load == 1'b1 && ex_waddr_i_1 == reg1_addr_o && reg1_read_o == 1'b1) - stallreq_for_reg1_loadrelate = `Stop; - end - - always @(*) begin - - if (rst == `RstEnable) stallreq_for_reg2_loadrelate = `NoStop; - else if (pre_inst_is_load == 1'b1 && ex_waddr_i_1 == reg2_addr_o && reg2_read_o == 1'b1) - stallreq_for_reg2_loadrelate = `Stop; - end - - //如果这条指令与另一条相邻且存在依赖就直接暂停 - assign stallreq = stallreq_for_reg1_loadrelate | stallreq_for_reg2_loadrelate; - - always @(*) begin - inst_pc = pc_i; - end - - always @(*) begin - if (rst == `RstEnable) begin - aluop_o = `EXE_NOP_OP; - alusel_o = `EXE_RES_NOP; - reg_waddr_o = `NOPRegAddr; - wreg_o = `WriteDisable; - inst_valid = `InstInvalid; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - reg1_addr_o = `NOPRegAddr; - reg2_addr_o = `NOPRegAddr; - imm = 32'h0; - branch_flag_o = `NotBranch; - branch_target_address_o = `ZeroWord; - link_addr_o = `ZeroWord; - inst_break = `False_v; - inst_syscall = `False_v; - idle_stallreq = 1'b0; - end else begin - aluop_o = `EXE_NOP_OP; - alusel_o = `EXE_RES_NOP; - reg_waddr_o = op1; - wreg_o = `WriteDisable; - inst_valid = `InstInvalid; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - reg1_addr_o = op2; - reg2_addr_o = op3; - imm = `ZeroWord; - branch_flag_o = `NotBranch; - branch_target_address_o = `ZeroWord; - link_addr_o = `ZeroWord; - idle_stallreq = 1'b0; - case (opcode_1) - - `EXE_SPECIAL: begin - case (opcode_2) - `EXE_CSR_RELATED: begin - case (op2) - `EXE_CSRRD: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_CSRRD_OP; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - imm = {18'b0, imm_14}; - csr_signal_o.we = 1'b1; - csr_signal_o.addr = imm_14; - csr_signal_o.data = `ZeroWord; - reg_waddr_o = op1; - inst_valid = `InstValid; - res_from_csr = 1'b1; - kernel_inst = 1'b1; - end - `EXE_CSRWR: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_CSRWR_OP; - reg1_read_o = 1'b1; - reg2_read_o = 1'b0; - imm = {18'b0, imm_14}; - csr_signal_o.we = 1'b1; - csr_signal_o.addr = imm_14; - csr_signal_o.data = reg1_data_i; - reg1_addr_o = op1; - reg_waddr_o = op1; - inst_valid = `InstValid; - res_from_csr = 1'b1; - kernel_inst = 1'b1; - end - default: begin - wreg_o = `WriteEnable; - aluop_o = `EXE_CSRXCHG_OP; - reg1_read_o = 1'b0; - reg2_read_o = 1'b0; - imm = {18'b0, imm_14}; - csr_signal_o.we = 1'b1; - csr_signal_o.addr = imm_14; - csr_signal_o.data = reg1_data_i; - reg_waddr_o = op1; - inst_valid = `InstValid; - res_from_csr = 1'b1; - kernel_inst = 1'b1; - end - endcase - end - endcase - end - - default: begin - end - endcase - end - end - - always @(*) begin - if (rst == `RstEnable) reg1_o = `ZeroWord; - else if (opcode_2[5:4] == 2'b00) - reg1_o = csr_data_i; // EXE_CSR_RELATED, TODO: replace magic number - else if ((reg1_read_o == 1'b1) && (reg1_addr_o == 0)) reg1_o = `ZeroWord; - else if ((reg1_read_o == 1'b1) && (ex_wreg_i_2 == 1'b1) && (ex_waddr_i_2 == reg1_addr_o)) - reg1_o = ex_wdata_i_2; - else if ((reg1_read_o == 1'b1) && (mem_wreg_i_2 == 1'b1) && (mem_waddr_i_2 == reg1_addr_o)) - reg1_o = mem_wdata_i_2; - else if ((reg1_read_o == 1'b1) && (ex_wreg_i_1 == 1'b1) && (ex_waddr_i_1 == reg1_addr_o)) - reg1_o = ex_wdata_i_1; - else if ((reg1_read_o == 1'b1) && (mem_wreg_i_1 == 1'b1) && (mem_waddr_i_1 == reg1_addr_o)) - reg1_o = mem_wdata_i_1; - else if (reg1_read_o == 1'b1) reg1_o = reg1_data_i; - else if (reg1_read_o == 1'b0) reg1_o = imm; - else reg1_o = `ZeroWord; - end - - always @(*) begin - if (rst == `RstEnable) reg2_o = `ZeroWord; - else if (opcode_2[5:4] == 2'b00) reg2_o = `ZeroWord; - else if ((reg2_read_o == 1'b1) && (reg2_addr_o == 0)) reg2_o = `ZeroWord; - else if ((reg2_read_o == 1'b1) && (ex_wreg_i_2 == 1'b1) && (ex_waddr_i_2 == reg2_addr_o)) - reg2_o = ex_wdata_i_2; - else if ((reg2_read_o == 1'b1) && (mem_wreg_i_2 == 1'b1) && (mem_waddr_i_2 == reg2_addr_o)) - reg2_o = mem_wdata_i_2; - else if ((reg2_read_o == 1'b1) && (ex_wreg_i_1 == 1'b1) && (ex_waddr_i_1 == reg2_addr_o)) - reg2_o = ex_wdata_i_1; - else if ((reg2_read_o == 1'b1) && (mem_wreg_i_1 == 1'b1) && (mem_waddr_i_1 == reg2_addr_o)) - reg2_o = mem_wdata_i_1; - else if (reg2_read_o == 1'b1) reg2_o = reg2_data_i; - else if (reg2_read_o == 1'b0) reg2_o = imm; - else reg2_o = `ZeroWord; - end - -endmodule From 3293228f3f4cc283f0dc353c78d934b52cc6fcd5 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Sat, 7 May 2022 16:13:26 +0800 Subject: [PATCH 082/114] fix: fix regfile & AXI latch --- src/vsrc/AXI/axi_master.sv | 5 +++++ src/vsrc/cpu_top.sv | 21 +++++++-------------- src/vsrc/regfile.sv | 4 ++-- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/src/vsrc/AXI/axi_master.sv b/src/vsrc/AXI/axi_master.sv index 1342d02..3be8a7d 100644 --- a/src/vsrc/AXI/axi_master.sv +++ b/src/vsrc/AXI/axi_master.sv @@ -162,6 +162,9 @@ module axi_master ( is_fetching_inst = 0; end default: begin + inst_stall_req_r = 0; + inst_cpu_data_o = 0; + is_fetching_inst = 0; end endcase end @@ -552,6 +555,8 @@ module axi_master ( end end default: begin + stall_req_w = 0; + write_wait_enable = 0; end endcase end diff --git a/src/vsrc/cpu_top.sv b/src/vsrc/cpu_top.sv index f07a866..491343f 100644 --- a/src/vsrc/cpu_top.sv +++ b/src/vsrc/cpu_top.sv @@ -99,28 +99,21 @@ module cpu_top ( logic data_axi_we; logic data_axi_ce; - logic [3:0] data_axi_sel; - logic [`RegAddrBus] data_axi_addr; + logic [`InstAddrBus] data_axi_addr; logic [`RegBus] data_axi_data; logic data_axi_busy; logic data_axi_we_1; - logic data_axi_ce_1; - logic [3:0] data_axi_sel_1; - logic [`RegAddrBus] data_axi_addr_1; + logic [`InstAddrBus] data_axi_addr_1; logic [`RegBus] data_axi_data_1; logic data_axi_we_2; - logic data_axi_ce_2; - logic [3:0] data_axi_sel_2; - logic [`RegAddrBus] data_axi_addr_2; + logic [`InstAddrBus] data_axi_addr_2; logic [`RegBus] data_axi_data_2; - assign data_axi_we = data_axi_we_1 | data_axi_we_2; - assign data_axi_ce = data_axi_ce_1 | data_axi_ce_2; - assign data_axi_sel = data_axi_we_1 ? data_axi_sel_1 : data_axi_we_2 ? data_axi_sel_2 : 4'b0; - assign data_axi_addr = data_axi_we_1 ? data_axi_addr_1 : data_axi_we_2 ? data_axi_addr_2 : 5'b0; - assign data_axi_data = data_axi_we_1 ? data_axi_data_1 : data_axi_we_2 ? data_axi_data_2 : 32'b0; + assign data_axi_we = data_axi_we_1 | data_axi_we_2; + assign data_axi_addr = data_axi_we_1 ? data_axi_addr_1 : data_axi_we_2 ? data_axi_addr_2 : 0; + assign data_axi_data = data_axi_we_1 ? data_axi_data_1 : data_axi_we_2 ? data_axi_data_2 : 0; axi_master u_axi_master ( .aclk (aclk), @@ -140,7 +133,7 @@ module cpu_top ( .data_cpu_addr_i(data_axi_addr), .data_cpu_ce_i(data_axi_addr != 0), // FIXME: ce should not be used as valid? .data_cpu_data_i(0), - .data_cpu_we_i(1'b0), + .data_cpu_we_i(1'b0), // FIXME: Write enable .data_cpu_sel_i(4'b1111), .data_stall_i(), .data_flush_i(), diff --git a/src/vsrc/regfile.sv b/src/vsrc/regfile.sv index 8fb2dd8..86d6e1c 100644 --- a/src/vsrc/regfile.sv +++ b/src/vsrc/regfile.sv @@ -16,8 +16,8 @@ module regfile #( // Read signals, all packed input logic [READ_PORTS-1:0] read_valid_i, - input logic [`RegNumLog2*READ_PORTS - 1:0] read_addr_i, - output logic [`RegWidth*READ_PORTS - 1:0] read_data_o + input logic [READ_PORTS-1:0][`RegAddrBus] read_addr_i, + output logic [READ_PORTS-1:0][`RegBus] read_data_o ); // Used in difftest, should named regs, IMPORTANT!! From df8ef37a38452f05444a7ab9e8348c6eab0df403 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Sat, 7 May 2022 16:29:19 +0800 Subject: [PATCH 083/114] docs: add comments in cpu_top --- src/vsrc/cpu_top.sv | 49 ++++++++++++++++++++++------------------ src/vsrc/dummy_icache.sv | 1 - 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/src/vsrc/cpu_top.sv b/src/vsrc/cpu_top.sv index 491343f..cd38c9b 100644 --- a/src/vsrc/cpu_top.sv +++ b/src/vsrc/cpu_top.sv @@ -88,17 +88,14 @@ module cpu_top ( // Global enable signal logic chip_enable; - logic branch_flag_1; - logic branch_flag_2; - logic Instram_branch_flag; - assign Instram_branch_flag = branch_flag_1 | branch_flag_2; - + // ICache <-> AXI Controller logic axi_busy; logic [`RegBus] axi_data; logic [`RegBus] axi_addr; + // MEM <-> AXI Controller + // TODO: replace with DCache logic data_axi_we; - logic data_axi_ce; logic [`InstAddrBus] data_axi_addr; logic [`RegBus] data_axi_data; logic data_axi_busy; @@ -111,6 +108,7 @@ module cpu_top ( logic [`InstAddrBus] data_axi_addr_2; logic [`RegBus] data_axi_data_2; + // 1 is prioritizes assign data_axi_we = data_axi_we_1 | data_axi_we_2; assign data_axi_addr = data_axi_we_1 ? data_axi_addr_1 : data_axi_we_2 ? data_axi_addr_2 : 0; assign data_axi_data = data_axi_we_1 ? data_axi_data_1 : data_axi_we_2 ? data_axi_data_2 : 0; @@ -119,17 +117,19 @@ module cpu_top ( .aclk (aclk), .aresetn(aresetn), + // <-> ICache .inst_cpu_addr_i(axi_addr), .inst_cpu_ce_i(axi_addr != 0), // FIXME: ce should not be used as valid? .inst_cpu_data_i(0), .inst_cpu_we_i(1'b0), .inst_cpu_sel_i(4'b1111), - .inst_stall_i(Instram_branch_flag), - .inst_flush_i(Instram_branch_flag), + .inst_stall_i(), // FIXME: stall & flush + .inst_flush_i(), .inst_cpu_data_o(axi_data), .inst_stallreq(axi_busy), .inst_id(4'b0000), // Read Instruction only, TODO: move this from AXI to cache + // <-> MEM Stage .data_cpu_addr_i(data_axi_addr), .data_cpu_ce_i(data_axi_addr != 0), // FIXME: ce should not be used as valid? .data_cpu_data_i(0), @@ -141,6 +141,7 @@ module cpu_top ( .data_stallreq(data_axi_busy), .data_id(4'b0000), + // External AXI signals .s_arid(arid), .s_araddr(araddr), .s_arlen(arlen), @@ -220,29 +221,31 @@ module cpu_top ( instr_buffer_info_t frontend_ib_instr_info[FETCH_WIDTH]; logic [`RegBus] next_pc; + // Frontend <-> Backend + logic backend_flush; + // All frontend structures frontend u_frontend ( .clk(clk), .rst(rst), // <-> ICache - .icache_read_addr_o (frontend_icache_addr), - .icache_stallreq_i (icache_frontend_stallreq), - .icache_read_valid_i(icache_frontend_valid), - .icache_read_addr_i (icache_frontend_addr), - .icache_read_data_i (icache_frontend_data), + .icache_read_addr_o(frontend_icache_addr), // -> ICache + .icache_stallreq_i(icache_frontend_stallreq), // <- ICache, I$ cannot accept more addr requests + .icache_read_valid_i(icache_frontend_valid), // <- ICache + .icache_read_addr_i(icache_frontend_addr), // <- ICache + .icache_read_data_i(icache_frontend_data), // <- ICache // <-> Backend - .branch_update_info_i(), - .backend_next_pc_i (next_pc), - .backend_flush_i (backend_flush), + .branch_update_info_i(), // branch update signals, <- EXE Stage + .backend_next_pc_i (next_pc), // backend PC, <- pc_gen + .backend_flush_i (backend_flush), // backend flush, usually come with next_pc // <-> Instruction Buffer - .instr_buffer_stallreq_i(ib_frontend_stallreq), - .instr_buffer_o (frontend_ib_instr_info) + .instr_buffer_stallreq_i(ib_frontend_stallreq), // instruction buffer is full + .instr_buffer_o (frontend_ib_instr_info) // -> IB ); - logic backend_flush; instr_buffer_info_t ib_backend_instr_info[2]; // IB -> ID // Instruction Buffer @@ -259,9 +262,9 @@ module cpu_top ( .frontend_stallreq_o(ib_frontend_stallreq), // <-> Backend - .backend_accept_i(2'b11), // 1 means valid - .backend_flush_i(backend_flush), - .backend_instr_o(ib_backend_instr_info) + .backend_accept_i(2'b11), // TODO: connect to dispatch + .backend_flush_i(backend_flush), // Assure output is reset the next cycle + .backend_instr_o(ib_backend_instr_info) // -> ID ); // ID <-> Regfile @@ -459,6 +462,7 @@ module cpu_top ( logic [`RegBus] id_csr_data_i_2; logic disable_cache; + logic branch_flag_1, branch_flag_2; assign backend_flush = excp_flush | ertn_flush | branch_flag_1 | branch_flag_2; @@ -889,6 +893,7 @@ module cpu_top ( .wdata_2(wb_reg_wdata_2), // Read signals + // Registers are read in dispatch stage .read_valid_i(dispatch_regfile_reg_read_valid), .read_addr_i (dispatch_regfile_reg_read_addr), .read_data_o (regfile_dispatch_reg_read_data) diff --git a/src/vsrc/dummy_icache.sv b/src/vsrc/dummy_icache.sv index 0158509..9cc6386 100644 --- a/src/vsrc/dummy_icache.sv +++ b/src/vsrc/dummy_icache.sv @@ -11,7 +11,6 @@ module dummy_icache #( input logic rst, // <-> IF - input logic frontend_flush_i, // All signals are 1 cycle valid // all 0 means invalid input logic [ADDR_WIDTH-1:0] raddr_1_i, From 6a7aa5e4c8307988ce601c543d4fb13440d1c1eb Mon Sep 17 00:00:00 2001 From: Rookie-rookie-rookie <292601787@qq.com> Date: Sat, 7 May 2022 20:00:41 +0800 Subject: [PATCH 084/114] connect data path --- src/vsrc/cpu_top.sv | 472 ++++++++--------------- src/vsrc/pipeline/2_dispatch/dispatch.sv | 1 - src/vsrc/pipeline/3_execution/ex.sv | 53 +-- src/vsrc/pipeline/3_execution/ex_mem.sv | 59 +-- src/vsrc/pipeline/4_mem/mem.sv | 318 +++++++-------- src/vsrc/pipeline/4_mem/mem_wb.sv | 64 ++- src/vsrc/pipeline_defines.sv | 41 +- 7 files changed, 388 insertions(+), 620 deletions(-) diff --git a/src/vsrc/cpu_top.sv b/src/vsrc/cpu_top.sv index f07a866..69a4c66 100644 --- a/src/vsrc/cpu_top.sv +++ b/src/vsrc/cpu_top.sv @@ -100,27 +100,17 @@ module cpu_top ( logic data_axi_we; logic data_axi_ce; logic [3:0] data_axi_sel; - logic [`RegAddrBus] data_axi_addr; + logic [`DataAddrBus] data_axi_addr; logic [`RegBus] data_axi_data; logic data_axi_busy; - logic data_axi_we_1; - logic data_axi_ce_1; - logic [3:0] data_axi_sel_1; - logic [`RegAddrBus] data_axi_addr_1; - logic [`RegBus] data_axi_data_1; + mem_axi_struct mem_axi_signal[2]; - logic data_axi_we_2; - logic data_axi_ce_2; - logic [3:0] data_axi_sel_2; - logic [`RegAddrBus] data_axi_addr_2; - logic [`RegBus] data_axi_data_2; - - assign data_axi_we = data_axi_we_1 | data_axi_we_2; - assign data_axi_ce = data_axi_ce_1 | data_axi_ce_2; - assign data_axi_sel = data_axi_we_1 ? data_axi_sel_1 : data_axi_we_2 ? data_axi_sel_2 : 4'b0; - assign data_axi_addr = data_axi_we_1 ? data_axi_addr_1 : data_axi_we_2 ? data_axi_addr_2 : 5'b0; - assign data_axi_data = data_axi_we_1 ? data_axi_data_1 : data_axi_we_2 ? data_axi_data_2 : 32'b0; + assign data_axi_we = mem_axi_signal[0].we | mem_axi_signal[1].we; + assign data_axi_ce = mem_axi_signal[0].ce | mem_axi_signal[1].ce; + assign data_axi_sel = mem_axi_signal[0].we ? mem_axi_signal[1].sel : mem_axi_signal[1].we ? mem_axi_signal[1].sel : 4'b0; + assign data_axi_addr = mem_axi_signal[0].we ? mem_axi_signal[1].addr : mem_axi_signal[1].we ? mem_axi_signal[1].addr : 32'b0; + assign data_axi_data = mem_axi_signal[0].we ? mem_axi_signal[1].data : mem_axi_signal[1].we ? mem_axi_signal[1].data : 32'b0; axi_master u_axi_master ( .aclk (aclk), @@ -325,7 +315,7 @@ module cpu_top ( .clk (clk), .rst (rst), .stall (), - .flush (), + .flush (flush), .id_i (id_id_dispatch), .dispatch_o(id_dispatch_dispatch) ); @@ -414,11 +404,16 @@ module cpu_top ( logic has_int; logic excp_flush; logic ertn_flush; - logic [31:0] wb_csr_era; - logic [8:0] wb_csr_esubcode; - logic [5:0] wb_csr_ecode; - logic wb_va_error; - logic [31:0] wb_bad_va; + logic [31:0] csr_era_i; + logic [31:0] wb_csr_era[2]; + logic [8:0] csr_esubcode_i; + logic [8:0] wb_csr_esubcode[2]; + logic [5:0] csr_ecode_i; + logic [5:0] wb_csr_ecode[2]; + logic va_error_i; + logic wb_va_error[2]; + logic [31:0] bad_va_i; + logic [31:0] wb_bad_va[2]; logic tlbsrch_en; logic tlbsrch_found; logic [4:0] tlbsrch_index; @@ -454,16 +449,12 @@ module cpu_top ( logic idle_flush; logic [`InstAddrBus] idle_pc; - logic excp_flush_1; - logic ertn_flush_1; - logic excp_flush_2; - logic ertn_flush_2; + logic wb_excp_flush[2]; + logic wb_ertn_flush[2]; - assign excp_flush = excp_flush_1 | excp_flush_2; - assign ertn_flush = ertn_flush_1 | ertn_flush_2; + assign excp_flush = wb_excp_flush[0] | wb_excp_flush[1]; + assign ertn_flush = wb_ertn_flush[0] | wb_ertn_flush[1]; - logic [`RegBus] id_csr_data_i_1; - logic [`RegBus] id_csr_data_i_2; logic disable_cache; @@ -476,11 +467,7 @@ module cpu_top ( ertn_flush ? csr_era : `ZeroWord; - csr_write_signal id_csr_signal_o_1; - csr_write_signal id_csr_signal_o_2; - - csr_write_signal ex_csr_signal_o_1; - csr_write_signal ex_csr_signal_o_2; + ex_mem_struct ex_signal_o[2]; // EXE Stage @@ -490,19 +477,9 @@ module cpu_top ( .rst(rst), .dispatch_i(dispatch_exe[i]), - .excepttype_i(), .csr_vppn(), - .wreg_o(), - .wd_o(), - .wdata_o(), - .inst_valid_o(), - .inst_pc_o(), - .aluop_o(), - .mem_addr_o(), - .reg2_o(), - .excepttype_o(), - .csr_signal_o(), + .ex_o(ex_signal_o[i]), .stallreq(), @@ -539,8 +516,6 @@ module cpu_top ( logic [1:0] mem_excepttype_i_1; logic [`RegBus] mem_current_inst_address_i_1; - csr_write_signal mem_csr_signal_i_1; - csr_write_signal mem_csr_signal_i_2; logic mem_excp_i_1; logic [9:0] mem_excp_num_i_1; @@ -576,76 +551,34 @@ module cpu_top ( logic data_dmw0_en_2; logic data_dmw1_en_2; + ex_mem_struct mem_signal_i[2]; + generate + for(genvar i=0; i<2; i++)begin : ex_mem + ex_mem u_ex_mem( + .clk(clk), + .rst(rst), + .stall(), + .excp_flush(excp_flush), + .ertn_flush(ertn_flush), - mem u_mem_1 ( - .rst(rst), + .ex_o(ex_signal_o[i]), + .mem_i(mem_signal_i[i]), - .inst_pc_i (mem_inst_pc_1), - .wd_i (mem_reg_waddr_i_1), - .wreg_i (mem_wreg_i_1), - .wdata_i (mem_reg_wdata_i_1), - .aluop_i (mem_aluop_i_1), - .mem_addr_i(mem_addr_i_1), - .reg2_i (mem_reg2_i_1), - - .mem_data_i(dram_data_i_1), - - .LLbit_i(LLbit_o_1), - .wb_LLbit_we_i(wb_LLbit_we_i_1), - .wb_LLbit_value_i(wb_LLbit_value_i_1), - - .excepttype_i(mem_excepttype_i_1), - .current_inst_address_i(mem_current_inst_address_i_1), - - .csr_signal_i(mem_csr_signal_i_1), - - .inst_pc_o(wb_inst_pc_1), - .wd_o (mem_reg_waddr_o_1), - .wreg_o (mem_wreg_o_1), - .wdata_o (mem_reg_wdata_o_1), - .aluop_o (mem_aluop_i_1), - - .mem_addr_o(data_axi_addr_1), - .mem_we_o (data_axi_we_1), - .mem_sel_o (data_axi_sel_1), - .mem_data_o(data_axi_data_1), - .mem_ce_o (data_axi_ce_1), - - .LLbit_we_o(mem_LLbit_we_o_1), - .LLbit_value_o(mem_LLbit_value_o_1), - - .excepttype_o(mem_excepttype_o_1), - .current_inst_address_o(mem_current_inst_address_o_1), - - .csr_signal_o(mem_csr_signal_o_1), - - .excp_i(mem_excp_i_1), - .excp_num_i(mem_excp_num_i_1), - .excp_o(mem_excp_o_1), - .excp_num_o(mem_excp_num_o_1), - - .csr_pg(csr_pg), - .csr_da(csr_da), - .csr_dmw0(csr_dmw0), - .csr_dmw1(csr_dmw1), - .csr_plv(csr_plv), - .csr_datf(csr_datf), - .disable_cache(1'b0), - - .data_addr_trans_en(data_addr_trans_en_1), - .dmw0_en(data_dmw0_en_1), - .dmw1_en(data_dmw1_en_1), - .cacop_op_mode_di(cacop_op_mode_di), - - .data_tlb_found(data_tlb_found), - .data_tlb_index(data_tlb_index), - .data_tlb_v(data_tlb_v), - .data_tlb_d(data_tlb_d), - .data_tlb_mat(data_tlb_mat), - .data_tlb_plv(data_tlb_plv) + .flush(flush), + .ex_current_inst_address(), + .excp_i(), + .excp_num_i(), - ); + .mem_current_inst_address(), + .excp_o(), + .excp_num_o() + ); + end + + endgenerate + + mem_wb_struct mem_signal_o[2]; logic LLbit_o_2; logic wb_LLbit_we_i_2; @@ -658,94 +591,62 @@ module cpu_top ( logic [13:0] mem_csr_addr_o_2; logic [31:0] mem_csr_data_o_2; + generate + for(genvar i=0; i<2; i++)begin : mem + mem u_mem( + .rst(), + .signal_i(mem_signal_i[i]), - mem u_mem_2 ( - .rst(rst), + .signal_o(mem_signal_o[i]), - .inst_pc_i (mem_inst_pc_2), - .wd_i (mem_reg_waddr_i_2), - .wreg_i (mem_wreg_i_2), - .wdata_i (mem_reg_wdata_i_2), - .aluop_i (mem_aluop_i_2), - .mem_addr_i(mem_addr_i_2), - .reg2_i (mem_reg2_i_2), - - .mem_data_i(dram_data_i_2), - - .LLbit_i(LLbit_o_2), - .wb_LLbit_we_i(wb_LLbit_we_i_2), - .wb_LLbit_value_i(wb_LLbit_value_i_2), - - .excepttype_i(mem_excepttype_i_2), - .current_inst_address_i(mem_current_inst_address_i_2), - - .csr_signal_i(mem_csr_signal_i_2), - - .inst_pc_o(wb_inst_pc_2), - .wd_o (mem_reg_waddr_o_2), - .wreg_o (mem_wreg_o_2), - .wdata_o (mem_reg_wdata_o_2), - .aluop_o (mem_aluop_o_2), - - .mem_addr_o(data_axi_addr_2), - .mem_we_o (data_axi_we_2), - .mem_sel_o (data_axi_sel_2), - .mem_data_o(data_axi_data_2), - .mem_ce_o (data_axi_ce_2), - - .LLbit_we_o(mem_LLbit_we_o_2), - .LLbit_value_o(mem_LLbit_value_o_2), - - .excepttype_o(mem_excepttype_o_2), - .current_inst_address_o(mem_current_inst_address_o_2), - - .csr_signal_o(mem_csr_signal_o_2), - - .excp_i(mem_excp_i_2), - .excp_num_i(mem_excp_num_i_2), - .excp_o(mem_excp_o_2), - .excp_num_o(mem_excp_num_o_2), - - .csr_pg(csr_pg), - .csr_da(csr_da), - .csr_dmw0(csr_dmw0), - .csr_dmw1(csr_dmw1), - .csr_plv(csr_plv), - .csr_datf(csr_datf), - .disable_cache(1'b0), - - .data_addr_trans_en(data_addr_trans_en_2), - .dmw0_en(data_dmw0_en_2), - .dmw1_en(data_dmw1_en_2), - .cacop_op_mode_di(cacop_op_mode_di), - - .data_tlb_found(data_tlb_found), - .data_tlb_index(data_tlb_index), - .data_tlb_v(data_tlb_v), - .data_tlb_d(data_tlb_d), - .data_tlb_mat(data_tlb_mat), - .data_tlb_plv(data_tlb_plv) + .signal_axi_o(mem_axi_signal[i]), - ); + .mem_data_i(), + + .LLbit_i(), + .wb_LLbit_we_i(), + .wb_LLbit_value_i(), + + .current_inst_address_i(), - assign dram_pc_o_1 = wb_inst_pc_1; - assign dram_pc_o_2 = wb_inst_pc_2; + .excp_i(mem_excp_i_2), + .excp_num_i(mem_excp_num_i_2), + .excp_o(mem_excp_o_2), + .excp_num_o(mem_excp_num_o_2), - logic wb_wreg_1; - logic [`RegAddrBus] wb_reg_waddr_1; - logic [`RegBus] wb_reg_wdata_1; + .csr_pg(csr_pg), + .csr_da(csr_da), + .csr_dmw0(csr_dmw0), + .csr_dmw1(csr_dmw1), + .csr_plv(csr_plv), + .csr_datf(csr_datf), + .disable_cache(1'b0), + + .data_addr_trans_en(data_addr_trans_en_2), + .dmw0_en(data_dmw0_en_2), + .dmw1_en(data_dmw1_en_2), + .cacop_op_mode_di(cacop_op_mode_di), + + .data_tlb_found(data_tlb_found), + .data_tlb_index(data_tlb_index), + .data_tlb_v(data_tlb_v), + .data_tlb_d(data_tlb_d), + .data_tlb_mat(data_tlb_mat), + .data_tlb_plv(data_tlb_plv) + ); + end + + endgenerate logic wb_csr_we_1; logic [13:0] wb_csr_addr_1; logic [`RegBus] wb_csr_data_1; - logic [8:0] wb_csr_esubcode_1; - logic [5:0] wb_csr_ecode_1; - assign debug0_wb_rf_wen = wb_wreg_1; - assign debug0_wb_rf_wnum = wb_reg_waddr_1; - assign debug0_wb_rf_wdata = wb_reg_wdata_1; + assign debug0_wb_rf_wen = wb_reg_signal[0].we; + assign debug0_wb_rf_wnum = wb_reg_signal[0].waddr; + assign debug0_wb_rf_wdata = wb_reg_signal[0].wdata; logic wb_excp_o_1; @@ -756,129 +657,66 @@ module cpu_top ( csr_write_signal wb_csr_signal_o_1; csr_write_signal wb_csr_signal_o_2; - logic wb_va_error_1; - logic [`RegBus] wb_bad_va_1; - logic excp_tlbrefill_1; - logic [18:0] excp_tlb_vppn_1; + + logic [18:0] wb_excp_tlb_vppn[2]; logic [`InstAddrBus] debug_commit_pc_1; - mem_wb mem_wb_1 ( - .clk (clk), - .rst (rst), - .stall(stall1[5]), - .mem_wd (mem_reg_waddr_o_1), - .mem_wreg (mem_wreg_o_1), - .mem_wdata (mem_reg_wdata_o_1), - .mem_inst_pc (mem_inst_pc_1), - .mem_instr (), - .mem_aluop (mem_aluop_o_1), - .mem_inst_valid(mem_inst_valid_1), + logic wb_csr_we_2; + logic [13:0] wb_csr_addr_2; + logic [`RegBus] wb_csr_data_2; - .mem_LLbit_we(mem_LLbit_we_o_1), - .mem_LLbit_value(mem_LLbit_value_o_1), + logic wb_excp_tlbrefill[2]; + wb_reg wb_reg_signal[2]; - .flush(flush), + generate + for(genvar i=0; i<2; i++)begin : mem_wb + mem_wb u_mem_wb( + .clk(clk), + .rst(rst), + .stall(), - .mem_csr_signal_o(mem_csr_signal_o_1), + .mem_signal_o(mem_signal_o[i]), - .wb_wd(wb_reg_waddr_1), - .wb_wreg(wb_wreg_1), - .wb_wdata(wb_reg_wdata_1), + .mem_LLbit_we(), + .mem_LLbit_value(), - .wb_LLbit_we(wb_LLbit_we_i_1), - .wb_LLbit_value(wb_LLbit_value_i_1), + .flush(), + .excp_num(), - .debug_commit_pc (debug_commit_pc_1), - .debug_commit_valid(debug_commit_valid_1), - .debug_commit_instr(debug_commit_instr_1), + .wb_reg_o(wb_reg_signal[i]), - .excp_i(mem_excp_o_1), - .excp_num_i(mem_excp_num_o_1), - .excp_o(wb_excp_o_1), - .excp_num_o(wb_excp_num_o_1), + .wb_csr_signal_o(), - .wb_csr_signal_o(wb_csr_signal_o_1), - .excp_flush(excp_flush_1), - .ertn_flush(ertn_flush_1), - .va_error(wb_va_error_1), - .bad_va(wb_bad_va_1), - .excp_tlbrefill(excp_tlbrefill_1), - .excp_tlb_vppn(excp_tlb_vppn_1) - ); + .debug_commit_pc(), + .debug_commit_valid(), + .debug_commit_instr(), - logic wb_wreg_2; - logic [`RegAddrBus] wb_reg_waddr_2; - logic [`RegBus] wb_reg_wdata_2; + .wb_LLbit_we(), + .wb_LLbit_value(), - logic wb_csr_we_2; - logic [13:0] wb_csr_addr_2; - logic [`RegBus] wb_csr_data_2; + .excp_i(), + .excp_num_i(), + .excp_o(), + .excp_num_o(), + + //to csr + .csr_era(wb_csr_era[i]), + .csr_esubcode(wb_csr_esubcode[i]), + .csr_ecode(wb_csr_ecode[i]), + .excp_flush(wb_excp_flush[i]), + .ertn_flush(wb_ertn_flush[i]), + .va_error(wb_va_error[i]), + .bad_va(wb_bad_va[i]), + .excp_tlbrefill(), + .excp_tlb(), + .excp_tlb_vppn() + ); + end + endgenerate - assign debug_commit_wreg_2 = wb_wreg_2; - assign debug_commit_reg_waddr_2 = wb_reg_waddr_2; - assign debug_commit_reg_wdata_2 = wb_reg_wdata_2; - - logic [`RegBus] wb_csr_era_2; - logic [8:0] wb_csr_esubcode_2; - logic [5:0] wb_csr_ecode_2; - - logic wb_va_error_2; - logic [`RegBus] wb_bad_va_2; - logic excp_tlbrefill_2; - logic [18:0] excp_tlb_vppn_2; - logic wb_csr_era_1; - - mem_wb mem_wb_2 ( - .clk (clk), - .rst (rst), - .stall(stall2[5]), - - .mem_wd (mem_reg_waddr_o_2), - .mem_wreg (mem_wreg_o_2), - .mem_wdata (mem_reg_wdata_o_2), - .mem_inst_pc (mem_inst_pc_2), - .mem_instr (), - .mem_aluop (mem_aluop_o_2), - .mem_inst_valid(mem_inst_valid_2), - - .mem_LLbit_we(mem_LLbit_we_o_2), - .mem_LLbit_value(mem_LLbit_value_o_2), - - .flush(flush), - - .mem_csr_signal_o(mem_csr_signal_o_2), - - .wb_wd(wb_reg_waddr_2), - .wb_wreg(wb_wreg_2), - .wb_wdata(wb_reg_wdata_2), - - .wb_LLbit_we(wb_LLbit_we_i), - .wb_LLbit_value(wb_LLbit_value_2), - - .wb_csr_signal_o(wb_csr_signal_o_2), - - .debug_commit_pc (debug_commit_pc_2), - .debug_commit_valid(debug_commit_valid_2), - .debug_commit_instr(debug_commit_instr_2), - - .excp_i(mem_excp_o_2), - .excp_num_i(mem_excp_num_o_2), - .excp_o(wb_excp_o_2), - .excp_num_o(wb_excp_num_o_2), - - .csr_era(wb_csr_era_2), - .csr_esubcode(wb_csr_esubcode_2), - .csr_ecode(wb_csr_ecode_2), - .excp_flush(excp_flush_2), - .ertn_flush(ertn_flush_2), - .va_error(wb_va_error_2), - .bad_va(wb_bad_va_2), - .excp_tlbrefill(excp_tlbrefill_2), - .excp_tlb_vppn(excp_tlb_vppn_2) - ); regfile #( .READ_PORTS(4) // 2 for each ID, 2 ID in total, TODO: remove magic number @@ -886,14 +724,14 @@ module cpu_top ( .clk(clk), .rst(rst), - .we_1 (wb_wreg_1), + .we_1 (wb_reg_signal[0].we), .pc_i_1 (), - .waddr_1(wb_reg_waddr_1), - .wdata_1(wb_reg_wdata_1), - .we_2 (wb_wreg_2), + .waddr_1(wb_reg_signal[0].waddr), + .wdata_1(wb_reg_signal[0].wdata), + .we_2 (wb_reg_signal[1].we), .pc_i_2 (), - .waddr_2(wb_reg_waddr_2), - .wdata_2(wb_reg_wdata_2), + .waddr_2(wb_reg_signal[1].waddr), + .wdata_2(wb_reg_signal[1].wdata), // Read signals .read_valid_i(dispatch_regfile_reg_read_valid), @@ -930,15 +768,15 @@ module cpu_top ( //目前没有进行冲突处理,是假设不会同时出现两条异常同时发生 - assign wb_csr_era = wb_csr_era_1 | wb_csr_era_2; - assign wb_csr_ecode = wb_csr_ecode_1 | wb_csr_ecode_2; - assign wb_csr_esubcode = wb_csr_esubcode_1 | wb_csr_esubcode_2; - assign excp_flush = excp_flush_1 | excp_flush_2; - assign ertn_flush = ertn_flush_1 | ertn_flush_2; - assign wb_va_error = wb_va_error_1 | wb_va_error_2; - assign wb_bad_va = wb_bad_va_1 | wb_bad_va_2; - assign excp_tlbrefill = excp_tlbrefill_1 | excp_tlbrefill_2; - assign excp_tlb_vppn = excp_tlb_vppn_1 | excp_tlb_vppn_2; + assign csr_era_i = wb_csr_era[0] | wb_csr_era[1]; + assign csr_ecode_i = wb_csr_ecode[0] | wb_csr_ecode[1]; + assign csr_esubcode_i = wb_csr_esubcode[0] | wb_csr_esubcode[1]; + assign excp_flush = wb_excp_flush[0] | wb_excp_flush[1]; + assign ertn_flush = wb_ertn_flush[0] | wb_ertn_flush[1]; + assign va_error_i = wb_va_error[0] | wb_va_error[1]; + assign bad_va_i = wb_bad_va[0] | wb_bad_va[1]; + assign excp_tlbrefill = wb_excp_tlbrefill[0] | wb_excp_tlbrefill[1]; + assign excp_tlb_vppn = wb_excp_tlb_vppn[0] | wb_excp_tlb_vppn[1]; cs_reg u_cs_reg ( .clk(clk), @@ -951,10 +789,10 @@ module cpu_top ( .raddr_2(id_csr_read_addr_o_2), .rdata_1(id_csr_data_1), .rdata_2(id_csr_data_2), - .era_i(wb_csr_era), - .esubcode_i(wb_csr_esubcode), - .va_error_i(wb_va_error), - .bad_va_i(wb_bad_va), + .era_i(csr_era_i), + .esubcode_i(csr_esubcode_i), + .va_error_i(va_error_i), + .bad_va_i(bad_va_i), .tlbsrch_en(tlbsrch_en), .tlbsrch_found(tlbsrch_found), .tlbsrch_index(tlbsrch_index), diff --git a/src/vsrc/pipeline/2_dispatch/dispatch.sv b/src/vsrc/pipeline/2_dispatch/dispatch.sv index 401a597..dfa433c 100644 --- a/src/vsrc/pipeline/2_dispatch/dispatch.sv +++ b/src/vsrc/pipeline/2_dispatch/dispatch.sv @@ -29,7 +29,6 @@ module dispatch #( // Pass through to EXE // TODO: add dispatch logic - exe_o[i].instr_valid <= id_i[i].instr_valid; exe_o[i].instr_info <= id_i[i].instr_info; exe_o[i].aluop <= id_i[i].aluop; exe_o[i].alusel <= id_i[i].alusel; diff --git a/src/vsrc/pipeline/3_execution/ex.sv b/src/vsrc/pipeline/3_execution/ex.sv index 941fc91..d0673ef 100644 --- a/src/vsrc/pipeline/3_execution/ex.sv +++ b/src/vsrc/pipeline/3_execution/ex.sv @@ -1,28 +1,15 @@ -`include "defines.sv" -`include "csr_defines.sv" `include "pipeline_defines.sv" module ex ( input logic rst, - input logic [1:0] excepttype_i, - // <- Dispatch // Information from dispatch input dispatch_ex_struct dispatch_i, input logic [18:0] csr_vppn, - output logic wreg_o, - output logic [`RegAddrBus] wd_o, - output logic [`RegBus] wdata_o, - output reg inst_valid_o, - output reg [`InstAddrBus] inst_pc_o, - output logic [`AluOpBus] aluop_o, - output logic [`RegBus] mem_addr_o, - output logic [`RegBus] reg2_o, - output logic [1:0] excepttype_o, - output csr_write_signal csr_signal_o, + output ex_mem_struct ex_o, output logic stallreq, @@ -51,25 +38,23 @@ module ex ( assign inst_i = dispatch_i.instr_info.instr; assign inst_pc_i = dispatch_i.instr_info.pc; logic inst_valid_i; - assign inst_valid_i = dispatch_i.instr_valid; + assign inst_valid_i = dispatch_i.instr_info.valid; logic wreg_i; logic [`RegAddrBus] wd_i; assign wd_i = dispatch_i.reg_write_addr; assign wreg_i = dispatch_i.reg_write_valid; - assign aluop_o = aluop_i; - assign mem_addr_o = reg1_i + {{20{inst_i[21]}}, inst_i[21:10]}; - assign reg2_o = reg2_i; - - assign excepttype_o = excepttype_i; + assign ex_o.aluop = aluop_i; + assign ex_o.mem_addr = reg1_i + {{20{inst_i[21]}}, inst_i[21:10]}; + assign ex_o.reg2 = reg2_i; csr_write_signal csr_signal_i; assign csr_signal_i = dispatch_i.csr_signal; //写入csr的数据,对csrxchg指令进行掩码处理 - assign csr_signal_o.we = csr_signal_i.we; - assign csr_signal_o.addr = csr_signal_i.addr; - assign csr_signal_o.data = (aluop_i ==`EXE_CSRXCHG_OP) ?((reg1_i & reg2_i) | (~reg1_i & csr_signal_i.data)) : csr_signal_i.data; + assign ex_o.csr_signal.we = csr_signal_i.we; + assign ex_o.csr_signal.addr = csr_signal_i.addr; + assign ex_o.csr_signal.data = (aluop_i ==`EXE_CSRXCHG_OP) ?((reg1_i & reg2_i) | (~reg1_i & csr_signal_i.data)) : csr_signal_i.data; assign excp_o = excp_i || 1'b0; assign excp_num_o = {1'b0, excp_num_i}; @@ -78,8 +63,8 @@ module ex ( if (rst == `RstEnable) begin logicout = `ZeroWord; end else begin - inst_pc_o = inst_pc_i; - inst_valid_o = inst_valid_i; + ex_o.instr_info.pc = inst_pc_i; + ex_o.instr_info.valid = inst_valid_i; case (aluop_i) `EXE_OR_OP: begin logicout = reg1_i | reg2_i; @@ -189,7 +174,7 @@ module ex ( moveout = reg2_i; end `EXE_PCADD_OP: begin - moveout = reg2_i + inst_pc_o; + moveout = reg2_i + ex_o.instr_info.pc; end default: begin end @@ -198,26 +183,26 @@ module ex ( end always @(*) begin - wd_o = wd_i; - wreg_o = wreg_i; + ex_o.waddr = wd_i; + ex_o.wreg = wreg_i; case (alusel_i) `EXE_RES_LOGIC: begin - wdata_o = logicout; + ex_o.wdata = logicout; end `EXE_RES_SHIFT: begin - wdata_o = shiftout; + ex_o.wdata = shiftout; end `EXE_RES_MOVE: begin - wdata_o = moveout; + ex_o.wdata = moveout; end `EXE_RES_ARITH: begin - wdata_o = arithout; + ex_o.wdata = arithout; end `EXE_RES_JUMP: begin - wdata_o = 0; // FIXME: add link addr + ex_o.wdata = 0; // FIXME: add link addr end default: begin - wdata_o = `ZeroWord; + ex_o.wdata = `ZeroWord; end endcase end diff --git a/src/vsrc/pipeline/3_execution/ex_mem.sv b/src/vsrc/pipeline/3_execution/ex_mem.sv index 7a645c4..e6f465d 100644 --- a/src/vsrc/pipeline/3_execution/ex_mem.sv +++ b/src/vsrc/pipeline/3_execution/ex_mem.sv @@ -1,5 +1,4 @@ -`include "defines.sv" -`include "csr_defines.sv" +`include "pipeline_defines.sv" module ex_mem ( input logic clk, @@ -8,79 +7,35 @@ module ex_mem ( input logic excp_flush, input logic ertn_flush, - input logic [`RegAddrBus] ex_wd, - input logic ex_wreg, - input logic [`RegBus] ex_wdata, - input logic ex_inst_valid, - input logic [`InstAddrBus] ex_inst_pc, - input logic [`AluOpBus] ex_aluop, - input logic [`RegBus] ex_mem_addr, - input logic [`RegBus] ex_reg2, + input ex_mem_struct ex_o, + output ex_mem_struct mem_i, + input logic flush, - input logic [1:0] ex_excepttype, input logic [`RegBus] ex_current_inst_address, - input csr_write_signal ex_csr_signal_o, input logic excp_i, input logic [9:0] excp_num_i, - output reg [`RegAddrBus] mem_wd, - output reg mem_wreg, - output reg [`RegBus] mem_wdata, - output reg mem_inst_valid, - output reg [`InstAddrBus] mem_inst_pc, - output reg [`AluOpBus] mem_aluop, - output reg [`RegBus] mem_mem_addr, - output reg [`RegBus] mem_reg2, - output reg [1:0] mem_excepttype, output reg [`RegBus] mem_current_inst_address, - output csr_write_signal mem_csr_signal_i, output reg excp_o, output reg [9:0] excp_num_o ); always @(posedge clk) begin if (rst == `RstEnable) begin - mem_wd <= `NOPRegAddr; - mem_wreg <= `WriteDisable; - mem_wdata <= `ZeroWord; - mem_inst_pc <= `ZeroWord; - mem_inst_valid <= `InstInvalid; - mem_aluop <= `EXE_NOP_OP; - mem_mem_addr <= `ZeroWord; - mem_reg2 <= `ZeroWord; - mem_excepttype <= 2'b00; + mem_i <= 0; mem_current_inst_address <= `ZeroWord; - mem_csr_signal_i <= 47'b0; excp_o <= 1'b0; excp_num_o <= 10'b0; end else if (flush == 1'b1 || excp_flush == 1'b1 || ertn_flush == 1'b1) begin - mem_wd <= `NOPRegAddr; - mem_wreg <= `WriteDisable; - mem_wdata <= `ZeroWord; - mem_inst_pc <= `ZeroWord; - mem_inst_valid <= `InstInvalid; - mem_aluop <= `EXE_NOP_OP; - mem_mem_addr <= `ZeroWord; - mem_reg2 <= `ZeroWord; - mem_excepttype <= 2'b00; + mem_i <= 0; mem_current_inst_address <= `ZeroWord; - mem_csr_signal_i <= 47'b0; excp_o <= 1'b0; excp_num_o <= 10'b0; end else if (stall == `Stop) begin end else begin - mem_wd <= ex_wd; - mem_wreg <= ex_wreg; - mem_wdata <= ex_wdata; - mem_inst_pc <= ex_inst_pc; - mem_inst_valid <= ex_inst_valid; - mem_aluop <= ex_aluop; - mem_mem_addr <= ex_mem_addr; - mem_reg2 <= ex_reg2; - mem_excepttype <= ex_excepttype; + mem_i <= ex_o; mem_current_inst_address <= ex_current_inst_address; - mem_csr_signal_i <= ex_csr_signal_o; excp_o <= excp_i; excp_num_o <= excp_num_i; end diff --git a/src/vsrc/pipeline/4_mem/mem.sv b/src/vsrc/pipeline/4_mem/mem.sv index b63a9db..3f8fe43 100644 --- a/src/vsrc/pipeline/4_mem/mem.sv +++ b/src/vsrc/pipeline/4_mem/mem.sv @@ -1,111 +1,88 @@ `timescale 1ns / 1ns -`include "defines.sv" -`include "csr_defines.sv" +`include "pipeline_defines.sv" module mem ( - input wire rst, + input logic rst, - input wire [`InstAddrBus] inst_pc_i, - input wire [`RegAddrBus] wd_i, - input wire wreg_i, - input wire [`RegBus] wdata_i, - input wire [`AluOpBus] aluop_i, - input wire [`RegBus] mem_addr_i, - input wire [`RegBus] reg2_i, + input ex_mem_struct signal_i, - input wire [`RegBus] mem_data_i, + output mem_wb_struct signal_o, - input wire LLbit_i, - input wire wb_LLbit_we_i, - input wire wb_LLbit_value_i, + output mem_axi_struct signal_axi_o, - input wire [1:0] excepttype_i, - input wire [`RegBus] current_inst_address_i, - input csr_write_signal csr_signal_i, + input logic [`RegBus] mem_data_i, - input wire excp_i, - input wire [9:0] excp_num_i, + input logic LLbit_i, + input logic wb_LLbit_we_i, + input logic wb_LLbit_value_i, + + input logic [`RegBus] current_inst_address_i, + + + input logic excp_i, + input logic [9:0] excp_num_i, //from csr - input wire csr_pg, - input wire csr_da, - input wire [31:0] csr_dmw0, - input wire [31:0] csr_dmw1, - input wire [1:0] csr_plv, - input wire [1:0] csr_datf, - input wire disable_cache, + input logic csr_pg, + input logic csr_da, + input logic [31:0] csr_dmw0, + input logic [31:0] csr_dmw1, + input logic [1:0] csr_plv, + input logic [1:0] csr_datf, + input logic disable_cache, //to addr trans - output wire data_addr_trans_en, - output wire dmw0_en, - output wire dmw1_en, - output wire cacop_op_mode_di, + output logic data_addr_trans_en, + output logic dmw0_en, + output logic dmw1_en, + output logic cacop_op_mode_di, //tlb - input wire data_tlb_found, - input wire [4:0] data_tlb_index, - input wire data_tlb_v, - input wire data_tlb_d, - input wire [1:0] data_tlb_mat, - input wire [1:0] data_tlb_plv, - - output reg [`InstAddrBus] inst_pc_o, - output reg [`RegAddrBus] wd_o, - output reg wreg_o, - output reg [`RegBus] wdata_o, - output reg [`AluOpBus] aluop_o, - - output reg [`RegBus] mem_addr_o, - output wire mem_we_o, - output reg [3:0] mem_sel_o, - output reg [`RegBus] mem_data_o, - output reg mem_ce_o, + input logic data_tlb_found, + input logic [4:0] data_tlb_index, + input logic data_tlb_v, + input logic data_tlb_d, + input logic [1:0] data_tlb_mat, + input logic [1:0] data_tlb_plv, + output reg LLbit_we_o, output reg LLbit_value_o, - output wire [1:0] excepttype_o, - output wire [`RegBus] current_inst_address_o, - - output csr_write_signal csr_signal_o, + output logic [`RegBus] current_inst_address_o, - output wire excp_o, - output wire [15:0] excp_num_o + output logic excp_o, + output logic [15:0] excp_num_o ); - reg mem_we; reg LLbit; - wire access_mem; - wire mem_store_op; - wire mem_load_op; - wire excp_adem; - wire pg_mode; - wire da_mode; - wire excp_tlbr; - wire excp_pil; - wire excp_pis; - wire excp_pme; - wire excp_ppi; + logic access_mem; + logic mem_store_op; + logic mem_load_op; + logic excp_adem; + logic pg_mode; + logic da_mode; + logic excp_tlbr; + logic excp_pil; + logic excp_pis; + logic excp_pme; + logic excp_ppi; assign access_mem = mem_load_op || mem_store_op; - assign mem_load_op = aluop_i == `EXE_LD_B_OP || aluop_i == `EXE_LD_BU_OP || aluop_i == `EXE_LD_H_OP || aluop_i == `EXE_LD_HU_OP || - aluop_i == `EXE_LD_W_OP || aluop_i == `EXE_LL_OP; - - assign mem_store_op = aluop_i == `EXE_ST_B_OP || aluop_i == `EXE_ST_H_OP || aluop_i == `EXE_ST_W_OP || aluop_i == `EXE_SC_OP; + assign mem_load_op = signal_i.aluop == `EXE_LD_B_OP || signal_i.aluop == `EXE_LD_BU_OP || signal_i.aluop == `EXE_LD_H_OP || signal_i.aluop == `EXE_LD_HU_OP || + signal_i.aluop == `EXE_LD_W_OP || signal_i.aluop == `EXE_LL_OP; - assign mem_we_o = mem_we & (~(|excepttype_i)); + assign mem_store_op = signal_i.aluop == `EXE_ST_B_OP || signal_i.aluop == `EXE_ST_H_OP || signal_i.aluop == `EXE_ST_W_OP || signal_i.aluop == `EXE_SC_OP; - assign excepttype_o = excepttype_i; assign current_inst_address_o = current_inst_address_i; - assign csr_signal_o = csr_signal_i; //addr dmw trans - assign dmw0_en = ((csr_dmw0[`PLV0] && csr_plv == 2'd0) || (csr_dmw0[`PLV3] && csr_plv == 2'd3)) && (wdata_i[31:29] == csr_dmw0[`VSEG]); - assign dmw1_en = ((csr_dmw1[`PLV0] && csr_plv == 2'd0) || (csr_dmw1[`PLV3] && csr_plv == 2'd3)) && (wdata_i[31:29] == csr_dmw1[`VSEG]); + assign dmw0_en = ((csr_dmw0[`PLV0] && csr_plv == 2'd0) || (csr_dmw0[`PLV3] && csr_plv == 2'd3)) && (signal_i.wdata[31:29] == csr_dmw0[`VSEG]); + assign dmw1_en = ((csr_dmw1[`PLV0] && csr_plv == 2'd0) || (csr_dmw1[`PLV3] && csr_plv == 2'd3)) && (signal_i.wdata[31:29] == csr_dmw1[`VSEG]); assign pg_mode = !csr_da && csr_pg; assign da_mode = csr_da && !csr_pg; @@ -131,194 +108,181 @@ module mem ( always @(*) begin if (rst == `RstEnable) begin - wd_o = `NOPRegAddr; - wreg_o = `WriteDisable; - wdata_o = `ZeroWord; - mem_addr_o = `ZeroWord; - mem_we = `WriteDisable; - mem_sel_o = 4'b0000; - mem_data_o = `ZeroWord; - mem_ce_o = `ChipDisable; + signal_o = 0; + signal_axi_o = 0; LLbit_we_o = 1'b0; LLbit_value_o = 1'b0; - inst_pc_o = `ZeroWord; + signal_o.inst_pc = `ZeroWord; end else begin - wd_o = wd_i; - wreg_o = wreg_i; - wdata_o = wdata_i; - mem_addr_o = `ZeroWord; - mem_we = `WriteDisable; - mem_ce_o = `ChipDisable; - mem_sel_o = 4'b1111; LLbit_we_o = 1'b0; LLbit_value_o = 1'b0; - inst_pc_o = inst_pc_i; - case (aluop_i) + signal_o.instr_valid = 1'b1; + case (signal_i.aluop) `EXE_LD_B_OP: begin - mem_addr_o = mem_addr_i; - mem_we = `WriteDisable; - mem_ce_o = `ChipEnable; - case (mem_addr_i[1:0]) + signal_axi_o.addr = signal_i.mem_addr; + signal_o.wreg = `WriteDisable; + signal_axi_o.ce = `ChipEnable; + case (signal_i.mem_addr[1:0]) 2'b00: begin - wdata_o = {{24{mem_data_i[31]}}, mem_data_i[31:24]}; - mem_sel_o = 4'b1000; + signal_o.wdata = {{24{mem_data_i[31]}}, mem_data_i[31:24]}; + signal_axi_o.sel = 4'b1000; end 2'b01: begin - wdata_o = {{24{mem_data_i[23]}}, mem_data_i[23:16]}; - mem_sel_o = 4'b0100; + signal_o.wdata = {{24{mem_data_i[23]}}, mem_data_i[23:16]}; + signal_axi_o.sel = 4'b0100; end 2'b10: begin - wdata_o = {{24{mem_data_i[15]}}, mem_data_i[15:8]}; - mem_sel_o = 4'b0010; + signal_o.wdata = {{24{mem_data_i[15]}}, mem_data_i[15:8]}; + signal_axi_o.sel = 4'b0010; end 2'b11: begin - wdata_o = {{24{mem_data_i[7]}}, mem_data_i[7:0]}; - mem_sel_o = 4'b0001; + signal_o.wdata = {{24{mem_data_i[7]}}, mem_data_i[7:0]}; + signal_axi_o.sel = 4'b0001; end default: begin - wdata_o = `ZeroWord; + signal_o.wdata = `ZeroWord; end endcase end `EXE_LD_H_OP: begin - mem_addr_o = mem_addr_i; - mem_we = `WriteDisable; - mem_ce_o = `ChipEnable; - case (mem_addr_i[1:0]) + signal_axi_o.addr = signal_i.mem_addr; + signal_o.wreg = `WriteDisable; + signal_axi_o.ce = `ChipEnable; + case (signal_i.mem_addr[1:0]) 2'b00: begin - wdata_o = {{16{mem_data_i[31]}}, mem_data_i[31:16]}; - mem_sel_o = 4'b1100; + signal_o.wdata = {{16{mem_data_i[31]}}, mem_data_i[31:16]}; + signal_axi_o.sel = 4'b1100; end 2'b10: begin - wdata_o = {{16{mem_data_i[15]}}, mem_data_i[15:0]}; - mem_sel_o = 4'b0011; + signal_o.wdata = {{16{mem_data_i[15]}}, mem_data_i[15:0]}; + signal_axi_o.sel = 4'b0011; end default: begin - wdata_o = `ZeroWord; + signal_o.wdata = `ZeroWord; end endcase end `EXE_LD_W_OP: begin - mem_addr_o = mem_addr_i; - mem_we = `WriteDisable; - mem_ce_o = `ChipEnable; - mem_sel_o = 4'b1111; - wdata_o = mem_data_i; + signal_axi_o.addr = signal_i.mem_addr; + signal_o.wreg = `WriteDisable; + signal_axi_o.ce = `ChipEnable; + signal_axi_o.sel = 4'b1111; + signal_o.wdata = mem_data_i; end `EXE_LD_BU_OP: begin - mem_addr_o = mem_addr_i; - mem_we = `WriteDisable; - mem_ce_o = `ChipEnable; - case (mem_addr_i[1:0]) + signal_axi_o.addr = signal_i.mem_addr; + signal_o.wreg = `WriteDisable; + signal_axi_o.ce = `ChipEnable; + case (signal_i.mem_addr[1:0]) 2'b00: begin - wdata_o = {{24{1'b0}}, mem_data_i[31:24]}; - mem_sel_o = 4'b1000; + signal_o.wdata = {{24{1'b0}}, mem_data_i[31:24]}; + signal_axi_o.sel = 4'b1000; end 2'b01: begin - wdata_o = {{24{1'b0}}, mem_data_i[23:16]}; - mem_sel_o = 4'b0100; + signal_o.wdata = {{24{1'b0}}, mem_data_i[23:16]}; + signal_axi_o.sel = 4'b0100; end 2'b10: begin - wdata_o = {{24{1'b0}}, mem_data_i[15:8]}; - mem_sel_o = 4'b0010; + signal_o.wdata = {{24{1'b0}}, mem_data_i[15:8]}; + signal_axi_o.sel = 4'b0010; end 2'b11: begin - wdata_o = {{24{1'b0}}, mem_data_i[7:0]}; - mem_sel_o = 4'b0001; + signal_o.wdata = {{24{1'b0}}, mem_data_i[7:0]}; + signal_axi_o.sel = 4'b0001; end default: begin - wdata_o = `ZeroWord; + signal_o.wdata = `ZeroWord; end endcase end `EXE_LD_HU_OP: begin - mem_addr_o = mem_addr_i; - mem_we = `WriteDisable; - mem_ce_o = `ChipEnable; - case (mem_addr_i[1:0]) + signal_axi_o.addr = signal_i.mem_addr; + signal_o.wreg = `WriteDisable; + signal_axi_o.ce = `ChipEnable; + case (signal_i.mem_addr[1:0]) 2'b00: begin - wdata_o = {{16{1'b0}}, mem_data_i[31:16]}; - mem_sel_o = 4'b1100; + signal_o.wdata = {{16{1'b0}}, mem_data_i[31:16]}; + signal_axi_o.sel = 4'b1100; end 2'b10: begin - wdata_o = {{16{1'b0}}, mem_data_i[15:0]}; - mem_sel_o = 4'b0011; + signal_o.wdata = {{16{1'b0}}, mem_data_i[15:0]}; + signal_axi_o.sel = 4'b0011; end default: begin - wdata_o = `ZeroWord; + signal_o.wdata = `ZeroWord; end endcase end `EXE_ST_B_OP: begin - mem_addr_o = mem_addr_i; - mem_we = `WriteEnable; - mem_ce_o = `ChipEnable; - mem_data_o = {reg2_i[7:0], reg2_i[7:0], reg2_i[7:0], reg2_i[7:0]}; - case (mem_addr_i[1:0]) + signal_axi_o.addr = signal_i.mem_addr; + signal_o.wreg = `WriteEnable; + signal_axi_o.ce = `ChipEnable; + signal_axi_o.data = {signal_i.reg2[7:0], signal_i.reg2[7:0], signal_i.reg2[7:0], signal_i.reg2[7:0]}; + case (signal_i.mem_addr[1:0]) 2'b00: begin - mem_sel_o = 4'b1000; + signal_axi_o.sel = 4'b1000; end 2'b01: begin - mem_sel_o = 4'b0100; + signal_axi_o.sel = 4'b0100; end 2'b10: begin - mem_sel_o = 4'b0010; + signal_axi_o.sel = 4'b0010; end 2'b11: begin - mem_sel_o = 4'b0001; + signal_axi_o.sel = 4'b0001; end default: begin - mem_sel_o = 4'b0000; + signal_axi_o.sel = 4'b0000; end endcase end `EXE_ST_H_OP: begin - mem_addr_o = mem_addr_i; - mem_we = `WriteEnable; - mem_ce_o = `ChipEnable; - mem_data_o = {reg2_i[15:0], reg2_i[15:0]}; - case (mem_addr_i[1:0]) + signal_axi_o.addr = signal_i.mem_addr; + signal_o.wreg = `WriteEnable; + signal_axi_o.ce = `ChipEnable; + signal_axi_o.data = {signal_i.reg2[15:0], signal_i.reg2[15:0]}; + case (signal_i.mem_addr[1:0]) 2'b00: begin - mem_sel_o = 4'b1100; + signal_axi_o.sel = 4'b1100; end 2'b10: begin - mem_sel_o = 4'b0011; + signal_axi_o.sel = 4'b0011; end default: begin - mem_sel_o = 4'b0000; + signal_axi_o.sel = 4'b0000; end endcase end `EXE_ST_W_OP: begin - mem_addr_o = mem_addr_i; - mem_we = `WriteEnable; - mem_ce_o = `ChipEnable; - mem_data_o = reg2_i; - mem_sel_o = 4'b1111; + signal_axi_o.addr = signal_i.mem_addr; + signal_o.wreg = `WriteEnable; + signal_axi_o.ce = `ChipEnable; + signal_axi_o.data = signal_i.reg2; + signal_axi_o.sel = 4'b1111; end `EXE_LL_OP: begin - mem_addr_o = mem_addr_i; - mem_we = `WriteDisable; - mem_ce_o = `ChipEnable; - mem_sel_o = 4'b1111; - wdata_o = mem_data_i; + signal_axi_o.addr = signal_i.mem_addr; + signal_o.wreg = `WriteDisable; + signal_axi_o.ce = `ChipEnable; + signal_axi_o.sel = 4'b1111; + signal_o.wdata = mem_data_i; LLbit_we_o = 1'b1; LLbit_value_o = 1'b1; end `EXE_SC_OP: begin if (LLbit == 1'b1) begin - mem_addr_o = mem_addr_i; - mem_we = `WriteEnable; - mem_ce_o = `ChipEnable; - mem_data_o = reg2_i; - mem_sel_o = 4'b1111; + signal_axi_o.addr = signal_i.mem_addr; + signal_o.wreg = `WriteEnable; + signal_axi_o.ce = `ChipEnable; + signal_axi_o.data = signal_i.reg2; + signal_axi_o.sel = 4'b1111; LLbit_we_o = 1'b1; LLbit_value_o = 1'b0; - wdata_o = 32'b1; + signal_o.wdata = 32'b1; end else begin - wdata_o = 32'b0; + signal_o.wdata = 32'b0; end end default: begin diff --git a/src/vsrc/pipeline/4_mem/mem_wb.sv b/src/vsrc/pipeline/4_mem/mem_wb.sv index a58af24..05f031f 100644 --- a/src/vsrc/pipeline/4_mem/mem_wb.sv +++ b/src/vsrc/pipeline/4_mem/mem_wb.sv @@ -1,18 +1,11 @@ -`include "csr_defines.sv" -`include "defines.sv" +`include "pipeline_defines.sv" module mem_wb ( input wire clk, input wire rst, input wire stall, - input wire [`RegAddrBus] mem_wd, - input wire mem_wreg, - input wire [`RegBus] mem_wdata, - input wire [`InstAddrBus] mem_inst_pc, - input wire [`InstBus] mem_instr, - input wire [`AluOpBus] mem_aluop, - input wire mem_inst_valid, + input mem_wb_struct mem_signal_o, input wire mem_LLbit_we, input wire mem_LLbit_value, @@ -21,11 +14,8 @@ module mem_wb ( input wire [15:0] excp_num, - input csr_write_signal mem_csr_signal_o, - output reg [`RegAddrBus] wb_wd, - output reg wb_wreg, - output reg [`RegBus] wb_wdata, + output wb_reg wb_reg_o, output csr_write_signal wb_csr_signal_o, @@ -56,9 +46,9 @@ module mem_wb ( reg wb_valid; - assign csr_era = mem_inst_pc; + assign csr_era = mem_signal_o.instr_info.pc; assign excp_flush = excp_i; - assign ertn_flush = mem_aluop == `EXE_ERTN_OP; + assign ertn_flush = mem_signal_o.aluop == `EXE_ERTN_OP; assign csr_ecode = excp_num[0] ? `ECODE_INT : excp_num[1] ? `ECODE_ADEF : excp_num[2] ? `ECODE_TLBR : excp_num[3] ? `ECODE_PIF : @@ -71,10 +61,10 @@ module mem_wb ( excp_num[8] ? 1'b0 :excp_num[9] ? wb_valid : excp_num[10] ? wb_valid : excp_num[11] ? wb_valid : excp_num[12] ? wb_valid :excp_num[13] ? wb_valid : excp_num[14] ? wb_valid :excp_num[15] ? wb_valid : 1'b0 ; - assign bad_va = excp_num[0] ? 32'b0 : excp_num[1] ? mem_inst_pc : excp_num[2] ? mem_inst_pc : excp_num[3] ? mem_inst_pc : - excp_num[4] ? mem_inst_pc : excp_num[5] ? 32'b0 :excp_num[6] ? 32'b0 : excp_num[7] ? 32'b0 : - excp_num[8] ? 32'b0 :excp_num[9] ? wb_wdata : excp_num[10] ? wb_wdata : excp_num[11] ? wb_wdata : - excp_num[12] ? wb_wdata :excp_num[13] ? wb_wdata : excp_num[14] ? wb_wdata :excp_num[15] ? wb_wdata : 32'b0 ; + assign bad_va = excp_num[0] ? 32'b0 : excp_num[1] ? mem_signal_o.instr_info.pc : excp_num[2] ? mem_signal_o.instr_info.pc : excp_num[3] ? mem_signal_o.instr_info.pc : + excp_num[4] ? mem_signal_o.instr_info.pc : excp_num[5] ? 32'b0 :excp_num[6] ? 32'b0 : excp_num[7] ? 32'b0 : + excp_num[8] ? 32'b0 :excp_num[9] ? wb_reg_o.wdata : excp_num[10] ? wb_reg_o.wdata : excp_num[11] ? wb_reg_o.wdata : + excp_num[12] ? wb_reg_o.wdata :excp_num[13] ? wb_reg_o.wdata : excp_num[14] ? wb_reg_o.wdata :excp_num[15] ? wb_reg_o.wdata : 32'b0 ; assign csr_esubcode = excp_num[0] ? 9'b0 : excp_num[1] ? `ESUBCODE_ADEF : excp_num[2] ? 9'b0 : excp_num[3] ? 9'b0 : excp_num[4] ? 9'b0 : excp_num[5] ? 9'b0 :excp_num[6] ? 9'b0 : excp_num[7] ? 9'b0 : @@ -91,17 +81,17 @@ module mem_wb ( excp_num[8] ? 1'b0 :excp_num[9] ? 1'b0 : excp_num[10] ? 1'b0 : excp_num[11] ? wb_valid : excp_num[12] ? wb_valid :excp_num[13] ? wb_valid : excp_num[14] ? wb_valid :excp_num[15] ? wb_valid : 1'b0 ; - assign excp_tlb_vppn = excp_num[0] ? 19'b0 : excp_num[1] ? 19'b0 : excp_num[2] ? mem_inst_pc[31:13] : excp_num[3] ? mem_inst_pc[31:13] : - excp_num[4] ? mem_inst_pc[31:13] : excp_num[5] ? 19'b0 :excp_num[6] ? 19'b0 : excp_num[7] ? 19'b0 : - excp_num[8] ? 19'b0 :excp_num[9] ? 19'b0 : excp_num[10] ? 19'b0 : excp_num[11] ? wb_wdata[31:13] : - excp_num[12] ? wb_wdata[31:13] :excp_num[13] ? wb_wdata[31:13] : excp_num[14] ? wb_wdata[31:13] :excp_num[15] ? wb_wdata[31:13] : 19'b0 ; + assign excp_tlb_vppn = excp_num[0] ? 19'b0 : excp_num[1] ? 19'b0 : excp_num[2] ? mem_signal_o.instr_info.pc[31:13] : excp_num[3] ? mem_signal_o.instr_info.pc[31:13] : + excp_num[4] ? mem_signal_o.instr_info.pc[31:13] : excp_num[5] ? 19'b0 :excp_num[6] ? 19'b0 : excp_num[7] ? 19'b0 : + excp_num[8] ? 19'b0 :excp_num[9] ? 19'b0 : excp_num[10] ? 19'b0 : excp_num[11] ? wb_reg_o.wdata[31:13] : + excp_num[12] ? wb_reg_o.wdata[31:13] :excp_num[13] ? wb_reg_o.wdata[31:13] : excp_num[14] ? wb_reg_o.wdata[31:13] :excp_num[15] ? wb_reg_o.wdata[31:13] : 19'b0 ; always @(posedge clk) begin if (rst == `RstEnable) begin - wb_wd <= `NOPRegAddr; - wb_wreg <= `WriteDisable; - wb_wdata <= `ZeroWord; + wb_reg_o.waddr <= `NOPRegAddr; + wb_reg_o.we <= `WriteDisable; + wb_reg_o.wdata <= `ZeroWord; wb_valid <= 1'b0; wb_LLbit_we <= 1'b0; wb_LLbit_value <= 1'b0; @@ -109,10 +99,10 @@ module mem_wb ( debug_commit_instr <= `ZeroWord; debug_commit_pc <= `ZeroWord; debug_commit_valid <= `InstInvalid; - end else if (flush == 1'b1 || excp_i == 1'b1 || mem_aluop == `EXE_ERTN_OP) begin - wb_wd <= `NOPRegAddr; - wb_wreg <= `WriteDisable; - wb_wdata <= `ZeroWord; + end else if (flush == 1'b1 || excp_i == 1'b1 || mem_signal_o.aluop == `EXE_ERTN_OP) begin + wb_reg_o.waddr <= `NOPRegAddr; + wb_reg_o.we <= `WriteDisable; + wb_reg_o.wdata <= `ZeroWord; wb_valid <= 1'b0; wb_LLbit_we <= 1'b0; wb_LLbit_value <= 1'b0; @@ -125,16 +115,16 @@ module mem_wb ( debug_commit_instr <= `ZeroWord; debug_commit_valid <= `InstInvalid; end else begin - wb_wd <= mem_wd; - wb_wreg <= mem_wreg; - wb_wdata <= mem_wdata; + wb_reg_o.waddr <= mem_signal_o.waddr; + wb_reg_o.we <= mem_signal_o.wreg; + wb_reg_o.wdata <= mem_signal_o.wdata; wb_valid <= 1'b1; wb_LLbit_we <= mem_LLbit_we; wb_LLbit_value <= mem_LLbit_value; - wb_csr_signal_o <= mem_csr_signal_o; - debug_commit_pc <= mem_inst_pc; - debug_commit_valid <= mem_inst_valid; - debug_commit_instr <= mem_instr; + wb_csr_signal_o <= mem_signal_o.csr_signal; + debug_commit_pc <= mem_signal_o.instr_info.pc; + debug_commit_valid <= mem_signal_o.instr_info.valid; + debug_commit_instr <= mem_signal_o.instr_info.instr; end end diff --git a/src/vsrc/pipeline_defines.sv b/src/vsrc/pipeline_defines.sv index da0ad4f..f47af27 100644 --- a/src/vsrc/pipeline_defines.sv +++ b/src/vsrc/pipeline_defines.sv @@ -6,7 +6,6 @@ `define DECODE_WIDTH 2 typedef struct packed { - logic instr_valid; instr_buffer_info_t instr_info; // Reg read info @@ -14,6 +13,7 @@ typedef struct packed { logic [`RegBus] imm; logic [1:0] reg_read_valid; // Read valid for 2 regs logic [`RegNumLog2*2-1:0] reg_read_addr; // Read addr, {reg2, reg1} + logic [`InstBus] instr; logic [`AluOpBus] aluop; logic [`AluSelBus] alusel; @@ -25,9 +25,9 @@ typedef struct packed { typedef struct packed { - logic instr_valid; instr_buffer_info_t instr_info; + logic [`InstBus] instr; logic [`RegBus] oprand1; logic [`RegBus] oprand2; logic [`AluOpBus] aluop; @@ -39,4 +39,41 @@ typedef struct packed { csr_write_signal csr_signal; } dispatch_ex_struct; +typedef struct packed { + instr_buffer_info_t instr_info; + + logic wreg; + logic [`RegAddrBus] waddr; + logic [`RegBus] wdata; + logic [`AluOpBus] aluop; + logic [`RegBus] mem_addr; + logic [`RegBus] reg2; + csr_write_signal csr_signal; +} ex_mem_struct; + +typedef struct packed { + instr_buffer_info_t instr_info; + + logic [`RegAddrBus] waddr; + logic wreg; + logic [`RegBus] wdata; + logic [`AluOpBus] aluop; + csr_write_signal csr_signal; +} mem_wb_struct; + +typedef struct packed { + logic we; + logic ce; + logic [3:0] sel; + logic [`DataAddrBus] addr; + logic [`RegBus]data; +} mem_axi_struct; + +typedef struct packed { + logic we; + logic [`RegAddrBus] waddr; + logic [`RegBus] wdata; +} wb_reg; + + `endif From e1ea2d66ee1aaf372b3351c9241f42ad03c311f7 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Sat, 7 May 2022 20:07:47 +0800 Subject: [PATCH 085/114] fix: fix conflict solve error --- src/vsrc/cpu_top.sv | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/vsrc/cpu_top.sv b/src/vsrc/cpu_top.sv index 6cce243..3d7692f 100644 --- a/src/vsrc/cpu_top.sv +++ b/src/vsrc/cpu_top.sv @@ -96,7 +96,7 @@ module cpu_top ( // MEM <-> AXI Controller // TODO: replace with DCache logic data_axi_we; - logic [`InstAddrBus] data_axi_addr; + logic [`DataAddrBus] data_axi_addr; logic [`RegBus] data_axi_data; logic data_axi_busy; @@ -113,6 +113,12 @@ module cpu_top ( assign data_axi_addr = data_axi_we_1 ? data_axi_addr_1 : data_axi_we_2 ? data_axi_addr_2 : 0; assign data_axi_data = data_axi_we_1 ? data_axi_data_1 : data_axi_we_2 ? data_axi_data_2 : 0; + mem_axi_struct mem_axi_signal[2]; + + assign data_axi_we = mem_axi_signal[0].we | mem_axi_signal[1].we; + assign data_axi_addr = mem_axi_signal[0].we ? mem_axi_signal[1].addr : mem_axi_signal[1].we ? mem_axi_signal[1].addr : 32'b0; + assign data_axi_data = mem_axi_signal[0].we ? mem_axi_signal[1].data : mem_axi_signal[1].we ? mem_axi_signal[1].data : 32'b0; + axi_master u_axi_master ( .aclk (aclk), .aresetn(aresetn), From 493fce5f54733d4912c770fae65f52220c8e069d Mon Sep 17 00:00:00 2001 From: Easton Man Date: Sat, 7 May 2022 20:19:13 +0800 Subject: [PATCH 086/114] fix: fix not defined --- src/vsrc/cpu_top.sv | 17 +++++++++++------ src/vsrc/pipeline/4_mem/mem.sv | 13 +++++++++---- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/vsrc/cpu_top.sv b/src/vsrc/cpu_top.sv index 3d7692f..66d0ade 100644 --- a/src/vsrc/cpu_top.sv +++ b/src/vsrc/cpu_top.sv @@ -683,6 +683,11 @@ module cpu_top ( logic wb_excp_tlbrefill[2]; wb_reg wb_reg_signal[2]; + // Difftest Related + logic [1:0] debug_commit_valid; + logic [1:0][`InstBus] debug_commit_instr; + logic [1:0][`InstAddrBus] debug_commit_pc; + generate for (genvar i = 0; i < 2; i++) begin : mem_wb mem_wb u_mem_wb ( @@ -703,9 +708,9 @@ module cpu_top ( .wb_csr_signal_o(), - .debug_commit_pc(), - .debug_commit_valid(), - .debug_commit_instr(), + .debug_commit_pc(debug_commit_pc[i]), + .debug_commit_valid(debug_commit_valid[i]), + .debug_commit_instr(debug_commit_instr[i]), .wb_LLbit_we(), .wb_LLbit_value(), @@ -909,8 +914,8 @@ module cpu_top ( logic [`RegBus] debug_commit_pc_1_delay_1; logic debug_commit_valid_1_delay_1; always_ff @(posedge clk) begin - debug_commit_valid_1_delay_1 <= debug_commit_valid_1; - debug_commit_pc_1_delay_1 <= debug_commit_pc_1; + debug_commit_valid_1_delay_1 <= debug_commit_valid[0]; + debug_commit_pc_1_delay_1 <= debug_commit_pc[0]; end DifftestInstrCommit difftest_instr_commit_0 ( // TODO: not finished yet, blank signal is needed .clock (aclk), @@ -918,7 +923,7 @@ module cpu_top ( .index (0), // Commit channel index .valid (debug_commit_valid_1_delay_1), // 1 means valid .pc (debug_commit_pc_1_delay_1), - .instr (debug_commit_instr_1), + .instr (debug_commit_instr[0]), .skip (0), // Not sure meaning, but keep 0 for now .is_TLBFILL (), .TLBFILL_index (), diff --git a/src/vsrc/pipeline/4_mem/mem.sv b/src/vsrc/pipeline/4_mem/mem.sv index 3f8fe43..7b05ac9 100644 --- a/src/vsrc/pipeline/4_mem/mem.sv +++ b/src/vsrc/pipeline/4_mem/mem.sv @@ -57,7 +57,7 @@ module mem ( output logic [15:0] excp_num_o ); - reg LLbit; + reg LLbit; logic access_mem; logic mem_store_op; logic mem_load_op; @@ -112,11 +112,11 @@ module mem ( signal_axi_o = 0; LLbit_we_o = 1'b0; LLbit_value_o = 1'b0; - signal_o.inst_pc = `ZeroWord; + signal_o.instr_info.pc = `ZeroWord; end else begin LLbit_we_o = 1'b0; LLbit_value_o = 1'b0; - signal_o.instr_valid = 1'b1; + signal_o.instr_info.valid = 1'b1; case (signal_i.aluop) `EXE_LD_B_OP: begin signal_axi_o.addr = signal_i.mem_addr; @@ -219,7 +219,12 @@ module mem ( signal_axi_o.addr = signal_i.mem_addr; signal_o.wreg = `WriteEnable; signal_axi_o.ce = `ChipEnable; - signal_axi_o.data = {signal_i.reg2[7:0], signal_i.reg2[7:0], signal_i.reg2[7:0], signal_i.reg2[7:0]}; + signal_axi_o.data = { + signal_i.reg2[7:0], + signal_i.reg2[7:0], + signal_i.reg2[7:0], + signal_i.reg2[7:0] + }; case (signal_i.mem_addr[1:0]) 2'b00: begin signal_axi_o.sel = 4'b1000; From f75a1fed68b00cce40ad86deb922273a5fde2bc7 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Sat, 7 May 2022 21:26:35 +0800 Subject: [PATCH 087/114] fix: fix mem signal_o empty --- src/vsrc/pipeline/4_mem/mem.sv | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/vsrc/pipeline/4_mem/mem.sv b/src/vsrc/pipeline/4_mem/mem.sv index 7b05ac9..1ef5e30 100644 --- a/src/vsrc/pipeline/4_mem/mem.sv +++ b/src/vsrc/pipeline/4_mem/mem.sv @@ -116,7 +116,14 @@ module mem ( end else begin LLbit_we_o = 1'b0; LLbit_value_o = 1'b0; - signal_o.instr_info.valid = 1'b1; + // FIXME: information should be passed to next stage + // currently not carefully designed + signal_o.instr_info = signal_i.instr_info; + signal_o.wreg = signal_i.wreg; + signal_o.waddr = signal_i.waddr; + signal_o.wdata = signal_i.wdata; + signal_o.aluop = signal_i.aluop; + signal_o.csr_signal = signal_i.csr_signal; case (signal_i.aluop) `EXE_LD_B_OP: begin signal_axi_o.addr = signal_i.mem_addr; From 2596d2fdc89415ebad35aa0924fecbf014db10fe Mon Sep 17 00:00:00 2001 From: Rookie-rookie-rookie <292601787@qq.com> Date: Sun, 8 May 2022 10:14:15 +0800 Subject: [PATCH 088/114] connect LLbit_reg --- src/vsrc/cpu_top.sv | 93 +++++++++++-------------------- src/vsrc/pipeline/4_mem/mem_wb.sv | 9 ++- src/vsrc/pipeline_defines.sv | 1 + 3 files changed, 36 insertions(+), 67 deletions(-) diff --git a/src/vsrc/cpu_top.sv b/src/vsrc/cpu_top.sv index 3d7692f..20083e3 100644 --- a/src/vsrc/cpu_top.sv +++ b/src/vsrc/cpu_top.sv @@ -98,20 +98,9 @@ module cpu_top ( logic data_axi_we; logic [`DataAddrBus] data_axi_addr; logic [`RegBus] data_axi_data; + logic [`RegBus] axi_mem_data; logic data_axi_busy; - logic data_axi_we_1; - logic [`InstAddrBus] data_axi_addr_1; - logic [`RegBus] data_axi_data_1; - - logic data_axi_we_2; - logic [`InstAddrBus] data_axi_addr_2; - logic [`RegBus] data_axi_data_2; - - // 1 is prioritizes - assign data_axi_we = data_axi_we_1 | data_axi_we_2; - assign data_axi_addr = data_axi_we_1 ? data_axi_addr_1 : data_axi_we_2 ? data_axi_addr_2 : 0; - assign data_axi_data = data_axi_we_1 ? data_axi_data_1 : data_axi_we_2 ? data_axi_data_2 : 0; mem_axi_struct mem_axi_signal[2]; @@ -138,12 +127,12 @@ module cpu_top ( // <-> MEM Stage .data_cpu_addr_i(data_axi_addr), .data_cpu_ce_i(data_axi_addr != 0), // FIXME: ce should not be used as valid? - .data_cpu_data_i(0), + .data_cpu_data_i(data_axi_data), .data_cpu_we_i(1'b0), // FIXME: Write enable .data_cpu_sel_i(4'b1111), .data_stall_i(), .data_flush_i(), - .data_cpu_data_o(data_axi_data), + .data_cpu_data_o(axi_mem_data), .data_stallreq(data_axi_busy), .data_id(4'b0000), @@ -353,9 +342,6 @@ module cpu_top ( ); - - - logic [`RegBus] branch_target_address_1; logic [`RegBus] branch_target_address_2; logic [`RegBus] link_addr; @@ -504,11 +490,6 @@ module cpu_top ( end endgenerate - logic ex_inst_valid_o_2; - logic [`InstAddrBus] ex_inst_pc_o_2; - logic [`RegBus] ex_addr_o_2; - logic [`RegBus] ex_reg2_o_2; - logic [1:0] ex_excepttype_o_2; logic [`RegBus] ex_current_inst_address_o_2; logic ex_csr_we_o_2; logic [13:0] ex_csr_addr_o_2; @@ -523,10 +504,6 @@ module cpu_top ( logic mem_inst_valid_1; logic [`InstAddrBus] mem_inst_pc_1; - logic [`AluOpBus] mem_aluop_i_1; - logic [`RegBus] mem_addr_i_1; - logic [`RegBus] mem_reg2_i_1; - logic [1:0] mem_excepttype_i_1; logic [`RegBus] mem_current_inst_address_i_1; @@ -537,24 +514,13 @@ module cpu_top ( logic LLbit_o_1; - logic wb_LLbit_we_i_1; - logic wb_LLbit_value_i_1; - logic mem_LLbit_we_o_1; - logic mem_LLbit_value_o_1; - logic [1:0] mem_excepttype_o_1; - logic [1:0] mem_excepttype_o_2; logic [`RegBus] mem_current_inst_address_o_1; - logic [`InstAddrBus] wb_inst_pc_1; - csr_write_signal mem_csr_signal_o_1; - csr_write_signal mem_csr_signal_o_2; logic mem_excp_o_1; logic [15:0] mem_excp_num_o_1; logic mem_excp_o_2; logic [15:0] mem_excp_num_o_2; - logic [`AluOpBus] mem_aluop_o_1; - logic [`AluOpBus] mem_aluop_o_2; logic data_addr_trans_en_1; logic data_dmw0_en_1; @@ -594,20 +560,20 @@ module cpu_top ( mem_wb_struct mem_signal_o[2]; logic LLbit_o_2; - logic wb_LLbit_we_i_2; - logic wb_LLbit_value_i_2; - logic mem_LLbit_we_o_2; - logic mem_LLbit_value_o_2; logic [`RegBus] mem_current_inst_address_o_2; logic [`InstAddrBus] wb_inst_pc_2; logic mem_csr_we_o_2; logic [13:0] mem_csr_addr_o_2; logic [31:0] mem_csr_data_o_2; + logic LLbit_o; + logic mem_wb_LLbit_we[2]; + logic mem_wb_LLbit_value[2]; + generate for (genvar i = 0; i < 2; i++) begin : mem mem u_mem ( - .rst(), + .rst(rst), .signal_i(mem_signal_i[i]), @@ -615,14 +581,18 @@ module cpu_top ( .signal_axi_o(mem_axi_signal[i]), - .mem_data_i(), + .mem_data_i(axi_mem_data), - .LLbit_i(), - .wb_LLbit_we_i(), - .wb_LLbit_value_i(), + .LLbit_i(LLbit_o), + .wb_LLbit_we_i(wb_LLbit_we_i[i]), + .wb_LLbit_value_i(wb_LLbit_value_i[i]), + .LLbit_we_o(mem_wb_LLbit_we[i]), + .LLbit_value_o(mem_wb_LLbit_value[i]), .current_inst_address_i(), + .current_inst_address_o(), + .excp_i(mem_excp_i_2), .excp_num_i(mem_excp_num_i_2), .excp_o(mem_excp_o_2), @@ -682,6 +652,9 @@ module cpu_top ( logic wb_excp_tlbrefill[2]; wb_reg wb_reg_signal[2]; + + logic wb_LLbit_we_i[2]; + logic wb_LLbit_value_i[2]; generate for (genvar i = 0; i < 2; i++) begin : mem_wb @@ -692,12 +665,10 @@ module cpu_top ( .mem_signal_o(mem_signal_o[i]), - .mem_LLbit_we(), - .mem_LLbit_value(), - - .flush(), + .mem_LLbit_we(mem_wb_LLbit_we[i]), + .mem_LLbit_value(mem_wb_LLbit_value[i]), - .excp_num(), + .flush(flush), .wb_reg_o(wb_reg_signal[i]), @@ -707,13 +678,11 @@ module cpu_top ( .debug_commit_valid(), .debug_commit_instr(), - .wb_LLbit_we(), - .wb_LLbit_value(), + .wb_LLbit_we(wb_LLbit_we_i[i]), + .wb_LLbit_value(wb_LLbit_value_i[i]), .excp_i(), - .excp_num_i(), - .excp_o(), - .excp_num_o(), + .excp_num(), //to csr .csr_era(wb_csr_era[i]), @@ -738,11 +707,11 @@ module cpu_top ( .rst(rst), .we_1 (wb_reg_signal[0].we), - .pc_i_1 (), + .pc_i_1 (wb_reg_signal[0].pc), .waddr_1(wb_reg_signal[0].waddr), .wdata_1(wb_reg_signal[0].wdata), .we_2 (wb_reg_signal[1].we), - .pc_i_2 (), + .pc_i_2 (wb_reg_signal[1].pc), .waddr_2(wb_reg_signal[1].waddr), .wdata_2(wb_reg_signal[1].wdata), @@ -774,9 +743,9 @@ module cpu_top ( .clk(clk), .rst(rst), .flush(1'b0), - .LLbit_i_1(wb_LLbit_value_i_1), - .LLbit_i_2(wb_LLbit_value_i_2), - .we(wb_LLbit_we_i), + .LLbit_i_1(wb_LLbit_value_i[0]), + .LLbit_i_2(wb_LLbit_value_i[1]), + .we(wb_LLbit_we_i[0] | wb_LLbit_we_i[1]), .LLbit_o(LLbit_o) ); @@ -844,7 +813,7 @@ module cpu_top ( assign data_dmw1_en = data_dmw1_en_1 | data_dmw1_en_2; tlb u_tlb ( - .clk (), + .clk (clk), .asid (csr_asid), //trans mode .inst_addr_trans_en(inst_addr_trans_en), diff --git a/src/vsrc/pipeline/4_mem/mem_wb.sv b/src/vsrc/pipeline/4_mem/mem_wb.sv index 05f031f..653f938 100644 --- a/src/vsrc/pipeline/4_mem/mem_wb.sv +++ b/src/vsrc/pipeline/4_mem/mem_wb.sv @@ -12,8 +12,6 @@ module mem_wb ( input wire flush, - input wire [15:0] excp_num, - output wb_reg wb_reg_o, @@ -27,9 +25,7 @@ module mem_wb ( output reg wb_LLbit_value, input wire excp_i, - input wire [15:0] excp_num_i, - output reg excp_o, - output reg [15:0] excp_num_o, + input wire [15:0] excp_num, //to csr output wire [31:0] csr_era, @@ -92,6 +88,7 @@ module mem_wb ( wb_reg_o.waddr <= `NOPRegAddr; wb_reg_o.we <= `WriteDisable; wb_reg_o.wdata <= `ZeroWord; + wb_reg_o.pc <= `ZeroWord; wb_valid <= 1'b0; wb_LLbit_we <= 1'b0; wb_LLbit_value <= 1'b0; @@ -103,6 +100,7 @@ module mem_wb ( wb_reg_o.waddr <= `NOPRegAddr; wb_reg_o.we <= `WriteDisable; wb_reg_o.wdata <= `ZeroWord; + wb_reg_o.pc <= `ZeroWord; wb_valid <= 1'b0; wb_LLbit_we <= 1'b0; wb_LLbit_value <= 1'b0; @@ -118,6 +116,7 @@ module mem_wb ( wb_reg_o.waddr <= mem_signal_o.waddr; wb_reg_o.we <= mem_signal_o.wreg; wb_reg_o.wdata <= mem_signal_o.wdata; + wb_reg_o.pc <= mem_signal_o.instr_info.pc; wb_valid <= 1'b1; wb_LLbit_we <= mem_LLbit_we; wb_LLbit_value <= mem_LLbit_value; diff --git a/src/vsrc/pipeline_defines.sv b/src/vsrc/pipeline_defines.sv index f47af27..a099981 100644 --- a/src/vsrc/pipeline_defines.sv +++ b/src/vsrc/pipeline_defines.sv @@ -71,6 +71,7 @@ typedef struct packed { typedef struct packed { logic we; + logic [`InstAddrBus] pc; logic [`RegAddrBus] waddr; logic [`RegBus] wdata; } wb_reg; From 107526098a2ec435b3f305c0f7519d0111314170 Mon Sep 17 00:00:00 2001 From: Rookie-rookie-rookie <292601787@qq.com> Date: Sun, 8 May 2022 11:11:50 +0800 Subject: [PATCH 089/114] fix some bug --- src/vsrc/cpu_top.sv | 128 +++++++++------------------------ src/vsrc/pipeline/4_mem/mem.sv | 12 +--- 2 files changed, 37 insertions(+), 103 deletions(-) diff --git a/src/vsrc/cpu_top.sv b/src/vsrc/cpu_top.sv index 20083e3..20e0ebc 100644 --- a/src/vsrc/cpu_top.sv +++ b/src/vsrc/cpu_top.sv @@ -301,9 +301,9 @@ module cpu_top ( // <-> CSR Registers .has_int (), - .csr_data_i (), + .csr_data_i (id_csr_data[i]), .csr_plv (), - .csr_read_addr_o() + .csr_read_addr_o(id_csr_read_addr_o[i]) ); end endgenerate @@ -435,16 +435,6 @@ module cpu_top ( logic [1:0] csr_datm; logic [1:0] csr_plv; - logic [13:0] id_csr_addr_1; - logic [31:0] id_csr_data_1; - logic [13:0] id_csr_addr_2; - logic [31:0] id_csr_data_2; - logic [13:0] id_csr_read_addr_o_1; - logic [13:0] id_csr_read_addr_o_2; - - logic pc_excp_o; - logic [3:0] pc_excp_num_o; - logic idle_flush; logic [`InstAddrBus] idle_pc; logic wb_excp_flush[2]; @@ -467,6 +457,8 @@ module cpu_top ( ex_mem_struct ex_signal_o[2]; + logic ex_excp_i[2]; + logic [8:0] ex_excp_num_i[2]; // EXE Stage @@ -482,45 +474,22 @@ module cpu_top ( .stallreq(), - .excp_i(), - .excp_num_i(), - .excp_o(), - .excp_num_o() + .excp_i(ex_excp_i[i]), + .excp_num_i(ex_excp_num_i[i]), + .excp_o(ex_excp_o[i]), + .excp_num_o(ex_excp_num_o[i]) ); end endgenerate - logic [`RegBus] ex_current_inst_address_o_2; - logic ex_csr_we_o_2; - logic [13:0] ex_csr_addr_o_2; - logic [31:0] ex_csr_data_o_2; - - - - logic mem_wreg_i_1; - logic [`RegAddrBus] mem_reg_waddr_i_1; - logic [`RegBus] mem_reg_wdata_i_1; - - logic mem_inst_valid_1; - logic [`InstAddrBus] mem_inst_pc_1; + logic ex_excp_o[2]; + logic [9:0] ex_excp_num_o[2]; - logic [`RegBus] mem_current_inst_address_i_1; - - - logic mem_excp_i_1; - logic [9:0] mem_excp_num_i_1; - logic mem_excp_i_2; - logic [9:0] mem_excp_num_i_2; - - - logic LLbit_o_1; - logic [`RegBus] mem_current_inst_address_o_1; - - logic mem_excp_o_1; - logic [15:0] mem_excp_num_o_1; - logic mem_excp_o_2; - logic [15:0] mem_excp_num_o_2; + logic mem_excp_i[2]; + logic [9:0] mem_excp_num_i[2]; + logic mem_excp_o[2]; + logic [15:0] mem_excp_num_o[2]; logic data_addr_trans_en_1; logic data_dmw0_en_1; @@ -546,12 +515,12 @@ module cpu_top ( .flush(flush), .ex_current_inst_address(), - .excp_i(), - .excp_num_i(), + .excp_i(ex_excp_o[i]), + .excp_num_i(ex_excp_num_o[i]), .mem_current_inst_address(), - .excp_o(), - .excp_num_o() + .excp_o(mem_excp_i[i]), + .excp_num_o(mem_excp_num_i[i]) ); end @@ -559,13 +528,6 @@ module cpu_top ( mem_wb_struct mem_signal_o[2]; - logic LLbit_o_2; - logic [`RegBus] mem_current_inst_address_o_2; - logic [`InstAddrBus] wb_inst_pc_2; - logic mem_csr_we_o_2; - logic [13:0] mem_csr_addr_o_2; - logic [31:0] mem_csr_data_o_2; - logic LLbit_o; logic mem_wb_LLbit_we[2]; logic mem_wb_LLbit_value[2]; @@ -589,14 +551,10 @@ module cpu_top ( .LLbit_we_o(mem_wb_LLbit_we[i]), .LLbit_value_o(mem_wb_LLbit_value[i]), - .current_inst_address_i(), - - .current_inst_address_o(), - - .excp_i(mem_excp_i_2), - .excp_num_i(mem_excp_num_i_2), - .excp_o(mem_excp_o_2), - .excp_num_o(mem_excp_num_o_2), + .excp_i(mem_excp_i[i]), + .excp_num_i(mem_excp_num_i[i]), + .excp_o(mem_excp_o[i]), + .excp_num_o(mem_excp_num_o[i]), .csr_pg(csr_pg), .csr_da(csr_da), @@ -622,39 +580,20 @@ module cpu_top ( endgenerate - logic wb_csr_we_1; - logic [13:0] wb_csr_addr_1; - logic [`RegBus] wb_csr_data_1; - - assign debug0_wb_rf_wen = wb_reg_signal[0].we; assign debug0_wb_rf_wnum = wb_reg_signal[0].waddr; assign debug0_wb_rf_wdata = wb_reg_signal[0].wdata; - - logic wb_excp_o_1; - logic [15:0] wb_excp_num_o_1; - logic wb_excp_o_2; - logic [15:0] wb_excp_num_o_2; - - csr_write_signal wb_csr_signal_o_1; - csr_write_signal wb_csr_signal_o_2; - - logic [18:0] wb_excp_tlb_vppn[2]; logic [`InstAddrBus] debug_commit_pc_1; - - logic wb_csr_we_2; - logic [13:0] wb_csr_addr_2; - logic [`RegBus] wb_csr_data_2; - logic wb_excp_tlbrefill[2]; wb_reg wb_reg_signal[2]; logic wb_LLbit_we_i[2]; logic wb_LLbit_value_i[2]; + logic [46:0] wb_csr_signal[2]; generate for (genvar i = 0; i < 2; i++) begin : mem_wb @@ -672,7 +611,7 @@ module cpu_top ( .wb_reg_o(wb_reg_signal[i]), - .wb_csr_signal_o(), + .wb_csr_signal_o(wb_csr_signal[i]), .debug_commit_pc(), .debug_commit_valid(), @@ -681,8 +620,8 @@ module cpu_top ( .wb_LLbit_we(wb_LLbit_we_i[i]), .wb_LLbit_value(wb_LLbit_value_i[i]), - .excp_i(), - .excp_num(), + .excp_i(mem_excp_o[i]), + .excp_num(mem_excp_num_o[i]), //to csr .csr_era(wb_csr_era[i]), @@ -761,17 +700,20 @@ module cpu_top ( assign excp_tlbrefill = wb_excp_tlbrefill[0] | wb_excp_tlbrefill[1]; assign excp_tlb_vppn = wb_excp_tlb_vppn[0] | wb_excp_tlb_vppn[1]; + logic [13:0] id_csr_read_addr_o[2]; + logic [`RegBus] id_csr_data[2]; + cs_reg u_cs_reg ( .clk(clk), .rst(rst), .excp_flush(excp_flush), .ertn_flush(ertn_flush), - .write_signal_1(wb_csr_signal_o_1), - .write_signal_2(wb_csr_signal_o_2), - .raddr_1(id_csr_read_addr_o_1), - .raddr_2(id_csr_read_addr_o_2), - .rdata_1(id_csr_data_1), - .rdata_2(id_csr_data_2), + .write_signal_1(wb_csr_signal[0]), + .write_signal_2(wb_csr_signal[1]), + .raddr_1(id_csr_read_addr_o[0]), + .raddr_2(id_csr_read_addr_o[1]), + .rdata_1(id_csr_data[0]), + .rdata_2(id_csr_data[1]), .era_i(csr_era_i), .esubcode_i(csr_esubcode_i), .va_error_i(va_error_i), diff --git a/src/vsrc/pipeline/4_mem/mem.sv b/src/vsrc/pipeline/4_mem/mem.sv index 3f8fe43..4061f2b 100644 --- a/src/vsrc/pipeline/4_mem/mem.sv +++ b/src/vsrc/pipeline/4_mem/mem.sv @@ -18,9 +18,6 @@ module mem ( input logic wb_LLbit_we_i, input logic wb_LLbit_value_i, - input logic [`RegBus] current_inst_address_i, - - input logic excp_i, input logic [9:0] excp_num_i, @@ -47,12 +44,9 @@ module mem ( input logic [1:0] data_tlb_mat, input logic [1:0] data_tlb_plv, - output reg LLbit_we_o, output reg LLbit_value_o, - output logic [`RegBus] current_inst_address_o, - output logic excp_o, output logic [15:0] excp_num_o ); @@ -77,8 +71,6 @@ module mem ( assign mem_store_op = signal_i.aluop == `EXE_ST_B_OP || signal_i.aluop == `EXE_ST_H_OP || signal_i.aluop == `EXE_ST_W_OP || signal_i.aluop == `EXE_SC_OP; - assign current_inst_address_o = current_inst_address_i; - //addr dmw trans assign dmw0_en = ((csr_dmw0[`PLV0] && csr_plv == 2'd0) || (csr_dmw0[`PLV3] && csr_plv == 2'd3)) && (signal_i.wdata[31:29] == csr_dmw0[`VSEG]); @@ -112,11 +104,11 @@ module mem ( signal_axi_o = 0; LLbit_we_o = 1'b0; LLbit_value_o = 1'b0; - signal_o.inst_pc = `ZeroWord; + signal_o.instr_info.pc = `ZeroWord; end else begin LLbit_we_o = 1'b0; LLbit_value_o = 1'b0; - signal_o.instr_valid = 1'b1; + signal_o.instr_info.valid = 1'b1; case (signal_i.aluop) `EXE_LD_B_OP: begin signal_axi_o.addr = signal_i.mem_addr; From 059951f9c2e7e90c8a08a46b32f5356804fa4225 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Sun, 8 May 2022 15:43:58 +0800 Subject: [PATCH 090/114] feat: adapt to 2CMT --- .vscode/settings.json | 2 +- src/vsrc/cpu_top.sv | 71 ++++++++++++++++++++++++++++++------------- 2 files changed, 51 insertions(+), 22 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 08a9243..bee1b13 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,7 +2,7 @@ "verilog.linting.linter": "verilator", "verilog.linting.iverilog.arguments": "", "verilog.logging.enabled": true, - "verilog.linting.verilator.arguments": "-Isrc -Isrc/vsrc -Isrc/vsrc/pipeline/1_fetch -Wall", + "verilog.linting.verilator.arguments": "-Isrc -Isrc/vsrc -Isrc/vsrc/pipeline/1_fetch -Wall -DCPU_2CMT", "todo-tree.filtering.includeGlobs": [ "**/*.sv", "**/*.v" diff --git a/src/vsrc/cpu_top.sv b/src/vsrc/cpu_top.sv index ba55ff5..bf8d58d 100644 --- a/src/vsrc/cpu_top.sv +++ b/src/vsrc/cpu_top.sv @@ -73,6 +73,13 @@ module cpu_top ( output [ 3:0] debug0_wb_rf_wen, output [ 4:0] debug0_wb_rf_wnum, output [31:0] debug0_wb_rf_wdata + `ifdef CPU_2CMT + , + output [31:0] debug1_wb_pc, + output [ 3:0] debug1_wb_rf_wen, + output [ 4:0] debug1_wb_rf_wnum, + output [31:0] debug1_wb_rf_wdata + `endif ); // Clock signal @@ -580,17 +587,12 @@ module cpu_top ( endgenerate - assign debug0_wb_rf_wen = wb_reg_signal[0].we; - assign debug0_wb_rf_wnum = wb_reg_signal[0].waddr; - assign debug0_wb_rf_wdata = wb_reg_signal[0].wdata; logic [18:0] wb_excp_tlb_vppn[2]; - logic [`InstAddrBus] debug_commit_pc_1; - logic wb_excp_tlbrefill[2]; wb_reg wb_reg_signal[2]; - + logic wb_LLbit_we_i[2]; logic wb_LLbit_value_i[2]; logic [46:0] wb_csr_signal[2]; @@ -625,7 +627,7 @@ module cpu_top ( .wb_LLbit_we(wb_LLbit_we_i[i]), .wb_LLbit_value(wb_LLbit_value_i[i]), - .excp_i(mem_excp_o[i]), + .excp_i (mem_excp_o[i]), .excp_num(mem_excp_num_o[i]), //to csr @@ -820,22 +822,31 @@ module cpu_top ( .csr_pg (csr_pg) ); - // Difftest DPI-C -`ifdef SIMU // SIMU is defined in chiplab run_func/Makefile - logic [`RegBus] debug_commit_pc_1_delay_1; - logic debug_commit_valid_1_delay_1; + // Difftest Delay signals + logic [1:0] debug_commit_valid_delay1; + logic [1:0][`InstBus] debug_commit_instr_delay1; + logic [1:0][`InstAddrBus] debug_commit_pc_delay1; always_ff @(posedge clk) begin - debug_commit_valid_1_delay_1 <= debug_commit_valid[0]; - debug_commit_pc_1_delay_1 <= debug_commit_pc[0]; + debug_commit_instr_delay1 <= debug_commit_instr; + debug_commit_pc_delay1 <= debug_commit_pc; + debug_commit_valid_delay1 <= debug_commit_valid; end - DifftestInstrCommit difftest_instr_commit_0 ( // TODO: not finished yet, blank signal is needed + assign debug0_wb_pc = debug_commit_pc[0]; + assign debug0_wb_rf_wen = 1; + assign debug0_wb_rf_wdata = 0; + assign debug0_wb_rf_wnum = 0; + assign debug1_wb_pc = debug_commit_pc[1]; + assign debug1_wb_rf_wen = 1; + // difftest dpi-c +`ifdef SIMU // simu is defined in chiplab run_func/makefile + DifftestInstrCommit difftest_instr_commit_0 ( // todo: not finished yet, blank signal is needed .clock (aclk), - .coreid (0), // Only one core, so always 0 - .index (0), // Commit channel index - .valid (debug_commit_valid_1_delay_1), // 1 means valid - .pc (debug_commit_pc_1_delay_1), - .instr (debug_commit_instr[0]), - .skip (0), // Not sure meaning, but keep 0 for now + .coreid (0), // only one core, so always 0 + .index (0), // commit channel index + .valid (debug_commit_valid_delay1[0]), // 1 means valid + .pc (debug_commit_pc_delay1[0]), + .instr (debug_commit_instr_delay1[0]), + .skip (0), // not sure meaning, but keep 0 for now .is_TLBFILL (), .TLBFILL_index (), .is_CNTinst (), @@ -846,6 +857,24 @@ module cpu_top ( .csr_rstat (), .csr_data () ); + DifftestInstrCommit difftest_instr_commit_1 ( // todo: not finished yet, blank signal is needed + .clock (aclk), + .coreid (0), // only one core, so always 0 + .index (1), // commit channel index + .valid (debug_commit_valid_delay1[1]), // 1 means valid + .pc (debug_commit_pc_delay1[1]), + .instr (debug_commit_instr_delay1[1]), + .skip (0), // not sure meaning, but keep 0 for now + .is_TLBFILL (), + .TLBFILL_index (), + .is_CNTinst (), + .timer_64_value(), + .wen (debug1_wb_rf_wen), + .wdest ({3'b0, debug1_wb_rf_wnum}), + .wdata (debug1_wb_rf_wdata), + .csr_rstat (), + .csr_data () + ); DifftestCSRRegState difftest_csr_state ( .clock (aclk), @@ -879,7 +908,7 @@ module cpu_top ( .dmw1 (u_cs_reg.csr_dmw1) ); - // Assume regilfe instance name is u_regfile + // Assume regfile instance name is u_regfile // and architectural register are under regs[] array DifftestGRegState difftest_gpr_state ( .clock (aclk), From 19499a3c11f3de782b4fc219e0f8048fb66250b8 Mon Sep 17 00:00:00 2001 From: Rookie-rookie-rookie <292601787@qq.com> Date: Sun, 8 May 2022 19:45:43 +0800 Subject: [PATCH 091/114] add branch calculation --- src/vsrc/cpu_top.sv | 14 +++++---- src/vsrc/pipeline/3_execution/ex.sv | 49 ++++++++++++++++++++++++++++- 2 files changed, 56 insertions(+), 7 deletions(-) diff --git a/src/vsrc/cpu_top.sv b/src/vsrc/cpu_top.sv index bf8d58d..f0bbb92 100644 --- a/src/vsrc/cpu_top.sv +++ b/src/vsrc/cpu_top.sv @@ -349,8 +349,7 @@ module cpu_top ( ); - logic [`RegBus] branch_target_address_1; - logic [`RegBus] branch_target_address_2; + logic [`RegBus] branch_target_address[2]; logic [`RegBus] link_addr; logic flush; logic [`RegBus] new_pc; @@ -452,12 +451,12 @@ module cpu_top ( logic disable_cache; - logic branch_flag_1, branch_flag_2; + logic branch_flag[2]; - assign backend_flush = excp_flush | ertn_flush | branch_flag_1 | branch_flag_2; + assign backend_flush = excp_flush | ertn_flush | branch_flag[0] | branch_flag[1]; - assign next_pc = branch_flag_1 ? branch_target_address_1 : - branch_flag_2 ? branch_target_address_2 : + assign next_pc = branch_flag[0] ? branch_target_address[0] : + branch_flag[1] ? branch_target_address[1] : (excp_flush && !excp_tlbrefill) ? csr_eentry : (excp_flush && excp_tlbrefill) ? csr_tlbrentry : ertn_flush ? csr_era : `ZeroWord; @@ -481,6 +480,9 @@ module cpu_top ( .stallreq(), + .branch_flag(branch_flag[i]), + .branch_target_address(branch_target_address[i]), + .excp_i(ex_excp_i[i]), .excp_num_i(ex_excp_num_i[i]), .excp_o(ex_excp_o[i]), diff --git a/src/vsrc/pipeline/3_execution/ex.sv b/src/vsrc/pipeline/3_execution/ex.sv index d0673ef..eee4f09 100644 --- a/src/vsrc/pipeline/3_execution/ex.sv +++ b/src/vsrc/pipeline/3_execution/ex.sv @@ -13,6 +13,9 @@ module ex ( output logic stallreq, + output logic branch_flag, + output logic [`RegBus]branch_target_address, + input logic excp_i, input logic [8:0] excp_num_i, output logic excp_o, @@ -161,7 +164,51 @@ module ex ( end end - + always @(*) begin + if(rst == `RstEnable)begin + branch_flag = 1'b0; + branch_target_address = `ZeroWord; + end else begin + case(aluop_i) + `EXE_B_OP,`EXE_BL_OP,`EXE_JIRL_OP:begin + branch_flag = 1'b1; + branch_target_address = inst_pc_i + reg2_i; + end + `EXE_BEQ_OP:begin + if(reg1_i == reg2_i) + branch_flag = 1'b1; + branch_target_address = inst_pc_i + inst_i; + end + `EXE_BNE_OP:begin + if(reg1_i != reg2_i) + branch_flag = 1'b1; + branch_target_address = inst_pc_i + {{14{inst_i[25]}}, inst_i[25:10], 2'b0}; + end + `EXE_BLT_OP:begin + if(reg1_i < reg2_i) + branch_flag = 1'b1; + branch_target_address = inst_pc_i + {{14{inst_i[25]}}, inst_i[25:10], 2'b0}; + end + `EXE_BGE_OP:begin + if(reg1_i >= reg2_i) + branch_target_address = inst_pc_i + {{14{inst_i[25]}}, inst_i[25:10], 2'b0}; + end + `EXE_BLTU_OP:begin + if(reg1_i < reg2_i) + branch_flag = 1'b1; + branch_target_address = inst_pc_i + {{14{inst_i[25]}}, inst_i[25:10], 2'b0}; + end + `EXE_BGEU_OP:begin + if(reg1_i >= reg2_i) + branch_flag = 1'b1; + branch_target_address = inst_pc_i + {{14{inst_i[25]}}, inst_i[25:10], 2'b0}; + end + default:begin + + end + endcase + end + end always @(*) begin if (rst == `RstEnable) begin From 111e17cc1a4f441b29310a43c2f4c4d2fb743d5e Mon Sep 17 00:00:00 2001 From: Easton Man Date: Mon, 9 May 2022 10:06:52 +0800 Subject: [PATCH 092/114] fix: fix ID default 0 - rewrite ctrl block --- src/vsrc/cpu_top.sv | 36 +++++------- src/vsrc/ctrl.sv | 63 ++------------------- src/vsrc/pipeline/1_decode/decoder_1RI20.sv | 19 ++++--- src/vsrc/pipeline/1_decode/decoder_2RI14.sv | 23 +++++--- src/vsrc/pipeline/1_decode/decoder_CSR.sv | 27 +++++---- src/vsrc/pipeline/1_decode/decoder_I26.sv | 20 +++---- src/vsrc/pipeline/3_execution/ex.sv | 58 +++++++++---------- src/vsrc/pipeline/3_execution/ex_mem.sv | 6 +- 8 files changed, 102 insertions(+), 150 deletions(-) diff --git a/src/vsrc/cpu_top.sv b/src/vsrc/cpu_top.sv index f0bbb92..5e94baa 100644 --- a/src/vsrc/cpu_top.sv +++ b/src/vsrc/cpu_top.sv @@ -126,7 +126,7 @@ module cpu_top ( .inst_cpu_we_i(1'b0), .inst_cpu_sel_i(4'b1111), .inst_stall_i(), // FIXME: stall & flush - .inst_flush_i(), + .inst_flush_i(backend_flush), // FIXME: use ctrl module instead .inst_cpu_data_o(axi_data), .inst_stallreq(axi_busy), .inst_id(4'b0000), // Read Instruction only, TODO: move this from AXI to cache @@ -264,7 +264,7 @@ module cpu_top ( .frontend_stallreq_o(ib_frontend_stallreq), // <-> Backend - .backend_accept_i(2'b11), // TODO: connect to dispatch + .backend_accept_i({id_id_dispatch[1].instr_info.valid, id_id_dispatch[0].instr_info.valid}), // FIXME: does not carefully designed .backend_flush_i(backend_flush), // Assure output is reset the next cycle .backend_instr_o(ib_backend_instr_info) // -> ID ); @@ -323,7 +323,7 @@ module cpu_top ( .clk (clk), .rst (rst), .stall (), - .flush (flush), + .flush (backend_flush), // FIXME: does not carefully designed .id_i (id_id_dispatch), .dispatch_o(id_dispatch_dispatch) ); @@ -451,7 +451,7 @@ module cpu_top ( logic disable_cache; - logic branch_flag[2]; + logic [1:0] branch_flag; assign backend_flush = excp_flush | ertn_flush | branch_flag[0] | branch_flag[1]; @@ -509,20 +509,22 @@ module cpu_top ( logic data_dmw1_en_2; ex_mem_struct mem_signal_i[2]; - + logic [1:0] ex_mem_flush; generate for (genvar i = 0; i < 2; i++) begin : ex_mem ex_mem u_ex_mem ( .clk(clk), .rst(rst), - .stall(), .excp_flush(excp_flush), .ertn_flush(ertn_flush), .ex_o (ex_signal_o[i]), .mem_i(mem_signal_i[i]), - .flush(flush), + // <-> Ctrl + .stall(), + .flush(ex_mem_flush[i]), + .ex_current_inst_address(), .excp_i(ex_excp_o[i]), .excp_num_i(ex_excp_num_o[i]), @@ -670,22 +672,12 @@ module cpu_top ( .read_data_o (regfile_dispatch_reg_read_data) ); - - ctrl u_ctrl ( - .clk(clk), - .rst(rst), - .stall1(stall1), - .stallreq_from_id_1(stallreq_from_id_1), - .stallreq_from_ex_1(stallreq_from_ex_1), - .stall2(stall2), - .stallreq_from_id_2(stallreq_from_id_2), - .stallreq_from_ex_2(stallreq_from_ex_2), - .idle_stallreq(), - .excepttype_i_1(mem_excepttype_o_1), - .excepttype_i_2(mem_excepttype_o_2), - .new_pc(new_pc), - .flush(flush) + ctrl u_ctrl( + .ex_branch_flag_i (branch_flag), + .ex_mem_flush_o (ex_mem_flush) ); + + LLbit_reg u_LLbit_reg ( .clk(clk), diff --git a/src/vsrc/ctrl.sv b/src/vsrc/ctrl.sv index 79f95f1..89c4f06 100644 --- a/src/vsrc/ctrl.sv +++ b/src/vsrc/ctrl.sv @@ -1,67 +1,12 @@ `include "defines.sv" module ctrl ( - input wire clk, - input wire rst, - input wire stallreq_from_id_1, - input wire stallreq_from_ex_1, - input wire stallreq_from_id_2, - input wire stallreq_from_ex_2, + input logic [1:0] ex_branch_flag_i, - input wire idle_stallreq, - input wire has_int_stallreq, - input wire [1:0] excepttype_i_1, - input wire [1:0] excepttype_i_2, - - - output reg [6:0] stall1, - output reg [6:0] stall2, - output reg [`RegBus] new_pc, - output reg flush + output logic [1:0] ex_mem_flush_o ); - wire rst_n = ~rst; - - always @(*) begin - if (!rst_n) begin - flush = 1'b0; - new_pc = `ZeroWord; - end else if (excepttype_i_1 != 0) begin - flush = 1'b1; - case (excepttype_i_1) - 2'b01: new_pc = 32'h0000000c; - 2'b10: new_pc = 32'h0000000c; - default: begin - end - endcase - end else if (excepttype_i_2 != 0) begin - flush = 1'b1; - case (excepttype_i_2) - 2'b01: new_pc = 32'h0000000c; - 2'b10: new_pc = 32'h0000000c; - default: begin - end - endcase - end else begin - flush = 1'b0; - new_pc = `ZeroWord; - end - end - - always @(*) begin - if (!rst_n) stall1 = 7'b0000000; - else if (idle_stallreq) stall1 = 7'b1111111; - else if (stallreq_from_ex_1 == `Stop || has_int_stallreq == `Stop) stall1 = 7'b0011111; - else if (stallreq_from_id_1 == `Stop) stall1 = 7'b0011111; - else stall1 = 7'b0000000; - end - - always @(*) begin - if (!rst_n) stall2 = 7'b0000000; - else if (idle_stallreq) stall2 = 7'b1111111; - else if (stallreq_from_ex_2 == `Stop || has_int_stallreq == `Stop) stall2 = 7'b0011111; - else if (stallreq_from_id_2 == `Stop) stall2 = 7'b0011111; - else stall2 = 7'b0000000; - end + assign ex_mem_flush_o[1] = ex_branch_flag_i[0]; + assign ex_mem_flush_o[0] = 0; endmodule //ctrl diff --git a/src/vsrc/pipeline/1_decode/decoder_1RI20.sv b/src/vsrc/pipeline/1_decode/decoder_1RI20.sv index f2780fc..98d2431 100644 --- a/src/vsrc/pipeline/1_decode/decoder_1RI20.sv +++ b/src/vsrc/pipeline/1_decode/decoder_1RI20.sv @@ -55,20 +55,25 @@ module decoder_1RI20 #( reg_write_addr_o = rd; reg_read_valid_o = 2'b00; reg_read_addr_o = 10'b0; - imm_o = {imm_20,12'b0}; + imm_o = {imm_20, 12'b0}; case (instr[31:25]) `EXE_LU12I_W: begin - aluop_o = `EXE_LUI_OP; - alusel_o = `EXE_RES_MOVE; + aluop_o = `EXE_LUI_OP; + alusel_o = `EXE_RES_MOVE; end - `EXE_PCADDU12I:begin - aluop_o = `EXE_PCADD_OP; - alusel_o = `EXE_RES_MOVE; + `EXE_PCADDU12I: begin + aluop_o = `EXE_PCADD_OP; + alusel_o = `EXE_RES_MOVE; end default: begin decode_result_valid_o = 0; + reg_write_valid_o = 0; + reg_write_addr_o = 0; + reg_read_valid_o = 0; + reg_read_addr_o = 0; + imm_o = 0; end endcase end -endmodule \ No newline at end of file +endmodule diff --git a/src/vsrc/pipeline/1_decode/decoder_2RI14.sv b/src/vsrc/pipeline/1_decode/decoder_2RI14.sv index 167c898..cee2798 100644 --- a/src/vsrc/pipeline/1_decode/decoder_2RI14.sv +++ b/src/vsrc/pipeline/1_decode/decoder_2RI14.sv @@ -11,7 +11,7 @@ module decoder_2RI14 #( parameter GPR_NUM = 32, parameter ALU_OP_WIDTH = 8, parameter ALU_SEL_WIDTH = 3 -)( +) ( input instr_buffer_info_t instr_info_i, // indicates current decoder module result is valid or not @@ -59,27 +59,32 @@ module decoder_2RI14 #( reg_read_addr_o = 10'b0; imm_o = {{18{imm_14[13]}}, imm_14}; // Signed Extension case (instr[31:24]) - `EXE_LL_W:begin + `EXE_LL_W: begin aluop_o = `EXE_LL_OP; alusel_o = `EXE_RES_MOVE; reg_write_valid_o = 1; reg_write_addr_o = rd; reg_read_valid_o = 2'b01; - reg_read_addr_o = {5'b0,rj}; - end - `EXE_SC_W:begin + reg_read_addr_o = {5'b0, rj}; + end + `EXE_SC_W: begin aluop_o = `EXE_SC_OP; alusel_o = `EXE_RES_MOVE; reg_write_valid_o = 0; reg_write_addr_o = 0; reg_read_valid_o = 2'b01; - reg_read_addr_o = {5'b0,rj}; + reg_read_addr_o = {5'b0, rj}; end - default:begin + default: begin decode_result_valid_o = 0; - end + reg_write_valid_o = 0; + reg_write_addr_o = 0; + reg_read_valid_o = 0; + reg_read_addr_o = 0; + imm_o = 0; + end endcase end -endmodule \ No newline at end of file +endmodule diff --git a/src/vsrc/pipeline/1_decode/decoder_CSR.sv b/src/vsrc/pipeline/1_decode/decoder_CSR.sv index 089fca8..38af00a 100644 --- a/src/vsrc/pipeline/1_decode/decoder_CSR.sv +++ b/src/vsrc/pipeline/1_decode/decoder_CSR.sv @@ -33,7 +33,7 @@ module decoder_CSR #( // ALU info - output logic [ ALU_OP_WIDTH-1:0] aluop_o + output logic [ALU_OP_WIDTH-1:0] aluop_o ); @@ -56,29 +56,34 @@ module decoder_CSR #( reg_write_addr_o = rd; reg_read_valid_o = 2'b00; reg_read_addr_o = 10'b0; - imm_o = {18'b0,csr_num}; + imm_o = {18'b0, csr_num}; case (instr[31:24]) - `EXE_SPECIAL:begin + `EXE_SPECIAL: begin case (rj) - `EXE_CSRRD:begin + `EXE_CSRRD: begin aluop_o = `EXE_CSRRD_OP; - end - `EXE_CSRWR:begin + end + `EXE_CSRWR: begin aluop_o = `EXE_CSRWR_OP; reg_read_valid_o = 2'b01; - reg_read_addr_o = {5'b0,rd}; + reg_read_addr_o = {5'b0, rd}; end - default:begin // EXE_CSRXCHG + default: begin // EXE_CSRXCHG aluop_o = `EXE_CSRXCHG_OP; reg_read_valid_o = 2'b11; - reg_read_addr_o = {rj,rd}; - end + reg_read_addr_o = {rj, rd}; + end endcase end default: begin decode_result_valid_o = 0; + reg_write_valid_o = 0; + reg_write_addr_o = 0; + reg_read_valid_o = 0; + reg_read_addr_o = 0; + imm_o = 0; end endcase end -endmodule \ No newline at end of file +endmodule diff --git a/src/vsrc/pipeline/1_decode/decoder_I26.sv b/src/vsrc/pipeline/1_decode/decoder_I26.sv index b3e736e..e471abf 100644 --- a/src/vsrc/pipeline/1_decode/decoder_I26.sv +++ b/src/vsrc/pipeline/1_decode/decoder_I26.sv @@ -11,7 +11,7 @@ module decoder_I26 #( parameter GPR_NUM = 32, parameter ALU_OP_WIDTH = 8, parameter ALU_SEL_WIDTH = 3 -)( +) ( input instr_buffer_info_t instr_info_i, // indicates current decoder module result is valid or not @@ -41,26 +41,26 @@ module decoder_I26 #( // imm26 logic [25:0] imm_26; - assign imm_26 = {instr[9:0] ,instr[25:10]}; + assign imm_26 = {instr[9:0], instr[25:10]}; - always_comb begin + always_comb begin // Default decode decode_result_valid_o = 1; reg_write_valid_o = 0; reg_write_addr_o = 0; - imm_o = {{4{imm_26[25]}},imm_26,2'b0}; + imm_o = {{4{imm_26[25]}}, imm_26, 2'b0}; case (instr[31:26]) - `EXE_B:begin + `EXE_B: begin aluop_o = `EXE_B_OP; alusel_o = `EXE_RES_JUMP; - end - `EXE_BL:begin - aluop_o = `EXE_BL_OP; + end + `EXE_BL: begin + aluop_o = `EXE_BL_OP; alusel_o = `EXE_RES_JUMP; reg_write_valid_o = 1; reg_write_addr_o = 5'b1; end - default:begin + default: begin decode_result_valid_o = 0; aluop_o = 0; alusel_o = 0; @@ -69,4 +69,4 @@ module decoder_I26 #( endcase end -endmodule \ No newline at end of file +endmodule diff --git a/src/vsrc/pipeline/3_execution/ex.sv b/src/vsrc/pipeline/3_execution/ex.sv index eee4f09..bf31c9c 100644 --- a/src/vsrc/pipeline/3_execution/ex.sv +++ b/src/vsrc/pipeline/3_execution/ex.sv @@ -14,7 +14,7 @@ module ex ( output logic stallreq, output logic branch_flag, - output logic [`RegBus]branch_target_address, + output logic [`RegBus] branch_target_address, input logic excp_i, input logic [8:0] excp_num_i, @@ -165,46 +165,44 @@ module ex ( end always @(*) begin - if(rst == `RstEnable)begin + if (rst == `RstEnable) begin branch_flag = 1'b0; branch_target_address = `ZeroWord; end else begin - case(aluop_i) - `EXE_B_OP,`EXE_BL_OP,`EXE_JIRL_OP:begin + // Default is not branching + branch_flag = 1'b0; + branch_target_address = `ZeroWord; + case (aluop_i) + `EXE_B_OP, `EXE_BL_OP, `EXE_JIRL_OP: begin branch_flag = 1'b1; branch_target_address = inst_pc_i + reg2_i; end - `EXE_BEQ_OP:begin - if(reg1_i == reg2_i) - branch_flag = 1'b1; - branch_target_address = inst_pc_i + inst_i; + `EXE_BEQ_OP: begin + if (reg1_i == reg2_i) branch_flag = 1'b1; + branch_target_address = inst_pc_i + inst_i; end - `EXE_BNE_OP:begin - if(reg1_i != reg2_i) - branch_flag = 1'b1; - branch_target_address = inst_pc_i + {{14{inst_i[25]}}, inst_i[25:10], 2'b0}; + `EXE_BNE_OP: begin + if (reg1_i != reg2_i) branch_flag = 1'b1; + branch_target_address = inst_pc_i + {{14{inst_i[25]}}, inst_i[25:10], 2'b0}; end - `EXE_BLT_OP:begin - if(reg1_i < reg2_i) - branch_flag = 1'b1; - branch_target_address = inst_pc_i + {{14{inst_i[25]}}, inst_i[25:10], 2'b0}; + `EXE_BLT_OP: begin + if (reg1_i < reg2_i) branch_flag = 1'b1; + branch_target_address = inst_pc_i + {{14{inst_i[25]}}, inst_i[25:10], 2'b0}; end - `EXE_BGE_OP:begin - if(reg1_i >= reg2_i) + `EXE_BGE_OP: begin + if (reg1_i >= reg2_i) branch_target_address = inst_pc_i + {{14{inst_i[25]}}, inst_i[25:10], 2'b0}; end - `EXE_BLTU_OP:begin - if(reg1_i < reg2_i) - branch_flag = 1'b1; - branch_target_address = inst_pc_i + {{14{inst_i[25]}}, inst_i[25:10], 2'b0}; + `EXE_BLTU_OP: begin + if (reg1_i < reg2_i) branch_flag = 1'b1; + branch_target_address = inst_pc_i + {{14{inst_i[25]}}, inst_i[25:10], 2'b0}; end - `EXE_BGEU_OP:begin - if(reg1_i >= reg2_i) - branch_flag = 1'b1; - branch_target_address = inst_pc_i + {{14{inst_i[25]}}, inst_i[25:10], 2'b0}; + `EXE_BGEU_OP: begin + if (reg1_i >= reg2_i) branch_flag = 1'b1; + branch_target_address = inst_pc_i + {{14{inst_i[25]}}, inst_i[25:10], 2'b0}; end - default:begin - + default: begin + end endcase end @@ -230,8 +228,8 @@ module ex ( end always @(*) begin - ex_o.waddr = wd_i; - ex_o.wreg = wreg_i; + ex_o.waddr = wd_i; + ex_o.wreg = wreg_i; case (alusel_i) `EXE_RES_LOGIC: begin ex_o.wdata = logicout; diff --git a/src/vsrc/pipeline/3_execution/ex_mem.sv b/src/vsrc/pipeline/3_execution/ex_mem.sv index e6f465d..0c32e18 100644 --- a/src/vsrc/pipeline/3_execution/ex_mem.sv +++ b/src/vsrc/pipeline/3_execution/ex_mem.sv @@ -3,14 +3,16 @@ module ex_mem ( input logic clk, input logic rst, - input logic stall, input logic excp_flush, input logic ertn_flush, - input ex_mem_struct ex_o, + input ex_mem_struct ex_o, output ex_mem_struct mem_i, + // Stall & flush + input logic stall, input logic flush, + input logic [`RegBus] ex_current_inst_address, input logic excp_i, input logic [9:0] excp_num_i, From ca15ef5183fa032699f72b7cd8ad90a532ab8497 Mon Sep 17 00:00:00 2001 From: Rookie-rookie-rookie <292601787@qq.com> Date: Mon, 9 May 2022 11:56:57 +0800 Subject: [PATCH 093/114] do nothing --- src/vsrc/cpu_top.sv | 22 +++++++++------------- src/vsrc/pipeline/3_execution/ex.sv | 4 ++-- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/src/vsrc/cpu_top.sv b/src/vsrc/cpu_top.sv index 5e94baa..59ed0cf 100644 --- a/src/vsrc/cpu_top.sv +++ b/src/vsrc/cpu_top.sv @@ -500,13 +500,10 @@ module cpu_top ( logic mem_excp_o[2]; logic [15:0] mem_excp_num_o[2]; - logic data_addr_trans_en_1; - logic data_dmw0_en_1; - logic data_dmw1_en_1; + logic mem_data_addr_trans_en[2]; + logic mem_data_dmw0_en[2]; + logic mem_data_dmw1_en[2]; - logic data_addr_trans_en_2; - logic data_dmw0_en_2; - logic data_dmw1_en_2; ex_mem_struct mem_signal_i[2]; logic [1:0] ex_mem_flush; @@ -575,9 +572,9 @@ module cpu_top ( .csr_datf(csr_datf), .disable_cache(1'b0), - .data_addr_trans_en(data_addr_trans_en_2), - .dmw0_en(data_dmw0_en_2), - .dmw1_en(data_dmw1_en_2), + .data_addr_trans_en(mem_data_addr_trans_en[i]), + .dmw0_en(mem_data_dmw0_en[i]), + .dmw1_en(mem_data_dmw1_en[i]), .cacop_op_mode_di(cacop_op_mode_di), .data_tlb_found(data_tlb_found), @@ -751,10 +748,9 @@ module cpu_top ( ); - assign data_addr_trans_en = data_addr_trans_en_1 | data_addr_trans_en_2; - assign data_dmw0_en = data_dmw0_en_1 | data_dmw0_en_2; - assign data_dmw1_en = data_dmw1_en_1 | data_dmw1_en_2; - + assign data_addr_trans_en = mem_data_addr_trans_en[0] | mem_data_addr_trans_en[1]; + assign data_dmw0_en = mem_data_dmw0_en[0] | mem_data_dmw0_en[1]; + assign data_dmw1_en = mem_data_dmw1_en[0] | mem_data_dmw1_en[1]; tlb u_tlb ( .clk (clk), .asid (csr_asid), diff --git a/src/vsrc/pipeline/3_execution/ex.sv b/src/vsrc/pipeline/3_execution/ex.sv index bf31c9c..296634e 100644 --- a/src/vsrc/pipeline/3_execution/ex.sv +++ b/src/vsrc/pipeline/3_execution/ex.sv @@ -190,8 +190,8 @@ module ex ( branch_target_address = inst_pc_i + {{14{inst_i[25]}}, inst_i[25:10], 2'b0}; end `EXE_BGE_OP: begin - if (reg1_i >= reg2_i) - branch_target_address = inst_pc_i + {{14{inst_i[25]}}, inst_i[25:10], 2'b0}; + if (reg1_i >= reg2_i)branch_flag = 1'b1; + branch_target_address = inst_pc_i + {{14{inst_i[25]}}, inst_i[25:10], 2'b0}; end `EXE_BLTU_OP: begin if (reg1_i < reg2_i) branch_flag = 1'b1; From 7c3f46f6aff3668ffc576e85b52b4c49c229c6a7 Mon Sep 17 00:00:00 2001 From: Rookie-rookie-rookie <292601787@qq.com> Date: Mon, 9 May 2022 15:44:51 +0800 Subject: [PATCH 094/114] simplify mem_csr,mem_tlb signal --- src/vsrc/cpu_top.sv | 27 ++++++++++----------------- src/vsrc/pipeline/4_mem/mem.sv | 32 +++++++++++--------------------- src/vsrc/pipeline_defines.sv | 17 +++++++++++++++++ 3 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/vsrc/cpu_top.sv b/src/vsrc/cpu_top.sv index 59ed0cf..8e38c11 100644 --- a/src/vsrc/cpu_top.sv +++ b/src/vsrc/cpu_top.sv @@ -307,9 +307,9 @@ module cpu_top ( .broadcast_excp_num_o(), // <-> CSR Registers - .has_int (), + .has_int (has_int), .csr_data_i (id_csr_data[i]), - .csr_plv (), + .csr_plv (csr_plv), .csr_read_addr_o(id_csr_read_addr_o[i]) ); end @@ -352,9 +352,6 @@ module cpu_top ( logic [`RegBus] branch_target_address[2]; logic [`RegBus] link_addr; logic flush; - logic [`RegBus] new_pc; - logic [6:0] stall1; // [pc_reg,if_buffer_1, if_id, id_ex, ex_mem, mem_wb, ctrl] - logic [6:0] stall2; //tlb @@ -540,6 +537,12 @@ module cpu_top ( logic mem_wb_LLbit_we[2]; logic mem_wb_LLbit_value[2]; + csr_to_mem_struct csr_mem_signal; + tlb_to_mem_struct tlb_mem_signal; + + assign csr_mem_signal = {csr_pg,csr_da,csr_dmw0,csr_dmw1,csr_plv,csr_datf}; + assign tlb_mem_signal = {data_tlb_found,data_tlb_index,data_tlb_v,data_tlb_d,data_tlb_mat,data_tlb_plv}; + generate for (genvar i = 0; i < 2; i++) begin : mem mem u_mem ( @@ -564,12 +567,7 @@ module cpu_top ( .excp_o(mem_excp_o[i]), .excp_num_o(mem_excp_num_o[i]), - .csr_pg(csr_pg), - .csr_da(csr_da), - .csr_dmw0(csr_dmw0), - .csr_dmw1(csr_dmw1), - .csr_plv(csr_plv), - .csr_datf(csr_datf), + .csr_mem_signal(csr_mem_signal), .disable_cache(1'b0), .data_addr_trans_en(mem_data_addr_trans_en[i]), @@ -577,12 +575,7 @@ module cpu_top ( .dmw1_en(mem_data_dmw1_en[i]), .cacop_op_mode_di(cacop_op_mode_di), - .data_tlb_found(data_tlb_found), - .data_tlb_index(data_tlb_index), - .data_tlb_v(data_tlb_v), - .data_tlb_d(data_tlb_d), - .data_tlb_mat(data_tlb_mat), - .data_tlb_plv(data_tlb_plv) + .tlb_mem_signal(tlb_mem_signal) ); end diff --git a/src/vsrc/pipeline/4_mem/mem.sv b/src/vsrc/pipeline/4_mem/mem.sv index da3632a..b9d5b92 100644 --- a/src/vsrc/pipeline/4_mem/mem.sv +++ b/src/vsrc/pipeline/4_mem/mem.sv @@ -22,12 +22,7 @@ module mem ( input logic [9:0] excp_num_i, //from csr - input logic csr_pg, - input logic csr_da, - input logic [31:0] csr_dmw0, - input logic [31:0] csr_dmw1, - input logic [1:0] csr_plv, - input logic [1:0] csr_datf, + input csr_to_mem_struct csr_mem_signal, input logic disable_cache, //to addr trans @@ -37,12 +32,7 @@ module mem ( output logic cacop_op_mode_di, //tlb - input logic data_tlb_found, - input logic [4:0] data_tlb_index, - input logic data_tlb_v, - input logic data_tlb_d, - input logic [1:0] data_tlb_mat, - input logic [1:0] data_tlb_plv, + input tlb_to_mem_struct tlb_mem_signal, output reg LLbit_we_o, output reg LLbit_value_o, @@ -73,19 +63,19 @@ module mem ( //addr dmw trans - assign dmw0_en = ((csr_dmw0[`PLV0] && csr_plv == 2'd0) || (csr_dmw0[`PLV3] && csr_plv == 2'd3)) && (signal_i.wdata[31:29] == csr_dmw0[`VSEG]); - assign dmw1_en = ((csr_dmw1[`PLV0] && csr_plv == 2'd0) || (csr_dmw1[`PLV3] && csr_plv == 2'd3)) && (signal_i.wdata[31:29] == csr_dmw1[`VSEG]); + assign dmw0_en = ((csr_mem_signal.csr_dmw0[`PLV0] && csr_mem_signal.csr_plv == 2'd0) || (csr_mem_signal.csr_dmw0[`PLV3] && csr_mem_signal.csr_plv == 2'd3)) && (signal_i.wdata[31:29] == csr_mem_signal.csr_dmw0[`VSEG]); + assign dmw1_en = ((csr_mem_signal.csr_dmw1[`PLV0] && csr_mem_signal.csr_plv == 2'd0) || (csr_mem_signal.csr_dmw1[`PLV3] && csr_mem_signal.csr_plv == 2'd3)) && (signal_i.wdata[31:29] == csr_mem_signal.csr_dmw1[`VSEG]); - assign pg_mode = !csr_da && csr_pg; - assign da_mode = csr_da && !csr_pg; + assign pg_mode = !csr_mem_signal.csr_da && csr_mem_signal.csr_pg; + assign da_mode = csr_mem_signal.csr_da && !csr_mem_signal.csr_pg; assign data_addr_trans_en = pg_mode && !dmw0_en && !dmw1_en && !cacop_op_mode_di; - assign excp_tlbr = access_mem && !data_tlb_found && data_addr_trans_en; - assign excp_pil = mem_load_op && !data_tlb_v && data_addr_trans_en; //cache will generate pil exception?? - assign excp_pis = mem_store_op && !data_tlb_v && data_addr_trans_en; - assign excp_ppi = access_mem && data_tlb_v && (csr_plv > data_tlb_plv) && data_addr_trans_en; - assign excp_pme = mem_store_op && data_tlb_v && (csr_plv <= data_tlb_plv) && !data_tlb_d && data_addr_trans_en; + assign excp_tlbr = access_mem && !tlb_mem_signal.data_tlb_found && data_addr_trans_en; + assign excp_pil = mem_load_op && !tlb_mem_signal.data_tlb_v && data_addr_trans_en; //cache will generate pil exception?? + assign excp_pis = mem_store_op && !tlb_mem_signal.data_tlb_v && data_addr_trans_en; + assign excp_ppi = access_mem && tlb_mem_signal.data_tlb_v && (csr_mem_signal.csr_plv > tlb_mem_signal.data_tlb_plv) && data_addr_trans_en; + assign excp_pme = mem_store_op && tlb_mem_signal.data_tlb_v && (csr_mem_signal.csr_plv <= tlb_mem_signal.data_tlb_plv) && !tlb_mem_signal.data_tlb_d && data_addr_trans_en; assign excp_o = excp_tlbr || excp_pil || excp_pis || excp_ppi || excp_pme || excp_adem || excp_i; assign excp_num_o = {excp_pil, excp_pis, excp_ppi, excp_pme, excp_tlbr, excp_adem, excp_num_i}; diff --git a/src/vsrc/pipeline_defines.sv b/src/vsrc/pipeline_defines.sv index a099981..b0347b1 100644 --- a/src/vsrc/pipeline_defines.sv +++ b/src/vsrc/pipeline_defines.sv @@ -76,5 +76,22 @@ typedef struct packed { logic [`RegBus] wdata; } wb_reg; +typedef struct packed { + logic csr_pg; + logic csr_da; + logic [`RegBus] csr_dmw0; + logic [`RegBus] csr_dmw1; + logic [1:0] csr_plv; + logic [1:0] csr_datf; +} csr_to_mem_struct; + +typedef struct packed { + logic data_tlb_found; + logic [4:0] data_tlb_index; + logic data_tlb_v; + logic data_tlb_d; + logic [1:0] data_tlb_mat; + logic [1:0] data_tlb_plv; +} tlb_to_mem_struct; `endif From c2d6eb5fa7bb7c31debc50f17f09bbee9cd4fdbb Mon Sep 17 00:00:00 2001 From: Easton Man Date: Mon, 9 May 2022 16:49:22 +0800 Subject: [PATCH 095/114] fix: fix multiple idiotic bug --- src/vsrc/cpu_top.sv | 1 + src/vsrc/dummy_icache.sv | 7 ++++--- src/vsrc/pipeline/1_decode/decoder_1RI20.sv | 2 ++ src/vsrc/pipeline/1_decode/decoder_2RI8.sv | 23 +++++++++++++-------- src/vsrc/pipeline/2_dispatch/dispatch.sv | 13 +++++++++--- src/vsrc/pipeline_defines.sv | 4 ++-- 6 files changed, 33 insertions(+), 17 deletions(-) diff --git a/src/vsrc/cpu_top.sv b/src/vsrc/cpu_top.sv index 8e38c11..714e144 100644 --- a/src/vsrc/cpu_top.sv +++ b/src/vsrc/cpu_top.sv @@ -202,6 +202,7 @@ module cpu_top ( .rst(rst), // <-> Frontend + .flush(backend_flush), .raddr_1_i (frontend_icache_addr[0]), .raddr_2_i (frontend_icache_addr[1]), .stallreq_o(icache_frontend_stallreq), diff --git a/src/vsrc/dummy_icache.sv b/src/vsrc/dummy_icache.sv index 9cc6386..0a59147 100644 --- a/src/vsrc/dummy_icache.sv +++ b/src/vsrc/dummy_icache.sv @@ -12,6 +12,7 @@ module dummy_icache #( // <-> IF // All signals are 1 cycle valid + input flush, // all 0 means invalid input logic [ADDR_WIDTH-1:0] raddr_1_i, input logic [ADDR_WIDTH-1:0] raddr_2_i, @@ -51,7 +52,7 @@ module dummy_icache #( state, next_state; always_ff @(posedge clk or negedge rst_n) begin : state_ff - if (!rst_n) begin + if (!rst_n || flush) begin state <= ACCEPT_ADDR; end else begin state <= next_state; @@ -61,7 +62,7 @@ module dummy_icache #( always_comb begin : transition_comb case (state) ACCEPT_ADDR: begin - if (raddr_1_i != 0 || raddr_2_i != 0) begin + if ((raddr_1_i != 0 || raddr_2_i != 0) & ~axi_busy_i) begin next_state = IN_TRANSACTION_1; end else begin next_state = ACCEPT_ADDR; @@ -101,7 +102,7 @@ module dummy_icache #( end end - assign stallreq_o = ~(state == ACCEPT_ADDR); + assign stallreq_o = ~(state == ACCEPT_ADDR) | axi_busy_i; always_ff @(posedge clk or negedge rst_n) begin : axi_ff if (!rst_n) begin diff --git a/src/vsrc/pipeline/1_decode/decoder_1RI20.sv b/src/vsrc/pipeline/1_decode/decoder_1RI20.sv index 98d2431..bd2667d 100644 --- a/src/vsrc/pipeline/1_decode/decoder_1RI20.sv +++ b/src/vsrc/pipeline/1_decode/decoder_1RI20.sv @@ -51,6 +51,8 @@ module decoder_1RI20 #( always_comb begin decode_result_valid_o = 1; + aluop_o = 0; + alusel_o = 0; reg_write_valid_o = 1; reg_write_addr_o = rd; reg_read_valid_o = 2'b00; diff --git a/src/vsrc/pipeline/1_decode/decoder_2RI8.sv b/src/vsrc/pipeline/1_decode/decoder_2RI8.sv index 5f96d6f..10b7a0c 100644 --- a/src/vsrc/pipeline/1_decode/decoder_2RI8.sv +++ b/src/vsrc/pipeline/1_decode/decoder_2RI8.sv @@ -57,24 +57,29 @@ module decoder_2RI8 #( reg_write_addr_o = rd; reg_read_valid_o = 2'b01; reg_read_addr_o = {5'b0, rj}; - imm_o = {27'b0,imm_8[4:0]}; + imm_o = {27'b0, imm_8[4:0]}; case (instr[31:18]) - `EXE_SLLI_W:begin - aluop_o = `EXE_SLL_OP; + `EXE_SLLI_W: begin + aluop_o = `EXE_SLL_OP; alusel_o = `EXE_RES_SHIFT; - end - `EXE_SRLI_W:begin - aluop_o = `EXE_SRL_OP; + end + `EXE_SRLI_W: begin + aluop_o = `EXE_SRL_OP; alusel_o = `EXE_RES_SHIFT; end - `EXE_SRAI_W:begin - aluop_o = `EXE_SRA_OP; + `EXE_SRAI_W: begin + aluop_o = `EXE_SRA_OP; alusel_o = `EXE_RES_SHIFT; end default: begin decode_result_valid_o = 0; + reg_write_valid_o = 0; + reg_write_addr_o = 0; + reg_read_valid_o = 0; + reg_read_addr_o = 0; + imm_o = 0; end endcase end -endmodule \ No newline at end of file +endmodule diff --git a/src/vsrc/pipeline/2_dispatch/dispatch.sv b/src/vsrc/pipeline/2_dispatch/dispatch.sv index dfa433c..cfcfcd8 100644 --- a/src/vsrc/pipeline/2_dispatch/dispatch.sv +++ b/src/vsrc/pipeline/2_dispatch/dispatch.sv @@ -23,6 +23,16 @@ module dispatch #( logic rst_n; assign rst_n = ~rst; + generate + for (genvar i = 0; i < DECODE_WIDTH; i++) begin : reg_read_comb + always_comb begin + // Reg read + regfile_reg_read_valid_o[i] = id_i[i].reg_read_valid; + regfile_reg_read_addr_o[i] = id_i[i].reg_read_addr; + end + end + endgenerate + generate for (genvar i = 0; i < DECODE_WIDTH; i++) begin always_ff @(posedge clk or negedge rst_n) begin : dispatch_ff @@ -37,9 +47,6 @@ module dispatch #( exe_o[i].csr_we <= id_i[i].csr_we; exe_o[i].csr_signal <= id_i[i].csr_signal; - // Reg read - regfile_reg_read_valid_o[i] <= id_i[i].reg_read_valid; - regfile_reg_read_addr_o[i] <= id_i[i].reg_read_addr; exe_o[i].oprand1 <= regfile_reg_read_data_i[i][0]; exe_o[i].oprand2 <= id_i[i].use_imm ? id_i[i].imm : regfile_reg_read_data_i[i][1]; end diff --git a/src/vsrc/pipeline_defines.sv b/src/vsrc/pipeline_defines.sv index b0347b1..dadc852 100644 --- a/src/vsrc/pipeline_defines.sv +++ b/src/vsrc/pipeline_defines.sv @@ -44,11 +44,11 @@ typedef struct packed { logic wreg; logic [`RegAddrBus] waddr; - logic [`RegBus] wdata; logic [`AluOpBus] aluop; logic [`RegBus] mem_addr; logic [`RegBus] reg2; csr_write_signal csr_signal; + logic [`RegBus] wdata; } ex_mem_struct; typedef struct packed { @@ -66,7 +66,7 @@ typedef struct packed { logic ce; logic [3:0] sel; logic [`DataAddrBus] addr; - logic [`RegBus]data; + logic [`RegBus] data; } mem_axi_struct; typedef struct packed { From a526972a4e6a3c1791c68e3644e3bab4d2235e1e Mon Sep 17 00:00:00 2001 From: Easton Man Date: Mon, 9 May 2022 17:27:39 +0800 Subject: [PATCH 096/114] fix: fix multiple idiotic bug --- src/vsrc/cpu_top.sv | 17 +++++++++++------ src/vsrc/pipeline/1_decode/decoder_2RI12.sv | 12 ++++++++++-- src/vsrc/pipeline/3_execution/ex.sv | 4 ++-- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/vsrc/cpu_top.sv b/src/vsrc/cpu_top.sv index 714e144..31bd902 100644 --- a/src/vsrc/cpu_top.sv +++ b/src/vsrc/cpu_top.sv @@ -815,12 +815,17 @@ module cpu_top ( debug_commit_pc_delay1 <= debug_commit_pc; debug_commit_valid_delay1 <= debug_commit_valid; end - assign debug0_wb_pc = debug_commit_pc[0]; - assign debug0_wb_rf_wen = 1; - assign debug0_wb_rf_wdata = 0; - assign debug0_wb_rf_wnum = 0; - assign debug1_wb_pc = debug_commit_pc[1]; - assign debug1_wb_rf_wen = 1; + + always_ff @(posedge clk) begin + debug0_wb_pc <= wb_reg_signal[0].pc; + debug0_wb_rf_wen <= {3'b0,wb_reg_signal[0].we}; + debug0_wb_rf_wdata <= wb_reg_signal[0].wdata; + debug0_wb_rf_wnum <= wb_reg_signal[0].waddr; + debug1_wb_pc <= wb_reg_signal[1].pc; + debug1_wb_rf_wen <= {3'b0, wb_reg_signal[1].we}; + debug1_wb_rf_wdata <= wb_reg_signal[1].wdata; + debug1_wb_rf_wnum <= wb_reg_signal[1].waddr; + end // difftest dpi-c `ifdef SIMU // simu is defined in chiplab run_func/makefile DifftestInstrCommit difftest_instr_commit_0 ( // todo: not finished yet, blank signal is needed diff --git a/src/vsrc/pipeline/1_decode/decoder_2RI12.sv b/src/vsrc/pipeline/1_decode/decoder_2RI12.sv index 19f08d6..8cdaf1b 100644 --- a/src/vsrc/pipeline/1_decode/decoder_2RI12.sv +++ b/src/vsrc/pipeline/1_decode/decoder_2RI12.sv @@ -35,7 +35,7 @@ module decoder_2RI12 #( // ALU info output logic [ ALU_OP_WIDTH-1:0] aluop_o, output logic [ALU_SEL_WIDTH-1:0] alusel_o - + ); logic [DATA_WIDTH-1:0] instr; @@ -105,16 +105,22 @@ module decoder_2RI12 #( imm_o = {{20{imm_12[11]}}, imm_12}; // Signed Extension end `EXE_ST_B: begin + reg_write_valid_o = 0; + reg_write_addr_o = 0; aluop_o = `EXE_ST_B_OP; alusel_o = `EXE_RES_LOAD_STORE; imm_o = {{20{imm_12[11]}}, imm_12}; // Signed Extension end `EXE_ST_H: begin + reg_write_valid_o = 0; + reg_write_addr_o = 0; aluop_o = `EXE_ST_H_OP; alusel_o = `EXE_RES_LOAD_STORE; imm_o = {{20{imm_12[11]}}, imm_12}; // Signed Extension end `EXE_ST_W: begin + reg_write_valid_o = 0; + reg_write_addr_o = 0; aluop_o = `EXE_ST_W_OP; alusel_o = `EXE_RES_LOAD_STORE; imm_o = {{20{imm_12[11]}}, imm_12}; // Signed Extension @@ -130,7 +136,9 @@ module decoder_2RI12 #( imm_o = {{20{imm_12[11]}}, imm_12}; // Signed Extension end `EXE_PRELD: begin - aluop_o = `EXE_NOP_OP; + reg_write_valid_o = 0; + reg_write_addr_o = 0; + aluop_o = `EXE_NOP_OP; alusel_o = `EXE_RES_NOP; end default: begin diff --git a/src/vsrc/pipeline/3_execution/ex.sv b/src/vsrc/pipeline/3_execution/ex.sv index 296634e..317664c 100644 --- a/src/vsrc/pipeline/3_execution/ex.sv +++ b/src/vsrc/pipeline/3_execution/ex.sv @@ -190,7 +190,7 @@ module ex ( branch_target_address = inst_pc_i + {{14{inst_i[25]}}, inst_i[25:10], 2'b0}; end `EXE_BGE_OP: begin - if (reg1_i >= reg2_i)branch_flag = 1'b1; + if (reg1_i >= reg2_i) branch_flag = 1'b1; branch_target_address = inst_pc_i + {{14{inst_i[25]}}, inst_i[25:10], 2'b0}; end `EXE_BLTU_OP: begin @@ -244,7 +244,7 @@ module ex ( ex_o.wdata = arithout; end `EXE_RES_JUMP: begin - ex_o.wdata = 0; // FIXME: add link addr + ex_o.wdata = inst_pc_i + 4; end default: begin ex_o.wdata = `ZeroWord; From a3ce8784a0c76c6194aa7c417b8d7517f7151421 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Mon, 9 May 2022 19:40:52 +0800 Subject: [PATCH 097/114] fix: fix instr not passed --- src/vsrc/pipeline/3_execution/ex.sv | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/vsrc/pipeline/3_execution/ex.sv b/src/vsrc/pipeline/3_execution/ex.sv index 317664c..3e50f81 100644 --- a/src/vsrc/pipeline/3_execution/ex.sv +++ b/src/vsrc/pipeline/3_execution/ex.sv @@ -66,8 +66,7 @@ module ex ( if (rst == `RstEnable) begin logicout = `ZeroWord; end else begin - ex_o.instr_info.pc = inst_pc_i; - ex_o.instr_info.valid = inst_valid_i; + ex_o.instr_info = dispatch_i.instr_info; case (aluop_i) `EXE_OR_OP: begin logicout = reg1_i | reg2_i; From 3e75973d3bcd208866750c6eb0eb59584c126402 Mon Sep 17 00:00:00 2001 From: Rookie-rookie-rookie <292601787@qq.com> Date: Mon, 9 May 2022 20:01:01 +0800 Subject: [PATCH 098/114] fix imm error --- src/vsrc/pipeline/2_dispatch/dispatch.sv | 3 ++- src/vsrc/pipeline/3_execution/ex.sv | 17 +++++++++-------- src/vsrc/pipeline_defines.sv | 1 + 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/vsrc/pipeline/2_dispatch/dispatch.sv b/src/vsrc/pipeline/2_dispatch/dispatch.sv index cfcfcd8..1204e49 100644 --- a/src/vsrc/pipeline/2_dispatch/dispatch.sv +++ b/src/vsrc/pipeline/2_dispatch/dispatch.sv @@ -48,7 +48,8 @@ module dispatch #( exe_o[i].csr_signal <= id_i[i].csr_signal; exe_o[i].oprand1 <= regfile_reg_read_data_i[i][0]; - exe_o[i].oprand2 <= id_i[i].use_imm ? id_i[i].imm : regfile_reg_read_data_i[i][1]; + exe_o[i].oprand2 <= regfile_reg_read_data_i[i][1]; + exe_o[i].imm <= id_i[i].imm; end end endgenerate diff --git a/src/vsrc/pipeline/3_execution/ex.sv b/src/vsrc/pipeline/3_execution/ex.sv index 3e50f81..ce15d27 100644 --- a/src/vsrc/pipeline/3_execution/ex.sv +++ b/src/vsrc/pipeline/3_execution/ex.sv @@ -33,9 +33,10 @@ module ex ( assign aluop_i = dispatch_i.aluop; assign alusel_i = dispatch_i.alusel; - logic [`RegBus] reg1_i, reg2_i; + logic [`RegBus] reg1_i, reg2_i, imm; assign reg1_i = dispatch_i.oprand1; assign reg2_i = dispatch_i.oprand2; + assign imm = dispatch_i.imm; logic [`RegBus] inst_i, inst_pc_i; assign inst_i = dispatch_i.instr_info.instr; @@ -174,31 +175,31 @@ module ex ( case (aluop_i) `EXE_B_OP, `EXE_BL_OP, `EXE_JIRL_OP: begin branch_flag = 1'b1; - branch_target_address = inst_pc_i + reg2_i; + branch_target_address = inst_pc_i + imm; end `EXE_BEQ_OP: begin if (reg1_i == reg2_i) branch_flag = 1'b1; - branch_target_address = inst_pc_i + inst_i; + branch_target_address = inst_pc_i + imm; end `EXE_BNE_OP: begin if (reg1_i != reg2_i) branch_flag = 1'b1; - branch_target_address = inst_pc_i + {{14{inst_i[25]}}, inst_i[25:10], 2'b0}; + branch_target_address = inst_pc_i + imm; end `EXE_BLT_OP: begin if (reg1_i < reg2_i) branch_flag = 1'b1; - branch_target_address = inst_pc_i + {{14{inst_i[25]}}, inst_i[25:10], 2'b0}; + branch_target_address = inst_pc_i + imm; end `EXE_BGE_OP: begin if (reg1_i >= reg2_i) branch_flag = 1'b1; - branch_target_address = inst_pc_i + {{14{inst_i[25]}}, inst_i[25:10], 2'b0}; + branch_target_address = inst_pc_i + imm; end `EXE_BLTU_OP: begin if (reg1_i < reg2_i) branch_flag = 1'b1; - branch_target_address = inst_pc_i + {{14{inst_i[25]}}, inst_i[25:10], 2'b0}; + branch_target_address = inst_pc_i + imm; end `EXE_BGEU_OP: begin if (reg1_i >= reg2_i) branch_flag = 1'b1; - branch_target_address = inst_pc_i + {{14{inst_i[25]}}, inst_i[25:10], 2'b0}; + branch_target_address = inst_pc_i + imm; end default: begin diff --git a/src/vsrc/pipeline_defines.sv b/src/vsrc/pipeline_defines.sv index dadc852..f578c9c 100644 --- a/src/vsrc/pipeline_defines.sv +++ b/src/vsrc/pipeline_defines.sv @@ -30,6 +30,7 @@ typedef struct packed { logic [`InstBus] instr; logic [`RegBus] oprand1; logic [`RegBus] oprand2; + logic [`RegBus] imm; logic [`AluOpBus] aluop; logic [`AluSelBus] alusel; logic [`RegAddrBus] reg_write_addr; From f33d62ca14adad89a132802b3cd672c9c1c5a96d Mon Sep 17 00:00:00 2001 From: Rookie-rookie-rookie <292601787@qq.com> Date: Mon, 9 May 2022 20:53:14 +0800 Subject: [PATCH 099/114] fix reg2_o error --- src/vsrc/pipeline/2_dispatch/dispatch.sv | 8 +++++++- src/vsrc/pipeline/3_execution/ex.sv | 12 ++++++------ src/vsrc/pipeline_defines.sv | 1 + 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/vsrc/pipeline/2_dispatch/dispatch.sv b/src/vsrc/pipeline/2_dispatch/dispatch.sv index 1204e49..d8fec09 100644 --- a/src/vsrc/pipeline/2_dispatch/dispatch.sv +++ b/src/vsrc/pipeline/2_dispatch/dispatch.sv @@ -48,8 +48,14 @@ module dispatch #( exe_o[i].csr_signal <= id_i[i].csr_signal; exe_o[i].oprand1 <= regfile_reg_read_data_i[i][0]; - exe_o[i].oprand2 <= regfile_reg_read_data_i[i][1]; + exe_o[i].oprand2 <= id_i[i].use_imm? id_i[i].imm : regfile_reg_read_data_i[i][1]; exe_o[i].imm <= id_i[i].imm; + exe_o[i].branch_com_result[0] <= regfile_reg_read_data_i[i][0] == regfile_reg_read_data_i[i][1]; + exe_o[i].branch_com_result[1] <= regfile_reg_read_data_i[i][0] != regfile_reg_read_data_i[i][1]; + exe_o[i].branch_com_result[2] <= ({~regfile_reg_read_data_i[i][0][31],regfile_reg_read_data_i[i][0][30:0]} < {~regfile_reg_read_data_i[i][0][31],regfile_reg_read_data_i[i][1][30:0]}); + exe_o[i].branch_com_result[3] <= ({~regfile_reg_read_data_i[i][0][31],regfile_reg_read_data_i[i][0][30:0]} >= {~regfile_reg_read_data_i[i][0][31],regfile_reg_read_data_i[i][1][30:0]}); + exe_o[i].branch_com_result[4] <= regfile_reg_read_data_i[i][0] < regfile_reg_read_data_i[i][1]; + exe_o[i].branch_com_result[5] <= regfile_reg_read_data_i[i][0] >= regfile_reg_read_data_i[i][1]; end end endgenerate diff --git a/src/vsrc/pipeline/3_execution/ex.sv b/src/vsrc/pipeline/3_execution/ex.sv index ce15d27..9bb48f7 100644 --- a/src/vsrc/pipeline/3_execution/ex.sv +++ b/src/vsrc/pipeline/3_execution/ex.sv @@ -178,27 +178,27 @@ module ex ( branch_target_address = inst_pc_i + imm; end `EXE_BEQ_OP: begin - if (reg1_i == reg2_i) branch_flag = 1'b1; + if (dispatch_i.branch_com_result[0]) branch_flag = 1'b1; branch_target_address = inst_pc_i + imm; end `EXE_BNE_OP: begin - if (reg1_i != reg2_i) branch_flag = 1'b1; + if (dispatch_i.branch_com_result[1]) branch_flag = 1'b1; branch_target_address = inst_pc_i + imm; end `EXE_BLT_OP: begin - if (reg1_i < reg2_i) branch_flag = 1'b1; + if (dispatch_i.branch_com_result[2]) branch_flag = 1'b1; branch_target_address = inst_pc_i + imm; end `EXE_BGE_OP: begin - if (reg1_i >= reg2_i) branch_flag = 1'b1; + if (dispatch_i.branch_com_result[3]) branch_flag = 1'b1; branch_target_address = inst_pc_i + imm; end `EXE_BLTU_OP: begin - if (reg1_i < reg2_i) branch_flag = 1'b1; + if (dispatch_i.branch_com_result[4]) branch_flag = 1'b1; branch_target_address = inst_pc_i + imm; end `EXE_BGEU_OP: begin - if (reg1_i >= reg2_i) branch_flag = 1'b1; + if (dispatch_i.branch_com_result[5]) branch_flag = 1'b1; branch_target_address = inst_pc_i + imm; end default: begin diff --git a/src/vsrc/pipeline_defines.sv b/src/vsrc/pipeline_defines.sv index f578c9c..730e1d9 100644 --- a/src/vsrc/pipeline_defines.sv +++ b/src/vsrc/pipeline_defines.sv @@ -35,6 +35,7 @@ typedef struct packed { logic [`AluSelBus] alusel; logic [`RegAddrBus] reg_write_addr; logic reg_write_valid; + logic [5:0] branch_com_result; logic csr_we; csr_write_signal csr_signal; From 1332fdedefad5303dcb5d15fe9ec70c8c981d804 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Mon, 9 May 2022 21:54:10 +0800 Subject: [PATCH 100/114] fix: fix decoder-3R latch --- src/vsrc/pipeline/1_decode/decoder_2RI8.sv | 2 ++ src/vsrc/pipeline/1_decode/decoder_3R.sv | 3 +++ src/vsrc/pipeline/2_dispatch/dispatch.sv | 2 +- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vsrc/pipeline/1_decode/decoder_2RI8.sv b/src/vsrc/pipeline/1_decode/decoder_2RI8.sv index 10b7a0c..32634c4 100644 --- a/src/vsrc/pipeline/1_decode/decoder_2RI8.sv +++ b/src/vsrc/pipeline/1_decode/decoder_2RI8.sv @@ -73,6 +73,8 @@ module decoder_2RI8 #( end default: begin decode_result_valid_o = 0; + aluop_o = 0; + alusel_o = 0; reg_write_valid_o = 0; reg_write_addr_o = 0; reg_read_valid_o = 0; diff --git a/src/vsrc/pipeline/1_decode/decoder_3R.sv b/src/vsrc/pipeline/1_decode/decoder_3R.sv index 71ecaed..39f4b1b 100644 --- a/src/vsrc/pipeline/1_decode/decoder_3R.sv +++ b/src/vsrc/pipeline/1_decode/decoder_3R.sv @@ -57,6 +57,9 @@ module decoder_3R #( reg_read_addr_o = {rj, rk}; instr_break = 0; instr_syscall = 0; + // Default + aluop_o = `EXE_NOP_OP; + alusel_o = `EXE_RES_NOP; case (instr[31:15]) // These two do not need GPR `EXE_BREAK: begin diff --git a/src/vsrc/pipeline/2_dispatch/dispatch.sv b/src/vsrc/pipeline/2_dispatch/dispatch.sv index d8fec09..4d5b16d 100644 --- a/src/vsrc/pipeline/2_dispatch/dispatch.sv +++ b/src/vsrc/pipeline/2_dispatch/dispatch.sv @@ -48,7 +48,7 @@ module dispatch #( exe_o[i].csr_signal <= id_i[i].csr_signal; exe_o[i].oprand1 <= regfile_reg_read_data_i[i][0]; - exe_o[i].oprand2 <= id_i[i].use_imm? id_i[i].imm : regfile_reg_read_data_i[i][1]; + exe_o[i].oprand2 <= id_i[i].use_imm ? id_i[i].imm : regfile_reg_read_data_i[i][1]; exe_o[i].imm <= id_i[i].imm; exe_o[i].branch_com_result[0] <= regfile_reg_read_data_i[i][0] == regfile_reg_read_data_i[i][1]; exe_o[i].branch_com_result[1] <= regfile_reg_read_data_i[i][0] != regfile_reg_read_data_i[i][1]; From 1131e22916233241b574e9817f7332d6abd4f915 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Mon, 9 May 2022 22:03:18 +0800 Subject: [PATCH 101/114] fix: fix jirl addr cal --- src/vsrc/pipeline/3_execution/ex.sv | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/vsrc/pipeline/3_execution/ex.sv b/src/vsrc/pipeline/3_execution/ex.sv index 9bb48f7..20ea700 100644 --- a/src/vsrc/pipeline/3_execution/ex.sv +++ b/src/vsrc/pipeline/3_execution/ex.sv @@ -173,10 +173,14 @@ module ex ( branch_flag = 1'b0; branch_target_address = `ZeroWord; case (aluop_i) - `EXE_B_OP, `EXE_BL_OP, `EXE_JIRL_OP: begin + `EXE_B_OP, `EXE_BL_OP: begin branch_flag = 1'b1; branch_target_address = inst_pc_i + imm; end + `EXE_JIRL_OP: begin + branch_flag = 1'b1; + branch_target_address = reg1_i + imm; + end `EXE_BEQ_OP: begin if (dispatch_i.branch_com_result[0]) branch_flag = 1'b1; branch_target_address = inst_pc_i + imm; From 0ee543600e4c352dc9f2df3312a825d4ec6e8fb1 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Tue, 10 May 2022 09:14:38 +0800 Subject: [PATCH 102/114] fix: fix ambiguious clk --- src/vsrc/cpu_top.sv | 18 +++++----- src/vsrc/pipeline/2_dispatch/dispatch.sv | 42 +++++++++++++----------- 2 files changed, 33 insertions(+), 27 deletions(-) diff --git a/src/vsrc/cpu_top.sv b/src/vsrc/cpu_top.sv index 31bd902..9e46460 100644 --- a/src/vsrc/cpu_top.sv +++ b/src/vsrc/cpu_top.sv @@ -69,16 +69,16 @@ module cpu_top ( input bvalid, output bready, // debug info - output [31:0] debug0_wb_pc, - output [ 3:0] debug0_wb_rf_wen, - output [ 4:0] debug0_wb_rf_wnum, - output [31:0] debug0_wb_rf_wdata + output logic [31:0] debug0_wb_pc, + output logic [ 3:0] debug0_wb_rf_wen, + output logic [ 4:0] debug0_wb_rf_wnum, + output logic [31:0] debug0_wb_rf_wdata `ifdef CPU_2CMT , - output [31:0] debug1_wb_pc, - output [ 3:0] debug1_wb_rf_wen, - output [ 4:0] debug1_wb_rf_wnum, - output [31:0] debug1_wb_rf_wdata + output logic [31:0] debug1_wb_pc, + output logic [ 3:0] debug1_wb_rf_wen, + output logic [ 4:0] debug1_wb_rf_wnum, + output logic [31:0] debug1_wb_rf_wdata `endif ); @@ -821,10 +821,12 @@ module cpu_top ( debug0_wb_rf_wen <= {3'b0,wb_reg_signal[0].we}; debug0_wb_rf_wdata <= wb_reg_signal[0].wdata; debug0_wb_rf_wnum <= wb_reg_signal[0].waddr; + `ifdef CPU_2CMT debug1_wb_pc <= wb_reg_signal[1].pc; debug1_wb_rf_wen <= {3'b0, wb_reg_signal[1].we}; debug1_wb_rf_wdata <= wb_reg_signal[1].wdata; debug1_wb_rf_wnum <= wb_reg_signal[1].waddr; + `endif end // difftest dpi-c `ifdef SIMU // simu is defined in chiplab run_func/makefile diff --git a/src/vsrc/pipeline/2_dispatch/dispatch.sv b/src/vsrc/pipeline/2_dispatch/dispatch.sv index 4d5b16d..31a1a80 100644 --- a/src/vsrc/pipeline/2_dispatch/dispatch.sv +++ b/src/vsrc/pipeline/2_dispatch/dispatch.sv @@ -36,26 +36,30 @@ module dispatch #( generate for (genvar i = 0; i < DECODE_WIDTH; i++) begin always_ff @(posedge clk or negedge rst_n) begin : dispatch_ff + if (!rst_n) begin + exe_o <= 0; + end else begin - // Pass through to EXE - // TODO: add dispatch logic - exe_o[i].instr_info <= id_i[i].instr_info; - exe_o[i].aluop <= id_i[i].aluop; - exe_o[i].alusel <= id_i[i].alusel; - exe_o[i].reg_write_addr <= id_i[i].reg_write_addr; - exe_o[i].reg_write_valid <= id_i[i].reg_write_valid; - exe_o[i].csr_we <= id_i[i].csr_we; - exe_o[i].csr_signal <= id_i[i].csr_signal; - - exe_o[i].oprand1 <= regfile_reg_read_data_i[i][0]; - exe_o[i].oprand2 <= id_i[i].use_imm ? id_i[i].imm : regfile_reg_read_data_i[i][1]; - exe_o[i].imm <= id_i[i].imm; - exe_o[i].branch_com_result[0] <= regfile_reg_read_data_i[i][0] == regfile_reg_read_data_i[i][1]; - exe_o[i].branch_com_result[1] <= regfile_reg_read_data_i[i][0] != regfile_reg_read_data_i[i][1]; - exe_o[i].branch_com_result[2] <= ({~regfile_reg_read_data_i[i][0][31],regfile_reg_read_data_i[i][0][30:0]} < {~regfile_reg_read_data_i[i][0][31],regfile_reg_read_data_i[i][1][30:0]}); - exe_o[i].branch_com_result[3] <= ({~regfile_reg_read_data_i[i][0][31],regfile_reg_read_data_i[i][0][30:0]} >= {~regfile_reg_read_data_i[i][0][31],regfile_reg_read_data_i[i][1][30:0]}); - exe_o[i].branch_com_result[4] <= regfile_reg_read_data_i[i][0] < regfile_reg_read_data_i[i][1]; - exe_o[i].branch_com_result[5] <= regfile_reg_read_data_i[i][0] >= regfile_reg_read_data_i[i][1]; + // Pass through to EXE + // TODO: add dispatch logic + exe_o[i].instr_info <= id_i[i].instr_info; + exe_o[i].aluop <= id_i[i].aluop; + exe_o[i].alusel <= id_i[i].alusel; + exe_o[i].reg_write_addr <= id_i[i].reg_write_addr; + exe_o[i].reg_write_valid <= id_i[i].reg_write_valid; + exe_o[i].csr_we <= id_i[i].csr_we; + exe_o[i].csr_signal <= id_i[i].csr_signal; + + exe_o[i].oprand1 <= regfile_reg_read_data_i[i][0]; + exe_o[i].oprand2 <= id_i[i].use_imm ? id_i[i].imm : regfile_reg_read_data_i[i][1]; + exe_o[i].imm <= id_i[i].imm; + exe_o[i].branch_com_result[0] <= regfile_reg_read_data_i[i][0] == regfile_reg_read_data_i[i][1]; + exe_o[i].branch_com_result[1] <= regfile_reg_read_data_i[i][0] != regfile_reg_read_data_i[i][1]; + exe_o[i].branch_com_result[2] <= ({~regfile_reg_read_data_i[i][0][31],regfile_reg_read_data_i[i][0][30:0]} < {~regfile_reg_read_data_i[i][0][31],regfile_reg_read_data_i[i][1][30:0]}); + exe_o[i].branch_com_result[3] <= ({~regfile_reg_read_data_i[i][0][31],regfile_reg_read_data_i[i][0][30:0]} >= {~regfile_reg_read_data_i[i][0][31],regfile_reg_read_data_i[i][1][30:0]}); + exe_o[i].branch_com_result[4] <= regfile_reg_read_data_i[i][0] < regfile_reg_read_data_i[i][1]; + exe_o[i].branch_com_result[5] <= regfile_reg_read_data_i[i][0] >= regfile_reg_read_data_i[i][1]; + end end end endgenerate From 5d57b971a3e45f48921854369a3910c00f999032 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Tue, 10 May 2022 10:20:08 +0800 Subject: [PATCH 103/114] fix: fix multiple latch issue --- src/vsrc/cs_reg.sv | 29 +++++++++++---------- src/vsrc/dummy_icache.sv | 7 ++++- src/vsrc/pipeline/1_decode/decoder_2RI14.sv | 2 ++ src/vsrc/pipeline/1_decode/decoder_3R.sv | 2 +- src/vsrc/pipeline/1_decode/decoder_CSR.sv | 1 + src/vsrc/pipeline/2_dispatch/dispatch.sv | 2 +- src/vsrc/pipeline/3_execution/ex.sv | 12 ++++----- 7 files changed, 32 insertions(+), 23 deletions(-) diff --git a/src/vsrc/cs_reg.sv b/src/vsrc/cs_reg.sv index e3c6f08..2554bdf 100644 --- a/src/vsrc/cs_reg.sv +++ b/src/vsrc/cs_reg.sv @@ -548,21 +548,22 @@ module cs_reg ( if (rst) csr_ticlr <= 32'b0; end + // Comment out to resolve multi-driven issue //llbitc - always @(posedge clk) begin - if (rst) begin - csr_llbctl[`KLO] <= 1'b0; - csr_llbctl[31:3] <= 29'b0; - llbit <= 1'b0; - end else if (ertn_flush) begin - if (csr_llbctl[`KLO]) csr_llbctl[`KLO] <= 1'b0; - else llbit <= 1'b0; - end else if (we == 1'b1 && waddr == `LLBCTL) begin - csr_llbctl[`KLO] <= wdata[`KLO]; - if (wdata[`WCLLB] == 1'b1) llbit <= 1'b0; - end else if (llbit_set_i) llbit <= llbit_i; - - end + // always @(posedge clk) begin + // if (rst) begin + // csr_llbctl[`KLO] <= 1'b0; + // csr_llbctl[31:3] <= 29'b0; + // llbit <= 1'b0; + // end else if (ertn_flush) begin + // if (csr_llbctl[`KLO]) csr_llbctl[`KLO] <= 1'b0; + // else llbit <= 1'b0; + // end else if (we == 1'b1 && waddr == `LLBCTL) begin + // csr_llbctl[`KLO] <= wdata[`KLO]; + // if (wdata[`WCLLB] == 1'b1) llbit <= 1'b0; + // end else if (llbit_set_i) llbit <= llbit_i; + + // end diff --git a/src/vsrc/dummy_icache.sv b/src/vsrc/dummy_icache.sv index 0a59147..58008c3 100644 --- a/src/vsrc/dummy_icache.sv +++ b/src/vsrc/dummy_icache.sv @@ -82,6 +82,9 @@ module dummy_icache #( next_state = IN_TRANSACTION_2; end end + default: begin + next_state = ACCEPT_ADDR; + end endcase end @@ -108,7 +111,6 @@ module dummy_icache #( if (!rst_n) begin axi_addr_o <= 0; end else begin - axi_addr_o <= 0; case (state) ACCEPT_ADDR: begin if (raddr_1_i != 0 && axi_busy_i == 0) axi_addr_o <= raddr_1_i; @@ -119,6 +121,9 @@ module dummy_icache #( IN_TRANSACTION_2: begin axi_addr_o <= 0; end + default: begin + axi_addr_o <= 0; + end endcase end end diff --git a/src/vsrc/pipeline/1_decode/decoder_2RI14.sv b/src/vsrc/pipeline/1_decode/decoder_2RI14.sv index cee2798..0aadee1 100644 --- a/src/vsrc/pipeline/1_decode/decoder_2RI14.sv +++ b/src/vsrc/pipeline/1_decode/decoder_2RI14.sv @@ -77,6 +77,8 @@ module decoder_2RI14 #( end default: begin decode_result_valid_o = 0; + aluop_o = `EXE_NOP_OP; + alusel_o = `EXE_RES_NOP; reg_write_valid_o = 0; reg_write_addr_o = 0; reg_read_valid_o = 0; diff --git a/src/vsrc/pipeline/1_decode/decoder_3R.sv b/src/vsrc/pipeline/1_decode/decoder_3R.sv index 39f4b1b..3d184b0 100644 --- a/src/vsrc/pipeline/1_decode/decoder_3R.sv +++ b/src/vsrc/pipeline/1_decode/decoder_3R.sv @@ -69,7 +69,7 @@ module decoder_3R #( reg_read_addr_o = 0; instr_break = 1; end - `EXE_BREAK: begin + `EXE_SYSCALL: begin reg_write_valid_o = 0; reg_write_addr_o = 0; reg_read_valid_o = 2'b00; diff --git a/src/vsrc/pipeline/1_decode/decoder_CSR.sv b/src/vsrc/pipeline/1_decode/decoder_CSR.sv index 38af00a..512dbc8 100644 --- a/src/vsrc/pipeline/1_decode/decoder_CSR.sv +++ b/src/vsrc/pipeline/1_decode/decoder_CSR.sv @@ -77,6 +77,7 @@ module decoder_CSR #( end default: begin decode_result_valid_o = 0; + aluop_o = `EXE_NOP_OP; reg_write_valid_o = 0; reg_write_addr_o = 0; reg_read_valid_o = 0; diff --git a/src/vsrc/pipeline/2_dispatch/dispatch.sv b/src/vsrc/pipeline/2_dispatch/dispatch.sv index 31a1a80..311c888 100644 --- a/src/vsrc/pipeline/2_dispatch/dispatch.sv +++ b/src/vsrc/pipeline/2_dispatch/dispatch.sv @@ -37,7 +37,7 @@ module dispatch #( for (genvar i = 0; i < DECODE_WIDTH; i++) begin always_ff @(posedge clk or negedge rst_n) begin : dispatch_ff if (!rst_n) begin - exe_o <= 0; + exe_o[i] <= 0; // end else begin // Pass through to EXE diff --git a/src/vsrc/pipeline/3_execution/ex.sv b/src/vsrc/pipeline/3_execution/ex.sv index 20ea700..24657c1 100644 --- a/src/vsrc/pipeline/3_execution/ex.sv +++ b/src/vsrc/pipeline/3_execution/ex.sv @@ -67,7 +67,6 @@ module ex ( if (rst == `RstEnable) begin logicout = `ZeroWord; end else begin - ex_o.instr_info = dispatch_i.instr_info; case (aluop_i) `EXE_OR_OP: begin logicout = reg1_i | reg2_i; @@ -82,6 +81,7 @@ module ex ( logicout = ~(reg1_i | reg2_i); end default: begin + logicout = `ZeroWord; end endcase end @@ -91,8 +91,6 @@ module ex ( if (rst == `RstEnable) begin shiftout = `ZeroWord; end else begin - // inst_pc_o = inst_pc_i; - // inst_valid_o = inst_valid_i; case (aluop_i) `EXE_SLL_OP: begin shiftout = reg1_i << reg2_i[4:0]; @@ -104,6 +102,7 @@ module ex ( shiftout = ({32{reg1_i[31]}} << (6'd32-{1'b0,reg2_i[4:0]})) | reg1_i >> reg2_i[4:0]; end default: begin + shiftout = `ZeroWord; end endcase end @@ -148,8 +147,6 @@ module ex ( if (rst == `RstEnable) begin arithout = `ZeroWord; end else begin - // inst_pc_o = inst_pc_i; - // inst_valid_o = inst_valid_i; case (aluop_i) `EXE_ADD_OP: arithout = reg1_i + reg2_i; `EXE_SUB_OP: arithout = reg1_i - reg2_i; @@ -159,6 +156,7 @@ module ex ( `EXE_MOD_OP: arithout = reg1_i % reg2_i; `EXE_SLT_OP, `EXE_SLTU_OP: arithout = {31'b0, reg1_lt_reg2}; default: begin + arithout = `ZeroWord; end endcase end @@ -226,14 +224,16 @@ module ex ( moveout = reg2_i + ex_o.instr_info.pc; end default: begin + moveout = `ZeroWord; end endcase end end always @(*) begin + ex_o.instr_info = dispatch_i.instr_info; ex_o.waddr = wd_i; - ex_o.wreg = wreg_i; + ex_o.wreg = wreg_i; case (alusel_i) `EXE_RES_LOGIC: begin ex_o.wdata = logicout; From 5e4e437cf81b409f5d445cd4091166987ed3b056 Mon Sep 17 00:00:00 2001 From: Rookie-rookie-rookie <292601787@qq.com> Date: Tue, 10 May 2022 12:37:31 +0800 Subject: [PATCH 104/114] fix data relate with bug --- src/vsrc/cpu_top.sv | 40 +++++++++++++----------- src/vsrc/ctrl.sv | 1 + src/vsrc/pipeline/1_decode/id.sv | 28 ++++++----------- src/vsrc/pipeline/2_dispatch/dispatch.sv | 25 +++++++++++++-- src/vsrc/pipeline/3_execution/ex.sv | 4 +++ src/vsrc/pipeline/4_mem/mem.sv | 4 +++ src/vsrc/pipeline_defines.sv | 13 ++++++++ 7 files changed, 75 insertions(+), 40 deletions(-) diff --git a/src/vsrc/cpu_top.sv b/src/vsrc/cpu_top.sv index 9e46460..36760f4 100644 --- a/src/vsrc/cpu_top.sv +++ b/src/vsrc/cpu_top.sv @@ -250,6 +250,7 @@ module cpu_top ( ); instr_buffer_info_t ib_backend_instr_info[2]; // IB -> ID + logic [5:0] stall; // Instruction Buffer // FIFO buffer @@ -265,7 +266,7 @@ module cpu_top ( .frontend_stallreq_o(ib_frontend_stallreq), // <-> Backend - .backend_accept_i({id_id_dispatch[1].instr_info.valid, id_id_dispatch[0].instr_info.valid}), // FIXME: does not carefully designed + .backend_accept_i({id_id_dispatch[1].instr_info.valid, id_id_dispatch[0].instr_info.valid} & {stall[0],stall[0]}), // FIXME: does not carefully designed .backend_flush_i(backend_flush), // Assure output is reset the next cycle .backend_instr_o(ib_backend_instr_info) // -> ID ); @@ -281,25 +282,12 @@ module cpu_top ( // ID Stage generate for (genvar i = 0; i < 2; i++) begin : id - id #( - .EXE_STAGE_WIDTH(2), // Obviously 2 for now - .MEM_STAGE_WIDTH(2) - ) u_id ( + id u_id ( .instr_buffer_i(ib_backend_instr_info[i]), // FIXME: excp info, currently unused .excp_i (), .excp_num_i (), - // Data forwarding network, unused for now - // TODO: add data forwarding network - .ex_write_reg_valid_i (), - .ex_write_reg_addr_i (), - .ex_write_reg_data_i (), - .ex_aluop_i (), - .mem_write_reg_valid_i(), - .mem_write_reg_addr_i (), - .mem_write_reg_data_i (), - // -> Dispatch .dispatch_o(id_id_dispatch[i]), @@ -323,7 +311,7 @@ module cpu_top ( id_dispatch u_id_dispatch ( .clk (clk), .rst (rst), - .stall (), + .stall (stall[1]), .flush (backend_flush), // FIXME: does not carefully designed .id_i (id_id_dispatch), .dispatch_o(id_dispatch_dispatch) @@ -332,14 +320,24 @@ module cpu_top ( // Dispatch -> EXE dispatch_ex_struct [1:0] dispatch_exe; + // + ex_dispatch_struct ex_data_forward[2]; + mem_dispatch_struct mem_data_forward[2]; + // Dispatch Stage, Sequential logic dispatch #( - .DECODE_WIDTH(2) + .DECODE_WIDTH(2), + .EXE_STAGE_WIDTH(2), + .MEM_STAGE_WIDTH(2) ) u_dispatch ( .clk (clk), .rst (rst), .id_i(id_dispatch_dispatch), + //Data forwarding + .ex_data_forward(ex_data_forward), + .mem_data_forward(mem_data_forward), + // <-> Regfile .regfile_reg_read_valid_o(dispatch_regfile_reg_read_valid), .regfile_reg_read_addr_o (dispatch_regfile_reg_read_addr), @@ -481,6 +479,8 @@ module cpu_top ( .branch_flag(branch_flag[i]), .branch_target_address(branch_target_address[i]), + .ex_data_forward(ex_data_forward[i]), + .excp_i(ex_excp_i[i]), .excp_num_i(ex_excp_num_i[i]), .excp_o(ex_excp_o[i]), @@ -517,7 +517,7 @@ module cpu_top ( .mem_i(mem_signal_i[i]), // <-> Ctrl - .stall(), + .stall(stall[2]), .flush(ex_mem_flush[i]), .ex_current_inst_address(), @@ -571,6 +571,8 @@ module cpu_top ( .csr_mem_signal(csr_mem_signal), .disable_cache(1'b0), + .mem_data_forward(mem_data_forward[i]), + .data_addr_trans_en(mem_data_addr_trans_en[i]), .dmw0_en(mem_data_dmw0_en[i]), .dmw1_en(mem_data_dmw1_en[i]), @@ -602,7 +604,7 @@ module cpu_top ( mem_wb u_mem_wb ( .clk (clk), .rst (rst), - .stall(), + .stall(stall[3]), .mem_signal_o(mem_signal_o[i]), diff --git a/src/vsrc/ctrl.sv b/src/vsrc/ctrl.sv index 89c4f06..82f2032 100644 --- a/src/vsrc/ctrl.sv +++ b/src/vsrc/ctrl.sv @@ -2,6 +2,7 @@ module ctrl ( input logic [1:0] ex_branch_flag_i, + output logic [5:0] stall, output logic [1:0] ex_mem_flush_o ); diff --git a/src/vsrc/pipeline/1_decode/id.sv b/src/vsrc/pipeline/1_decode/id.sv index cfeeb3c..5a59db4 100644 --- a/src/vsrc/pipeline/1_decode/id.sv +++ b/src/vsrc/pipeline/1_decode/id.sv @@ -25,30 +25,13 @@ // 2. Calculate anything, such as branch target // TODO: move regfile read to dispatch stage // -module id #( - parameter EXE_STAGE_WIDTH = 2, - parameter MEM_STAGE_WIDTH = 2 -) ( +module id ( // <- Instruction Buffer input instr_buffer_info_t instr_buffer_i, input logic excp_i, input logic [3:0] excp_num_i, - // <- EXE - // Data forwarding - input logic ex_write_reg_valid_i[EXE_STAGE_WIDTH], - input logic [`RegAddrBus] ex_write_reg_addr_i[EXE_STAGE_WIDTH], - input logic [`RegBus] ex_write_reg_data_i[EXE_STAGE_WIDTH], - input logic [`AluOpBus] ex_aluop_i[EXE_STAGE_WIDTH], - - // <- Mem - // Data forwarding - input logic mem_write_reg_valid_i[MEM_STAGE_WIDTH], - input logic [`RegAddrBus] mem_write_reg_addr_i[MEM_STAGE_WIDTH], - input logic [`RegBus] mem_write_reg_data_i[MEM_STAGE_WIDTH], - - // -> Dispatch output id_dispatch_struct dispatch_o, @@ -239,6 +222,15 @@ module id #( excp_ipe, excp_ine, instr_break, instr_syscall, excp_num_i, has_int }; + //logic pre_load; + //assign pre_load = ((ex_aluop_i == `EXE_LB_OP) ||(ex_aluop_i == `EXE_LBU_OP)||(ex_aluop_i == `EXE_LH_OP) || + // (ex_aluop_i == `EXE_LHU_OP)|| + // (ex_aluop_i == `EXE_LW_OP) || + // (ex_aluop_i == `EXE_LWR_OP)|| + // (ex_aluop_i == `EXE_LWL_OP)|| + // (ex_aluop_i == `EXE_LL_OP) || + // (ex_aluop_i == `EXE_SC_OP)) ? 1'b1 : 1'b0; + // TODO: ex_op generate rules not implemented yet diff --git a/src/vsrc/pipeline/2_dispatch/dispatch.sv b/src/vsrc/pipeline/2_dispatch/dispatch.sv index 311c888..faa82b2 100644 --- a/src/vsrc/pipeline/2_dispatch/dispatch.sv +++ b/src/vsrc/pipeline/2_dispatch/dispatch.sv @@ -2,7 +2,9 @@ `include "pipeline_defines.sv" module dispatch #( - parameter DECODE_WIDTH = 2 + parameter DECODE_WIDTH = 2, + parameter EXE_STAGE_WIDTH = 2, + parameter MEM_STAGE_WIDTH = 2 ) ( input logic clk, input logic rst, @@ -15,6 +17,14 @@ module dispatch #( output logic [DECODE_WIDTH-1:0][`RegNumLog2*2-1:0] regfile_reg_read_addr_o, // Read addr, {reg2, reg1} input logic [DECODE_WIDTH-1:0][1:0][`RegBus] regfile_reg_read_data_i, // Read result + // <- EXE + // Data forwarding + input ex_dispatch_struct ex_data_forward[EXE_STAGE_WIDTH], + + // <- Mem + // Data forwarding + input mem_dispatch_struct mem_data_forward[MEM_STAGE_WIDTH], + // Dispatch Port output dispatch_ex_struct [DECODE_WIDTH-1:0] exe_o ); @@ -33,6 +43,17 @@ module dispatch #( end endgenerate + //data relate + generate + for (genvar i = 0; i < DECODE_WIDTH; i++) begin : data_relate + always_comb begin + // Reg read + exe_o[i].oprand1 = regfile_reg_read_data_i[i][0]; + exe_o[i].oprand2 = id_i[i].use_imm ? id_i[i].imm : regfile_reg_read_data_i[i][1]; + end + end + endgenerate + generate for (genvar i = 0; i < DECODE_WIDTH; i++) begin always_ff @(posedge clk or negedge rst_n) begin : dispatch_ff @@ -50,8 +71,6 @@ module dispatch #( exe_o[i].csr_we <= id_i[i].csr_we; exe_o[i].csr_signal <= id_i[i].csr_signal; - exe_o[i].oprand1 <= regfile_reg_read_data_i[i][0]; - exe_o[i].oprand2 <= id_i[i].use_imm ? id_i[i].imm : regfile_reg_read_data_i[i][1]; exe_o[i].imm <= id_i[i].imm; exe_o[i].branch_com_result[0] <= regfile_reg_read_data_i[i][0] == regfile_reg_read_data_i[i][1]; exe_o[i].branch_com_result[1] <= regfile_reg_read_data_i[i][0] != regfile_reg_read_data_i[i][1]; diff --git a/src/vsrc/pipeline/3_execution/ex.sv b/src/vsrc/pipeline/3_execution/ex.sv index 24657c1..33e3764 100644 --- a/src/vsrc/pipeline/3_execution/ex.sv +++ b/src/vsrc/pipeline/3_execution/ex.sv @@ -16,6 +16,8 @@ module ex ( output logic branch_flag, output logic [`RegBus] branch_target_address, + output ex_dispatch_struct ex_data_forward, + input logic excp_i, input logic [8:0] excp_num_i, output logic excp_o, @@ -53,6 +55,8 @@ module ex ( assign ex_o.mem_addr = reg1_i + {{20{inst_i[21]}}, inst_i[21:10]}; assign ex_o.reg2 = reg2_i; + assign ex_data_forward = {ex_o.wreg,ex_o.waddr,ex_o.wdata,ex_o.aluop}; + csr_write_signal csr_signal_i; assign csr_signal_i = dispatch_i.csr_signal; //写入csr的数据,对csrxchg指令进行掩码处理 diff --git a/src/vsrc/pipeline/4_mem/mem.sv b/src/vsrc/pipeline/4_mem/mem.sv index b9d5b92..0e71d29 100644 --- a/src/vsrc/pipeline/4_mem/mem.sv +++ b/src/vsrc/pipeline/4_mem/mem.sv @@ -25,6 +25,8 @@ module mem ( input csr_to_mem_struct csr_mem_signal, input logic disable_cache, + output mem_dispatch_struct mem_data_forward, + //to addr trans output logic data_addr_trans_en, output logic dmw0_en, @@ -71,6 +73,8 @@ module mem ( assign data_addr_trans_en = pg_mode && !dmw0_en && !dmw1_en && !cacop_op_mode_di; + assign mem_data_forward = {signal_o.wreg,signal_o.waddr,signal_o.wdata}; + assign excp_tlbr = access_mem && !tlb_mem_signal.data_tlb_found && data_addr_trans_en; assign excp_pil = mem_load_op && !tlb_mem_signal.data_tlb_v && data_addr_trans_en; //cache will generate pil exception?? assign excp_pis = mem_store_op && !tlb_mem_signal.data_tlb_v && data_addr_trans_en; diff --git a/src/vsrc/pipeline_defines.sv b/src/vsrc/pipeline_defines.sv index 730e1d9..d7411c6 100644 --- a/src/vsrc/pipeline_defines.sv +++ b/src/vsrc/pipeline_defines.sv @@ -41,6 +41,13 @@ typedef struct packed { csr_write_signal csr_signal; } dispatch_ex_struct; +typedef struct packed { + logic reg_valid; + logic [`RegAddrBus] reg_addr; + logic [`RegBus] reg_data; + logic [`AluOpBus] aluop_i; +} ex_dispatch_struct; + typedef struct packed { instr_buffer_info_t instr_info; @@ -53,6 +60,12 @@ typedef struct packed { logic [`RegBus] wdata; } ex_mem_struct; +typedef struct packed { + logic reg_valid; + logic [`RegAddrBus] reg_addr; + logic [`RegBus] reg_data; +} mem_dispatch_struct; + typedef struct packed { instr_buffer_info_t instr_info; From 7c1a0f77675e96ff7136e84719b75bc2f57de555 Mon Sep 17 00:00:00 2001 From: Rookie-rookie-rookie <292601787@qq.com> Date: Tue, 10 May 2022 16:03:10 +0800 Subject: [PATCH 105/114] fix data relate and stall with error --- src/vsrc/cpu_top.sv | 12 +++- src/vsrc/ctrl.sv | 14 ++++- src/vsrc/pipeline/1_decode/id.sv | 8 --- src/vsrc/pipeline/2_dispatch/dispatch.sv | 73 ++++++++++++++++++++++-- 4 files changed, 90 insertions(+), 17 deletions(-) diff --git a/src/vsrc/cpu_top.sv b/src/vsrc/cpu_top.sv index 36760f4..351eb9e 100644 --- a/src/vsrc/cpu_top.sv +++ b/src/vsrc/cpu_top.sv @@ -266,7 +266,7 @@ module cpu_top ( .frontend_stallreq_o(ib_frontend_stallreq), // <-> Backend - .backend_accept_i({id_id_dispatch[1].instr_info.valid, id_id_dispatch[0].instr_info.valid} & {stall[0],stall[0]}), // FIXME: does not carefully designed + .backend_accept_i({id_id_dispatch[1].instr_info.valid, id_id_dispatch[0].instr_info.valid} & {~stall[0],~stall[0]}), // FIXME: does not carefully designed .backend_flush_i(backend_flush), // Assure output is reset the next cycle .backend_instr_o(ib_backend_instr_info) // -> ID ); @@ -320,10 +320,13 @@ module cpu_top ( // Dispatch -> EXE dispatch_ex_struct [1:0] dispatch_exe; - // + //data relate ex_dispatch_struct ex_data_forward[2]; mem_dispatch_struct mem_data_forward[2]; + //load relate + logic stallreg_from_dispatch; + // Dispatch Stage, Sequential logic dispatch #( .DECODE_WIDTH(2), @@ -343,6 +346,8 @@ module cpu_top ( .regfile_reg_read_addr_o (dispatch_regfile_reg_read_addr), .regfile_reg_read_data_i (regfile_dispatch_reg_read_data), + .stallreg_from_dispatch(stallreg_from_dispatch), + // -> EXE .exe_o(dispatch_exe) ); @@ -667,6 +672,9 @@ module cpu_top ( ctrl u_ctrl( .ex_branch_flag_i (branch_flag), + .stallreg_from_dispatch(stallreg_from_dispatch), + + .stall(), .ex_mem_flush_o (ex_mem_flush) ); diff --git a/src/vsrc/ctrl.sv b/src/vsrc/ctrl.sv index 82f2032..98916e7 100644 --- a/src/vsrc/ctrl.sv +++ b/src/vsrc/ctrl.sv @@ -1,13 +1,25 @@ `include "defines.sv" module ctrl ( + input logic rst, + input logic [1:0] ex_branch_flag_i, + input logic stallreg_from_dispatch, + input logic excp_i, + input logic [15:0] excp_num_i, + - output logic [5:0] stall, + output logic [3:0] stall, output logic [1:0] ex_mem_flush_o ); assign ex_mem_flush_o[1] = ex_branch_flag_i[0]; assign ex_mem_flush_o[0] = 0; + always_comb begin + if(rst) + stall = 4'b0000; + else if(stallreg_from_dispatch) + stall = 4'b1100; + end endmodule //ctrl diff --git a/src/vsrc/pipeline/1_decode/id.sv b/src/vsrc/pipeline/1_decode/id.sv index 5a59db4..7c521c9 100644 --- a/src/vsrc/pipeline/1_decode/id.sv +++ b/src/vsrc/pipeline/1_decode/id.sv @@ -222,14 +222,6 @@ module id ( excp_ipe, excp_ine, instr_break, instr_syscall, excp_num_i, has_int }; - //logic pre_load; - //assign pre_load = ((ex_aluop_i == `EXE_LB_OP) ||(ex_aluop_i == `EXE_LBU_OP)||(ex_aluop_i == `EXE_LH_OP) || - // (ex_aluop_i == `EXE_LHU_OP)|| - // (ex_aluop_i == `EXE_LW_OP) || - // (ex_aluop_i == `EXE_LWR_OP)|| - // (ex_aluop_i == `EXE_LWL_OP)|| - // (ex_aluop_i == `EXE_LL_OP) || - // (ex_aluop_i == `EXE_SC_OP)) ? 1'b1 : 1'b0; // TODO: ex_op generate rules not implemented yet diff --git a/src/vsrc/pipeline/2_dispatch/dispatch.sv b/src/vsrc/pipeline/2_dispatch/dispatch.sv index faa82b2..007ea3f 100644 --- a/src/vsrc/pipeline/2_dispatch/dispatch.sv +++ b/src/vsrc/pipeline/2_dispatch/dispatch.sv @@ -25,6 +25,10 @@ module dispatch #( // Data forwarding input mem_dispatch_struct mem_data_forward[MEM_STAGE_WIDTH], + //<- Ctrl + //request for stall + output logic stallreg_from_dispatch, + // Dispatch Port output dispatch_ex_struct [DECODE_WIDTH-1:0] exe_o ); @@ -33,6 +37,28 @@ module dispatch #( logic rst_n; assign rst_n = ~rst; + //Load relate + logic pre_load; + assign pre_load = ((ex_data_forward[1].aluop_i == `EXE_LD_B_OP) ||(ex_data_forward[1].aluop_i == `EXE_LD_H_OP)|| + (ex_data_forward[1].aluop_i == `EXE_LD_W_OP) ||(ex_data_forward[1].aluop_i == `EXE_ST_B_OP)|| + (ex_data_forward[1].aluop_i == `EXE_ST_H_OP) ||(ex_data_forward[1].aluop_i == `EXE_ST_W_OP)|| + (ex_data_forward[1].aluop_i == `EXE_LD_BU_OP)||(ex_data_forward[1].aluop_i == `EXE_LD_HU_OP) || + (ex_data_forward[1].aluop_i == `EXE_LL_OP) ||(ex_data_forward[1].aluop_i == `EXE_SC_OP)) || + ((ex_data_forward[0].aluop_i == `EXE_LD_B_OP) ||(ex_data_forward[0].aluop_i == `EXE_LD_H_OP)|| + (ex_data_forward[0].aluop_i == `EXE_LD_W_OP) ||(ex_data_forward[0].aluop_i == `EXE_ST_B_OP)|| + (ex_data_forward[0].aluop_i == `EXE_ST_H_OP) ||(ex_data_forward[0].aluop_i == `EXE_ST_W_OP)|| + (ex_data_forward[0].aluop_i == `EXE_LD_BU_OP)||(ex_data_forward[0].aluop_i == `EXE_LD_HU_OP) || + (ex_data_forward[0].aluop_i == `EXE_LL_OP) ||(ex_data_forward[0].aluop_i == `EXE_SC_OP))? 1'b1 : 1'b0; + + + always_comb begin + if(rst) + stallreg_from_dispatch = `NoStop; + else if(pre_load) + stallreg_from_dispatch = `Stop; + end + + generate for (genvar i = 0; i < DECODE_WIDTH; i++) begin : reg_read_comb always_comb begin @@ -44,15 +70,48 @@ module dispatch #( endgenerate //data relate + logic [`RegBus] oprand1,oprand2; + + generate + for (genvar i = 0; i < DECODE_WIDTH; i++) + always_comb begin + if (!rst_n) begin + oprand1 = 0; // + end else begin + if(ex_data_forward[1].reg_valid == `WriteEnable && ex_data_forward[1].reg_addr == regfile_reg_read_addr_o[i][4:0]) + oprand1 = ex_data_forward[1].reg_data; + else if(ex_data_forward[0].reg_valid == `WriteEnable && ex_data_forward[1].reg_addr == regfile_reg_read_addr_o[i][4:0]) + oprand1 = ex_data_forward[0].reg_data; + else if(mem_data_forward[1].reg_valid == `WriteEnable && mem_data_forward[1].reg_addr == regfile_reg_read_addr_o[i][4:0]) + oprand1 = mem_data_forward[1].reg_data; + else if(mem_data_forward[0].reg_valid == `WriteEnable && mem_data_forward[1].reg_addr == regfile_reg_read_addr_o[i][4:0]) + oprand1 = mem_data_forward[0].reg_data; + else + oprand1 = regfile_reg_read_data_i[i][0]; + end + end + endgenerate + generate - for (genvar i = 0; i < DECODE_WIDTH; i++) begin : data_relate - always_comb begin - // Reg read - exe_o[i].oprand1 = regfile_reg_read_data_i[i][0]; - exe_o[i].oprand2 = id_i[i].use_imm ? id_i[i].imm : regfile_reg_read_data_i[i][1]; + for (genvar i = 0; i < DECODE_WIDTH; i++) begin + always_comb begin + if (!rst_n) begin + oprand2 = 0; // + end else begin + if(ex_data_forward[1].reg_valid == `WriteEnable && ex_data_forward[1].reg_addr == regfile_reg_read_addr_o[i][4:0]) + oprand2 = ex_data_forward[1].reg_data; + else if(ex_data_forward[0].reg_valid == `WriteEnable && ex_data_forward[1].reg_addr == regfile_reg_read_addr_o[i][4:0]) + oprand2 = ex_data_forward[0].reg_data; + else if(mem_data_forward[1].reg_valid == `WriteEnable && mem_data_forward[1].reg_addr == regfile_reg_read_addr_o[i][4:0]) + oprand2 = mem_data_forward[1].reg_data; + else if(mem_data_forward[0].reg_valid == `WriteEnable && mem_data_forward[1].reg_addr == regfile_reg_read_addr_o[i][4:0]) + oprand2 = mem_data_forward[0].reg_data; + else + oprand2 = id_i[i].use_imm ? id_i[i].imm : regfile_reg_read_data_i[i][1]; + end end end - endgenerate + endgenerate generate for (genvar i = 0; i < DECODE_WIDTH; i++) begin @@ -70,6 +129,8 @@ module dispatch #( exe_o[i].reg_write_valid <= id_i[i].reg_write_valid; exe_o[i].csr_we <= id_i[i].csr_we; exe_o[i].csr_signal <= id_i[i].csr_signal; + exe_o[i].oprand1 <= oprand1; + exe_o[i].oprand2 <= oprand2; exe_o[i].imm <= id_i[i].imm; exe_o[i].branch_com_result[0] <= regfile_reg_read_data_i[i][0] == regfile_reg_read_data_i[i][1]; From 6c4db0f65ddcb8e109af61f614d36b1d470f1d55 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Tue, 10 May 2022 16:37:43 +0800 Subject: [PATCH 106/114] fix: fix op gen in dispatch --- src/vsrc/pipeline/2_dispatch/dispatch.sv | 78 +++++++++++------------- 1 file changed, 36 insertions(+), 42 deletions(-) diff --git a/src/vsrc/pipeline/2_dispatch/dispatch.sv b/src/vsrc/pipeline/2_dispatch/dispatch.sv index 007ea3f..7f8fccf 100644 --- a/src/vsrc/pipeline/2_dispatch/dispatch.sv +++ b/src/vsrc/pipeline/2_dispatch/dispatch.sv @@ -14,7 +14,7 @@ module dispatch #( // <-> Regfile output logic [DECODE_WIDTH-1:0][1:0] regfile_reg_read_valid_o, // Read valid for 2 regs - output logic [DECODE_WIDTH-1:0][`RegNumLog2*2-1:0] regfile_reg_read_addr_o, // Read addr, {reg2, reg1} + output logic [DECODE_WIDTH-1:0][1:0][`RegAddrBus] regfile_reg_read_addr_o, // Read addr, {reg2, reg1} input logic [DECODE_WIDTH-1:0][1:0][`RegBus] regfile_reg_read_data_i, // Read result // <- EXE @@ -52,72 +52,66 @@ module dispatch #( always_comb begin - if(rst) - stallreg_from_dispatch = `NoStop; - else if(pre_load) - stallreg_from_dispatch = `Stop; + if (rst) stallreg_from_dispatch = `NoStop; + else if (pre_load) stallreg_from_dispatch = `Stop; end + // Reg read, -> Regfile generate for (genvar i = 0; i < DECODE_WIDTH; i++) begin : reg_read_comb always_comb begin - // Reg read regfile_reg_read_valid_o[i] = id_i[i].reg_read_valid; regfile_reg_read_addr_o[i] = id_i[i].reg_read_addr; end end endgenerate - //data relate - logic [`RegBus] oprand1,oprand2; + // Data dependecies + logic [1:0][`RegBus] oprand1, oprand2; - generate - for (genvar i = 0; i < DECODE_WIDTH; i++) - always_comb begin - if (!rst_n) begin - oprand1 = 0; // - end else begin - if(ex_data_forward[1].reg_valid == `WriteEnable && ex_data_forward[1].reg_addr == regfile_reg_read_addr_o[i][4:0]) - oprand1 = ex_data_forward[1].reg_data; - else if(ex_data_forward[0].reg_valid == `WriteEnable && ex_data_forward[1].reg_addr == regfile_reg_read_addr_o[i][4:0]) - oprand1 = ex_data_forward[0].reg_data; - else if(mem_data_forward[1].reg_valid == `WriteEnable && mem_data_forward[1].reg_addr == regfile_reg_read_addr_o[i][4:0]) - oprand1 = mem_data_forward[1].reg_data; - else if(mem_data_forward[0].reg_valid == `WriteEnable && mem_data_forward[1].reg_addr == regfile_reg_read_addr_o[i][4:0]) - oprand1 = mem_data_forward[0].reg_data; - else - oprand1 = regfile_reg_read_data_i[i][0]; + generate + for (genvar i = 0; i < DECODE_WIDTH; i++) begin + always_comb begin + begin + if(ex_data_forward[1].reg_valid == `WriteEnable && ex_data_forward[1].reg_addr == regfile_reg_read_addr_o[i][0] && id_i[i].reg_read_valid[0]) + oprand1[i] = ex_data_forward[1].reg_data; + else if(ex_data_forward[0].reg_valid == `WriteEnable && ex_data_forward[1].reg_addr == regfile_reg_read_addr_o[i][0] && id_i[i].reg_read_valid[0]) + oprand1[i] = ex_data_forward[0].reg_data; + else if(mem_data_forward[1].reg_valid == `WriteEnable && mem_data_forward[1].reg_addr == regfile_reg_read_addr_o[i][0] && id_i[i].reg_read_valid[0]) + oprand1[i] = mem_data_forward[1].reg_data; + else if(mem_data_forward[0].reg_valid == `WriteEnable && mem_data_forward[1].reg_addr == regfile_reg_read_addr_o[i][0] && id_i[i].reg_read_valid[0]) + oprand1[i] = mem_data_forward[0].reg_data; + else oprand1[i] = regfile_reg_read_data_i[i][0]; end end + end endgenerate generate for (genvar i = 0; i < DECODE_WIDTH; i++) begin - always_comb begin - if (!rst_n) begin - oprand2 = 0; // - end else begin - if(ex_data_forward[1].reg_valid == `WriteEnable && ex_data_forward[1].reg_addr == regfile_reg_read_addr_o[i][4:0]) - oprand2 = ex_data_forward[1].reg_data; - else if(ex_data_forward[0].reg_valid == `WriteEnable && ex_data_forward[1].reg_addr == regfile_reg_read_addr_o[i][4:0]) - oprand2 = ex_data_forward[0].reg_data; - else if(mem_data_forward[1].reg_valid == `WriteEnable && mem_data_forward[1].reg_addr == regfile_reg_read_addr_o[i][4:0]) - oprand2 = mem_data_forward[1].reg_data; - else if(mem_data_forward[0].reg_valid == `WriteEnable && mem_data_forward[1].reg_addr == regfile_reg_read_addr_o[i][4:0]) - oprand2 = mem_data_forward[0].reg_data; - else - oprand2 = id_i[i].use_imm ? id_i[i].imm : regfile_reg_read_data_i[i][1]; + always_comb begin + begin + if (id_i[i].use_imm) oprand2[i] = id_i[i].imm; + else if(ex_data_forward[1].reg_valid == `WriteEnable && ex_data_forward[1].reg_addr == regfile_reg_read_addr_o[i][1] && id_i[i].reg_read_valid[1]) + oprand2[i] = ex_data_forward[1].reg_data; + else if(ex_data_forward[0].reg_valid == `WriteEnable && ex_data_forward[1].reg_addr == regfile_reg_read_addr_o[i][1] && id_i[i].reg_read_valid[1]) + oprand2[i] = ex_data_forward[0].reg_data; + else if(mem_data_forward[1].reg_valid == `WriteEnable && mem_data_forward[1].reg_addr == regfile_reg_read_addr_o[i][1] && id_i[i].reg_read_valid[1]) + oprand2[i] = mem_data_forward[1].reg_data; + else if(mem_data_forward[0].reg_valid == `WriteEnable && mem_data_forward[1].reg_addr == regfile_reg_read_addr_o[i][1] && id_i[i].reg_read_valid[1]) + oprand2[i] = mem_data_forward[0].reg_data; + else oprand2[i] = regfile_reg_read_data_i[i][1]; end end end - endgenerate + endgenerate generate for (genvar i = 0; i < DECODE_WIDTH; i++) begin always_ff @(posedge clk or negedge rst_n) begin : dispatch_ff if (!rst_n) begin - exe_o[i] <= 0; // + exe_o[i] <= 0; // end else begin // Pass through to EXE @@ -129,8 +123,8 @@ module dispatch #( exe_o[i].reg_write_valid <= id_i[i].reg_write_valid; exe_o[i].csr_we <= id_i[i].csr_we; exe_o[i].csr_signal <= id_i[i].csr_signal; - exe_o[i].oprand1 <= oprand1; - exe_o[i].oprand2 <= oprand2; + exe_o[i].oprand1 <= oprand1[i]; + exe_o[i].oprand2 <= oprand2[i]; exe_o[i].imm <= id_i[i].imm; exe_o[i].branch_com_result[0] <= regfile_reg_read_data_i[i][0] == regfile_reg_read_data_i[i][1]; From 93e914ec30eb3ab764af6ec073b9f86933d9e1e5 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Tue, 10 May 2022 17:22:05 +0800 Subject: [PATCH 107/114] fix: fix data dep --- src/vsrc/cpu_top.sv | 9 ++--- src/vsrc/instr_buffer.sv | 5 +-- src/vsrc/pipeline/2_dispatch/dispatch.sv | 46 ++++++++++++------------ src/vsrc/pipeline_defines.sv | 2 +- 4 files changed, 32 insertions(+), 30 deletions(-) diff --git a/src/vsrc/cpu_top.sv b/src/vsrc/cpu_top.sv index 351eb9e..f7bc346 100644 --- a/src/vsrc/cpu_top.sv +++ b/src/vsrc/cpu_top.sv @@ -252,6 +252,8 @@ module cpu_top ( instr_buffer_info_t ib_backend_instr_info[2]; // IB -> ID logic [5:0] stall; + logic [1:0] dispatch_ib_accept; + // Instruction Buffer // FIFO buffer instr_buffer #( @@ -266,7 +268,7 @@ module cpu_top ( .frontend_stallreq_o(ib_frontend_stallreq), // <-> Backend - .backend_accept_i({id_id_dispatch[1].instr_info.valid, id_id_dispatch[0].instr_info.valid} & {~stall[0],~stall[0]}), // FIXME: does not carefully designed + .backend_accept_i(dispatch_ib_accept), // FIXME: does not carefully designed .backend_flush_i(backend_flush), // Assure output is reset the next cycle .backend_instr_o(ib_backend_instr_info) // -> ID ); @@ -324,8 +326,6 @@ module cpu_top ( ex_dispatch_struct ex_data_forward[2]; mem_dispatch_struct mem_data_forward[2]; - //load relate - logic stallreg_from_dispatch; // Dispatch Stage, Sequential logic dispatch #( @@ -346,7 +346,8 @@ module cpu_top ( .regfile_reg_read_addr_o (dispatch_regfile_reg_read_addr), .regfile_reg_read_data_i (regfile_dispatch_reg_read_data), - .stallreg_from_dispatch(stallreg_from_dispatch), + // -> IB + .ib_accept_o(dispatch_ib_accept), // -> EXE .exe_o(dispatch_exe) diff --git a/src/vsrc/instr_buffer.sv b/src/vsrc/instr_buffer.sv index 59e1792..6a079c2 100644 --- a/src/vsrc/instr_buffer.sv +++ b/src/vsrc/instr_buffer.sv @@ -13,7 +13,7 @@ module instr_buffer #( output logic frontend_stallreq_o, // Require frontend to stop // <-> Backend - input logic [ID_WIDTH-1:0] backend_accept_i, // Backend can accept 0 or more instructions, must return in current cycle! + input logic [ID_WIDTH-1:0] backend_accept_i, // Backend can accept 0 or more instructions, must return in the next cycle! input logic backend_flush_i, // Backend require flush, maybe branch miss output instr_buffer_info_t backend_instr_o[ID_WIDTH] @@ -98,9 +98,10 @@ module instr_buffer #( // Connect backend_instr_o directly to buffer_queue // FIXME: may introduce large latency + // OPTIM: may have better ways always_comb begin : backend_instr_o_comb for (integer i = 0; i < ID_WIDTH; i++) begin - backend_instr_o[i] = buffer_queue[read_ptr+i]; + backend_instr_o[i] = buffer_queue[read_ptr+i+backend_accept_num]; end end diff --git a/src/vsrc/pipeline/2_dispatch/dispatch.sv b/src/vsrc/pipeline/2_dispatch/dispatch.sv index 7f8fccf..c1f7a7e 100644 --- a/src/vsrc/pipeline/2_dispatch/dispatch.sv +++ b/src/vsrc/pipeline/2_dispatch/dispatch.sv @@ -25,9 +25,8 @@ module dispatch #( // Data forwarding input mem_dispatch_struct mem_data_forward[MEM_STAGE_WIDTH], - //<- Ctrl - //request for stall - output logic stallreg_from_dispatch, + // -> Instruction Buffer + output logic [DECODE_WIDTH-1:0] ib_accept_o, // Dispatch Port output dispatch_ex_struct [DECODE_WIDTH-1:0] exe_o @@ -37,26 +36,25 @@ module dispatch #( logic rst_n; assign rst_n = ~rst; - //Load relate - logic pre_load; - assign pre_load = ((ex_data_forward[1].aluop_i == `EXE_LD_B_OP) ||(ex_data_forward[1].aluop_i == `EXE_LD_H_OP)|| - (ex_data_forward[1].aluop_i == `EXE_LD_W_OP) ||(ex_data_forward[1].aluop_i == `EXE_ST_B_OP)|| - (ex_data_forward[1].aluop_i == `EXE_ST_H_OP) ||(ex_data_forward[1].aluop_i == `EXE_ST_W_OP)|| - (ex_data_forward[1].aluop_i == `EXE_LD_BU_OP)||(ex_data_forward[1].aluop_i == `EXE_LD_HU_OP) || - (ex_data_forward[1].aluop_i == `EXE_LL_OP) ||(ex_data_forward[1].aluop_i == `EXE_SC_OP)) || - ((ex_data_forward[0].aluop_i == `EXE_LD_B_OP) ||(ex_data_forward[0].aluop_i == `EXE_LD_H_OP)|| - (ex_data_forward[0].aluop_i == `EXE_LD_W_OP) ||(ex_data_forward[0].aluop_i == `EXE_ST_B_OP)|| - (ex_data_forward[0].aluop_i == `EXE_ST_H_OP) ||(ex_data_forward[0].aluop_i == `EXE_ST_W_OP)|| - (ex_data_forward[0].aluop_i == `EXE_LD_BU_OP)||(ex_data_forward[0].aluop_i == `EXE_LD_HU_OP) || - (ex_data_forward[0].aluop_i == `EXE_LL_OP) ||(ex_data_forward[0].aluop_i == `EXE_SC_OP))? 1'b1 : 1'b0; - + // Dispatch flag + logic [EXE_STAGE_WIDTH-1:0] do_we_issue; + assign ib_accept_o = do_we_issue & {id_i[1].instr_info.valid, id_i[0].instr_info.valid}; + // Stall always_comb begin - if (rst) stallreg_from_dispatch = `NoStop; - else if (pre_load) stallreg_from_dispatch = `Stop; + if (id_i[1].reg_read_addr[0] == id_i[0].reg_write_addr && id_i[1].reg_read_valid[0] && id_i[0].reg_write_valid) begin + // If P1 instr read reg1 && P0 instr write reg && reg addr is the same + // Only P0 is issued + do_we_issue = 2'b01; + end else if (id_i[1].reg_read_addr[1] == id_i[0].reg_write_addr && id_i[1].reg_read_valid[1] && id_i[0].reg_write_valid) begin + // If P1 instr read reg2 && P0 instr write reg && reg addr is the same + // Only P0 is issued + do_we_issue = 2'b01; + end else begin + do_we_issue = 2'b11; // No data dependecies, can be issued + end end - // Reg read, -> Regfile generate for (genvar i = 0; i < DECODE_WIDTH; i++) begin : reg_read_comb @@ -76,11 +74,11 @@ module dispatch #( begin if(ex_data_forward[1].reg_valid == `WriteEnable && ex_data_forward[1].reg_addr == regfile_reg_read_addr_o[i][0] && id_i[i].reg_read_valid[0]) oprand1[i] = ex_data_forward[1].reg_data; - else if(ex_data_forward[0].reg_valid == `WriteEnable && ex_data_forward[1].reg_addr == regfile_reg_read_addr_o[i][0] && id_i[i].reg_read_valid[0]) + else if(ex_data_forward[0].reg_valid == `WriteEnable && ex_data_forward[0].reg_addr == regfile_reg_read_addr_o[i][0] && id_i[i].reg_read_valid[0]) oprand1[i] = ex_data_forward[0].reg_data; else if(mem_data_forward[1].reg_valid == `WriteEnable && mem_data_forward[1].reg_addr == regfile_reg_read_addr_o[i][0] && id_i[i].reg_read_valid[0]) oprand1[i] = mem_data_forward[1].reg_data; - else if(mem_data_forward[0].reg_valid == `WriteEnable && mem_data_forward[1].reg_addr == regfile_reg_read_addr_o[i][0] && id_i[i].reg_read_valid[0]) + else if(mem_data_forward[0].reg_valid == `WriteEnable && mem_data_forward[0].reg_addr == regfile_reg_read_addr_o[i][0] && id_i[i].reg_read_valid[0]) oprand1[i] = mem_data_forward[0].reg_data; else oprand1[i] = regfile_reg_read_data_i[i][0]; end @@ -95,11 +93,11 @@ module dispatch #( if (id_i[i].use_imm) oprand2[i] = id_i[i].imm; else if(ex_data_forward[1].reg_valid == `WriteEnable && ex_data_forward[1].reg_addr == regfile_reg_read_addr_o[i][1] && id_i[i].reg_read_valid[1]) oprand2[i] = ex_data_forward[1].reg_data; - else if(ex_data_forward[0].reg_valid == `WriteEnable && ex_data_forward[1].reg_addr == regfile_reg_read_addr_o[i][1] && id_i[i].reg_read_valid[1]) + else if(ex_data_forward[0].reg_valid == `WriteEnable && ex_data_forward[0].reg_addr == regfile_reg_read_addr_o[i][1] && id_i[i].reg_read_valid[1]) oprand2[i] = ex_data_forward[0].reg_data; else if(mem_data_forward[1].reg_valid == `WriteEnable && mem_data_forward[1].reg_addr == regfile_reg_read_addr_o[i][1] && id_i[i].reg_read_valid[1]) oprand2[i] = mem_data_forward[1].reg_data; - else if(mem_data_forward[0].reg_valid == `WriteEnable && mem_data_forward[1].reg_addr == regfile_reg_read_addr_o[i][1] && id_i[i].reg_read_valid[1]) + else if(mem_data_forward[0].reg_valid == `WriteEnable && mem_data_forward[0].reg_addr == regfile_reg_read_addr_o[i][1] && id_i[i].reg_read_valid[1]) oprand2[i] = mem_data_forward[0].reg_data; else oprand2[i] = regfile_reg_read_data_i[i][1]; end @@ -112,6 +110,8 @@ module dispatch #( always_ff @(posedge clk or negedge rst_n) begin : dispatch_ff if (!rst_n) begin exe_o[i] <= 0; // + end else if (do_we_issue[i] == 0) begin + exe_o[i] <= 0; // Cannot be issued, so do not issue end else begin // Pass through to EXE diff --git a/src/vsrc/pipeline_defines.sv b/src/vsrc/pipeline_defines.sv index d7411c6..b89f6b9 100644 --- a/src/vsrc/pipeline_defines.sv +++ b/src/vsrc/pipeline_defines.sv @@ -12,7 +12,7 @@ typedef struct packed { logic use_imm; logic [`RegBus] imm; logic [1:0] reg_read_valid; // Read valid for 2 regs - logic [`RegNumLog2*2-1:0] reg_read_addr; // Read addr, {reg2, reg1} + logic [1:0][`RegAddrBus] reg_read_addr; // Read addr, {reg2, reg1} logic [`InstBus] instr; logic [`AluOpBus] aluop; From 5cf3f9436350493e3741ed275cc9e367143bb0a7 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Tue, 10 May 2022 18:23:08 +0800 Subject: [PATCH 108/114] fix: fix dispatch flush --- src/vsrc/cpu_top.sv | 7 ++++++- src/vsrc/pipeline/2_dispatch/dispatch.sv | 14 +++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/vsrc/cpu_top.sv b/src/vsrc/cpu_top.sv index f7bc346..a6fc7b8 100644 --- a/src/vsrc/cpu_top.sv +++ b/src/vsrc/cpu_top.sv @@ -335,9 +335,14 @@ module cpu_top ( ) u_dispatch ( .clk (clk), .rst (rst), + + // <- ID .id_i(id_dispatch_dispatch), - //Data forwarding + .stall(), + .flush(backend_flush), + + // Data forwarding .ex_data_forward(ex_data_forward), .mem_data_forward(mem_data_forward), diff --git a/src/vsrc/pipeline/2_dispatch/dispatch.sv b/src/vsrc/pipeline/2_dispatch/dispatch.sv index c1f7a7e..2a7a543 100644 --- a/src/vsrc/pipeline/2_dispatch/dispatch.sv +++ b/src/vsrc/pipeline/2_dispatch/dispatch.sv @@ -12,7 +12,11 @@ module dispatch #( // <- ID input id_dispatch_struct [DECODE_WIDTH-1:0] id_i, - // <-> Regfile + // <- Ctrl + input logic stall, + input logic flush, + + // <-> Regfile, wire output logic [DECODE_WIDTH-1:0][1:0] regfile_reg_read_valid_o, // Read valid for 2 regs output logic [DECODE_WIDTH-1:0][1:0][`RegAddrBus] regfile_reg_read_addr_o, // Read addr, {reg2, reg1} input logic [DECODE_WIDTH-1:0][1:0][`RegBus] regfile_reg_read_data_i, // Read result @@ -25,7 +29,7 @@ module dispatch #( // Data forwarding input mem_dispatch_struct mem_data_forward[MEM_STAGE_WIDTH], - // -> Instruction Buffer + // -> Instruction Buffer, wire output logic [DECODE_WIDTH-1:0] ib_accept_o, // Dispatch Port @@ -109,7 +113,11 @@ module dispatch #( for (genvar i = 0; i < DECODE_WIDTH; i++) begin always_ff @(posedge clk or negedge rst_n) begin : dispatch_ff if (!rst_n) begin - exe_o[i] <= 0; // + exe_o[i] <= 0; + end else if (flush) begin + exe_o[i] <= 0; + end else if (stall) begin + // Do nothing, hold output end else if (do_we_issue[i] == 0) begin exe_o[i] <= 0; // Cannot be issued, so do not issue end else begin From c2f99daaacbfc8343c0e9248abae42be1c32d740 Mon Sep 17 00:00:00 2001 From: Rookie-rookie-rookie <292601787@qq.com> Date: Tue, 10 May 2022 19:45:45 +0800 Subject: [PATCH 109/114] fix bug --- src/vsrc/pipeline/3_execution/ex.sv | 8 +++++--- src/vsrc/pipeline/4_mem/mem.sv | 11 ++++++----- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/vsrc/pipeline/3_execution/ex.sv b/src/vsrc/pipeline/3_execution/ex.sv index 33e3764..777bfa9 100644 --- a/src/vsrc/pipeline/3_execution/ex.sv +++ b/src/vsrc/pipeline/3_execution/ex.sv @@ -118,10 +118,12 @@ module ex ( logic [`RegBus] reg1_i_mux; logic [`RegBus] result_compare; - assign reg2_i_mux = (aluop_i == `EXE_SLT_OP) ? {~reg2_i[`RegWidth-1], reg2_i[`RegWidth-2:0]} : reg2_i; // shifted encoding when signed comparison - assign reg1_i_mux = (aluop_i == `EXE_SLT_OP) ? {~reg1_i[`RegWidth-1], reg1_i[`RegWidth-2:0]} : reg1_i; + assign reg2_i_mux = (aluop_i == `EXE_SLT_OP) ? ~reg2_i + 32'b1 : reg2_i; // shifted encoding when signed comparison + assign reg1_i_mux = (aluop_i == `EXE_SLT_OP) ? ~reg1_i + 32'b1 : reg1_i; assign result_compare = reg1_i + reg2_i_mux; - assign reg1_lt_reg2 = (reg1_i_mux < reg2_i_mux); + assign reg1_lt_reg2 = (aluop_i == `EXE_SLT_OP) ? ((reg1_i[31] && !reg2_i[31]) || (!reg1_i[31] && !reg2_i[31] && result_compare[31])|| + (reg1_i[31] && reg2_i[31] && result_compare[31])) : (reg1_i < reg2_i); + //乘法模块 diff --git a/src/vsrc/pipeline/4_mem/mem.sv b/src/vsrc/pipeline/4_mem/mem.sv index 0e71d29..945122a 100644 --- a/src/vsrc/pipeline/4_mem/mem.sv +++ b/src/vsrc/pipeline/4_mem/mem.sv @@ -113,7 +113,8 @@ module mem ( case (signal_i.aluop) `EXE_LD_B_OP: begin signal_axi_o.addr = signal_i.mem_addr; - signal_o.wreg = `WriteDisable; + signal_axi_o.we = `WriteEnable; + signal_o.wreg = `WriteEnable; signal_axi_o.ce = `ChipEnable; case (signal_i.mem_addr[1:0]) 2'b00: begin @@ -139,7 +140,7 @@ module mem ( end `EXE_LD_H_OP: begin signal_axi_o.addr = signal_i.mem_addr; - signal_o.wreg = `WriteDisable; + signal_o.wreg = `WriteEnable; signal_axi_o.ce = `ChipEnable; case (signal_i.mem_addr[1:0]) 2'b00: begin @@ -159,14 +160,14 @@ module mem ( end `EXE_LD_W_OP: begin signal_axi_o.addr = signal_i.mem_addr; - signal_o.wreg = `WriteDisable; + signal_o.wreg = `WriteEnable; signal_axi_o.ce = `ChipEnable; signal_axi_o.sel = 4'b1111; signal_o.wdata = mem_data_i; end `EXE_LD_BU_OP: begin signal_axi_o.addr = signal_i.mem_addr; - signal_o.wreg = `WriteDisable; + signal_o.wreg = `WriteEnable; signal_axi_o.ce = `ChipEnable; case (signal_i.mem_addr[1:0]) 2'b00: begin @@ -192,7 +193,7 @@ module mem ( end `EXE_LD_HU_OP: begin signal_axi_o.addr = signal_i.mem_addr; - signal_o.wreg = `WriteDisable; + signal_o.wreg = `WriteEnable; signal_axi_o.ce = `ChipEnable; case (signal_i.mem_addr[1:0]) 2'b00: begin From 6e75e5eddeec3a28852099dc042f4ef6e4247e4e Mon Sep 17 00:00:00 2001 From: Easton Man Date: Tue, 10 May 2022 20:23:46 +0800 Subject: [PATCH 110/114] fix: fix branch cmp data dep --- src/vsrc/pipeline/1_decode/decoder_3R.sv | 2 +- src/vsrc/pipeline/2_dispatch/dispatch.sv | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/vsrc/pipeline/1_decode/decoder_3R.sv b/src/vsrc/pipeline/1_decode/decoder_3R.sv index 3d184b0..5659ff2 100644 --- a/src/vsrc/pipeline/1_decode/decoder_3R.sv +++ b/src/vsrc/pipeline/1_decode/decoder_3R.sv @@ -54,7 +54,7 @@ module decoder_3R #( reg_write_valid_o = 1; reg_write_addr_o = rd; reg_read_valid_o = 2'b11; - reg_read_addr_o = {rj, rk}; + reg_read_addr_o = {rk, rj}; instr_break = 0; instr_syscall = 0; // Default diff --git a/src/vsrc/pipeline/2_dispatch/dispatch.sv b/src/vsrc/pipeline/2_dispatch/dispatch.sv index 2a7a543..62665f3 100644 --- a/src/vsrc/pipeline/2_dispatch/dispatch.sv +++ b/src/vsrc/pipeline/2_dispatch/dispatch.sv @@ -94,8 +94,7 @@ module dispatch #( for (genvar i = 0; i < DECODE_WIDTH; i++) begin always_comb begin begin - if (id_i[i].use_imm) oprand2[i] = id_i[i].imm; - else if(ex_data_forward[1].reg_valid == `WriteEnable && ex_data_forward[1].reg_addr == regfile_reg_read_addr_o[i][1] && id_i[i].reg_read_valid[1]) + if(ex_data_forward[1].reg_valid == `WriteEnable && ex_data_forward[1].reg_addr == regfile_reg_read_addr_o[i][1] && id_i[i].reg_read_valid[1]) oprand2[i] = ex_data_forward[1].reg_data; else if(ex_data_forward[0].reg_valid == `WriteEnable && ex_data_forward[0].reg_addr == regfile_reg_read_addr_o[i][1] && id_i[i].reg_read_valid[1]) oprand2[i] = ex_data_forward[0].reg_data; @@ -131,16 +130,17 @@ module dispatch #( exe_o[i].reg_write_valid <= id_i[i].reg_write_valid; exe_o[i].csr_we <= id_i[i].csr_we; exe_o[i].csr_signal <= id_i[i].csr_signal; + exe_o[i].oprand1 <= oprand1[i]; - exe_o[i].oprand2 <= oprand2[i]; + exe_o[i].oprand2 <= id_i[i].use_imm ? id_i[i].imm : oprand2[i]; exe_o[i].imm <= id_i[i].imm; - exe_o[i].branch_com_result[0] <= regfile_reg_read_data_i[i][0] == regfile_reg_read_data_i[i][1]; - exe_o[i].branch_com_result[1] <= regfile_reg_read_data_i[i][0] != regfile_reg_read_data_i[i][1]; - exe_o[i].branch_com_result[2] <= ({~regfile_reg_read_data_i[i][0][31],regfile_reg_read_data_i[i][0][30:0]} < {~regfile_reg_read_data_i[i][0][31],regfile_reg_read_data_i[i][1][30:0]}); - exe_o[i].branch_com_result[3] <= ({~regfile_reg_read_data_i[i][0][31],regfile_reg_read_data_i[i][0][30:0]} >= {~regfile_reg_read_data_i[i][0][31],regfile_reg_read_data_i[i][1][30:0]}); - exe_o[i].branch_com_result[4] <= regfile_reg_read_data_i[i][0] < regfile_reg_read_data_i[i][1]; - exe_o[i].branch_com_result[5] <= regfile_reg_read_data_i[i][0] >= regfile_reg_read_data_i[i][1]; + exe_o[i].branch_com_result[0] <= oprand1[i] == oprand2[i]; + exe_o[i].branch_com_result[1] <= oprand1[i] != oprand2[i]; + exe_o[i].branch_com_result[2] <= ({~oprand1[i][31],oprand1[i][30:0]} < {~oprand2[i][31],oprand2[i][30:0]}); + exe_o[i].branch_com_result[3] <= ({~oprand1[i][31],oprand1[i][30:0]} >= {~oprand2[i][31],oprand2[i][30:0]}); + exe_o[i].branch_com_result[4] <= oprand1[i] < oprand2[i]; + exe_o[i].branch_com_result[5] <= oprand1[i] >= oprand2[i]; end end end From 53942d373c8ba4caf2488044cd5d2bf58c4ca631 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Wed, 11 May 2022 10:30:36 +0800 Subject: [PATCH 111/114] fix: fix slt opcode --- src/vsrc/defines.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vsrc/defines.sv b/src/vsrc/defines.sv index 1bbed9d..3513ec6 100644 --- a/src/vsrc/defines.sv +++ b/src/vsrc/defines.sv @@ -68,7 +68,7 @@ // 3R-type `define EXE_ADD_W 17'b00000000000100000 `define EXE_SUB_W 17'b00000000000100010 -`define EXE_SLT 17'b00000000000100101 +`define EXE_SLT 17'b00000000000100100 `define EXE_SLTU 17'b00000000000100101 `define EXE_NOR 17'b00000000000101000 `define EXE_AND 17'b00000000000101001 From ecccad146d24e0a8d16906b96ea65d39476c764a Mon Sep 17 00:00:00 2001 From: Rookie-rookie-rookie <292601787@qq.com> Date: Wed, 11 May 2022 12:55:36 +0800 Subject: [PATCH 112/114] fix difftest --- src/vsrc/cpu_top.sv | 23 ++++++++++++++-- src/vsrc/pipeline/4_mem/mem_wb.sv | 45 ++++++++++++++++++------------- 2 files changed, 48 insertions(+), 20 deletions(-) diff --git a/src/vsrc/cpu_top.sv b/src/vsrc/cpu_top.sv index a6fc7b8..ca10ab6 100644 --- a/src/vsrc/cpu_top.sv +++ b/src/vsrc/cpu_top.sv @@ -73,7 +73,7 @@ module cpu_top ( output logic [ 3:0] debug0_wb_rf_wen, output logic [ 4:0] debug0_wb_rf_wnum, output logic [31:0] debug0_wb_rf_wdata - `ifdef CPU_2CMT + `ifdef CPU_2debug_commit , output logic [31:0] debug1_wb_pc, output logic [ 3:0] debug1_wb_rf_wen, @@ -837,7 +837,7 @@ module cpu_top ( debug0_wb_rf_wen <= {3'b0,wb_reg_signal[0].we}; debug0_wb_rf_wdata <= wb_reg_signal[0].wdata; debug0_wb_rf_wnum <= wb_reg_signal[0].waddr; - `ifdef CPU_2CMT + `ifdef CPU_2debug_commit debug1_wb_pc <= wb_reg_signal[1].pc; debug1_wb_rf_wen <= {3'b0, wb_reg_signal[1].we}; debug1_wb_rf_wdata <= wb_reg_signal[1].wdata; @@ -883,6 +883,25 @@ module cpu_top ( .csr_data () ); + DifftestStoreEvent DifftestStoreEvent( + .clock (aclk), + .coreid (0), + .index (0), + .valid (debug_commit_inst_st_en), + .storePAddr (debug_commit_st_paddr), + .storeVAddr (debug_commit_st_vaddr), + .storeData (debug_commit_st_data) + ); + + DifftestLoadEvent DifftestLoadEvent( + .clock (aclk), + .coreid (0), + .index (0), + .valid (debug_commit_inst_ld_en), + .paddr (debug_commit_ld_paddr), + .vaddr (debug_commit_ld_vaddr) + ); + DifftestCSRRegState difftest_csr_state ( .clock (aclk), .coreid (0), // Only one core, so always 0 diff --git a/src/vsrc/pipeline/4_mem/mem_wb.sv b/src/vsrc/pipeline/4_mem/mem_wb.sv index 653f938..bc4aaf3 100644 --- a/src/vsrc/pipeline/4_mem/mem_wb.sv +++ b/src/vsrc/pipeline/4_mem/mem_wb.sv @@ -1,16 +1,16 @@ `include "pipeline_defines.sv" module mem_wb ( - input wire clk, - input wire rst, - input wire stall, + input logic clk, + input logic rst, + input logic stall, input mem_wb_struct mem_signal_o, - input wire mem_LLbit_we, - input wire mem_LLbit_value, + input logic mem_LLbit_we, + input logic mem_LLbit_value, - input wire flush, + input logic flush, output wb_reg wb_reg_o, @@ -24,20 +24,29 @@ module mem_wb ( output reg wb_LLbit_we, output reg wb_LLbit_value, - input wire excp_i, - input wire [15:0] excp_num, + input logic excp_i, + input logic [15:0] excp_num, //to csr - output wire [31:0] csr_era, - output wire [8:0] csr_esubcode, - output wire [5:0] csr_ecode, - output wire excp_flush, - output wire ertn_flush, - output wire va_error, - output wire [31:0] bad_va, - output wire excp_tlbrefill, - output wire excp_tlb, - output wire [18:0] excp_tlb_vppn + output logic [31:0] csr_era, + output logic [8:0] csr_esubcode, + output logic [5:0] csr_ecode, + output logic excp_flush, + output logic ertn_flush, + output logic va_error, + output logic [31:0] bad_va, + output logic excp_tlbrefill, + output logic excp_tlb, + output logic [18:0] excp_tlb_vppn, + + // load store relate difftest + output logic [7:0] debug_commit_inst_ld_en, + output logic [31:0] debug_commit_ld_paddr, + output logic [31:0] debug_commit_ld_vaddr, + output logic [7:0] debug_commit_inst_st_en, + output logic [31:0] debug_commit_st_paddr, + output logic [31:0] debug_commit_st_vaddr, + output logic [31:0] debug_commit_st_data ); reg wb_valid; From 9a90aab1ba5c1fa881f92de087eb5a9df697e827 Mon Sep 17 00:00:00 2001 From: Rookie-rookie-rookie <292601787@qq.com> Date: Wed, 11 May 2022 18:17:03 +0800 Subject: [PATCH 113/114] connetc load store difftest --- src/vsrc/cpu_top.sv | 19 +++++++++++++++++-- src/vsrc/pipeline/4_mem/mem.sv | 12 ++++++++++++ src/vsrc/pipeline/4_mem/mem_wb.sv | 21 +++++++++++++++++++++ src/vsrc/pipeline_defines.sv | 7 +++++++ 4 files changed, 57 insertions(+), 2 deletions(-) diff --git a/src/vsrc/cpu_top.sv b/src/vsrc/cpu_top.sv index ca10ab6..aa672ca 100644 --- a/src/vsrc/cpu_top.sv +++ b/src/vsrc/cpu_top.sv @@ -609,6 +609,13 @@ module cpu_top ( logic [1:0] debug_commit_valid; logic [1:0][`InstBus] debug_commit_instr; logic [1:0][`InstAddrBus] debug_commit_pc; + logic [7:0] debug_commit_inst_ld_en; + logic [31:0] debug_commit_ld_paddr; + logic [31:0] debug_commit_ld_vaddr; + logic [7:0] debug_commit_inst_st_en; + logic [31:0] debug_commit_st_paddr; + logic [31:0] debug_commit_st_vaddr; + logic [31:0] debug_commit_st_data; generate for (genvar i = 0; i < 2; i++) begin : mem_wb @@ -648,7 +655,15 @@ module cpu_top ( .bad_va(wb_bad_va[i]), .excp_tlbrefill(), .excp_tlb(), - .excp_tlb_vppn() + .excp_tlb_vppn(), + + .debug_commit_inst_ld_en(debug_commit_inst_ld_en), + .debug_commit_ld_paddr(debug_commit_ld_paddr), + .debug_commit_ld_vaddr(debug_commit_ld_vaddr), + .debug_commit_inst_st_en(debug_commit_inst_st_en), + .debug_commit_st_paddr(debug_commit_st_paddr), + .debug_commit_st_vaddr(debug_commit_st_vaddr), + .debug_commit_st_data(debug_commit_st_data) ); end endgenerate @@ -899,7 +914,7 @@ module cpu_top ( .index (0), .valid (debug_commit_inst_ld_en), .paddr (debug_commit_ld_paddr), - .vaddr (debug_commit_ld_vaddr) + .vaddr (debug_commit_ld_paddr) ); DifftestCSRRegState difftest_csr_state ( diff --git a/src/vsrc/pipeline/4_mem/mem.sv b/src/vsrc/pipeline/4_mem/mem.sv index 945122a..6f64604 100644 --- a/src/vsrc/pipeline/4_mem/mem.sv +++ b/src/vsrc/pipeline/4_mem/mem.sv @@ -56,6 +56,7 @@ module mem ( logic excp_pme; logic excp_ppi; + assign access_mem = mem_load_op || mem_store_op; assign mem_load_op = signal_i.aluop == `EXE_LD_B_OP || signal_i.aluop == `EXE_LD_BU_OP || signal_i.aluop == `EXE_LD_H_OP || signal_i.aluop == `EXE_LD_HU_OP || @@ -63,6 +64,17 @@ module mem ( assign mem_store_op = signal_i.aluop == `EXE_ST_B_OP || signal_i.aluop == `EXE_ST_H_OP || signal_i.aluop == `EXE_ST_W_OP || signal_i.aluop == `EXE_SC_OP; + //difftest + assign signal_o.inst_ld_en = {2'b0, signal_i.aluop == `EXE_LL_OP ? 1'b1 : 1'b0, signal_i.aluop == `EXE_LD_W_OP ? 1'b1 : 1'b0, + signal_i.aluop == `EXE_LD_HU_OP ? 1'b1 : 1'b0, signal_i.aluop == `EXE_LD_H_OP ? 1'b1 : 1'b0, + signal_i.aluop == `EXE_LD_BU_OP ? 1'b1 : 1'b0, signal_i.aluop == `EXE_LD_B_OP ? 1'b1 : 1'b0}; + + assign signal_o.inst_st_en = {4'b0, signal_i.aluop == `EXE_SC_OP ? 1'b1 : 1'b0, signal_i.aluop == `EXE_ST_W_OP ? 1'b1 : 1'b0, + signal_i.aluop == `EXE_ST_H_OP ? 1'b1 : 1'b0, signal_i.aluop == `EXE_ST_B_OP ? 1'b1 : 1'b0}; + + assign signal_o.load_addr = signal_i.mem_addr; + assign signal_o.store_addr = signal_o.load_addr; + assign signal_o.store_data = signal_axi_o.data; //addr dmw trans assign dmw0_en = ((csr_mem_signal.csr_dmw0[`PLV0] && csr_mem_signal.csr_plv == 2'd0) || (csr_mem_signal.csr_dmw0[`PLV3] && csr_mem_signal.csr_plv == 2'd3)) && (signal_i.wdata[31:29] == csr_mem_signal.csr_dmw0[`VSEG]); diff --git a/src/vsrc/pipeline/4_mem/mem_wb.sv b/src/vsrc/pipeline/4_mem/mem_wb.sv index bc4aaf3..adef3e0 100644 --- a/src/vsrc/pipeline/4_mem/mem_wb.sv +++ b/src/vsrc/pipeline/4_mem/mem_wb.sv @@ -105,6 +105,13 @@ module mem_wb ( debug_commit_instr <= `ZeroWord; debug_commit_pc <= `ZeroWord; debug_commit_valid <= `InstInvalid; + debug_commit_inst_ld_en <= 8'b0; + debug_commit_inst_st_en <= 8'b0; + debug_commit_ld_paddr <= `ZeroWord; + debug_commit_ld_vaddr <= `ZeroWord; + debug_commit_st_paddr <= `ZeroWord; + debug_commit_st_vaddr <= `ZeroWord; + debug_commit_st_data <= `ZeroWord; end else if (flush == 1'b1 || excp_i == 1'b1 || mem_signal_o.aluop == `EXE_ERTN_OP) begin wb_reg_o.waddr <= `NOPRegAddr; wb_reg_o.we <= `WriteDisable; @@ -117,6 +124,13 @@ module mem_wb ( debug_commit_instr <= `ZeroWord; debug_commit_pc <= `ZeroWord; debug_commit_valid <= `InstInvalid; + debug_commit_inst_ld_en <= 8'b0; + debug_commit_inst_st_en <= 8'b0; + debug_commit_ld_paddr <= `ZeroWord; + debug_commit_ld_vaddr <= `ZeroWord; + debug_commit_st_paddr <= `ZeroWord; + debug_commit_st_vaddr <= `ZeroWord; + debug_commit_st_data <= `ZeroWord; end else if (stall == `Stop) begin debug_commit_pc <= `ZeroWord; debug_commit_instr <= `ZeroWord; @@ -133,6 +147,13 @@ module mem_wb ( debug_commit_pc <= mem_signal_o.instr_info.pc; debug_commit_valid <= mem_signal_o.instr_info.valid; debug_commit_instr <= mem_signal_o.instr_info.instr; + debug_commit_inst_ld_en <= mem_signal_o.inst_ld_en; + debug_commit_inst_st_en <= mem_signal_o.inst_st_en; + debug_commit_ld_paddr <= mem_signal_o.load_addr; + debug_commit_ld_vaddr <= mem_signal_o.load_addr; + debug_commit_st_paddr <= mem_signal_o.store_addr; + debug_commit_st_vaddr <= mem_signal_o.store_addr; + debug_commit_st_data <= mem_signal_o.store_data; end end diff --git a/src/vsrc/pipeline_defines.sv b/src/vsrc/pipeline_defines.sv index b89f6b9..08bbc21 100644 --- a/src/vsrc/pipeline_defines.sv +++ b/src/vsrc/pipeline_defines.sv @@ -74,6 +74,13 @@ typedef struct packed { logic [`RegBus] wdata; logic [`AluOpBus] aluop; csr_write_signal csr_signal; + + //load store difftest + logic [7:0] inst_ld_en; + logic [7:0] inst_st_en; + logic [`DataAddrBus] load_addr; + logic [`DataAddrBus] store_addr; + logic [`RegBus] store_data; } mem_wb_struct; typedef struct packed { From 8402095191f2e1e0944a25a1b607fbe29c5f48d1 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Wed, 11 May 2022 20:01:54 +0800 Subject: [PATCH 114/114] fix: fix unexpected change --- src/vsrc/cpu_top.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vsrc/cpu_top.sv b/src/vsrc/cpu_top.sv index aa672ca..9d46127 100644 --- a/src/vsrc/cpu_top.sv +++ b/src/vsrc/cpu_top.sv @@ -73,7 +73,7 @@ module cpu_top ( output logic [ 3:0] debug0_wb_rf_wen, output logic [ 4:0] debug0_wb_rf_wnum, output logic [31:0] debug0_wb_rf_wdata - `ifdef CPU_2debug_commit + `ifdef CPU_2CMT , output logic [31:0] debug1_wb_pc, output logic [ 3:0] debug1_wb_rf_wen, @@ -852,7 +852,7 @@ module cpu_top ( debug0_wb_rf_wen <= {3'b0,wb_reg_signal[0].we}; debug0_wb_rf_wdata <= wb_reg_signal[0].wdata; debug0_wb_rf_wnum <= wb_reg_signal[0].waddr; - `ifdef CPU_2debug_commit + `ifdef CPU_2CMT debug1_wb_pc <= wb_reg_signal[1].pc; debug1_wb_rf_wen <= {3'b0, wb_reg_signal[1].we}; debug1_wb_rf_wdata <= wb_reg_signal[1].wdata;