From 441df2d19bb384eb24b2ed450b995d9b316ad509 Mon Sep 17 00:00:00 2001 From: UnbalancedCat Date: Sun, 2 Jul 2023 15:49:42 +0800 Subject: [PATCH] [Modifided] fix bugs & 56 Functional Test Point PASS --- lacpu/rtl/cpu/csr.hv | 1 + lacpu/rtl/cpu/csr.v | 280 ++++++++++++++++++++++--------- lacpu/rtl/cpu/exe_stage.v | 14 +- lacpu/rtl/cpu/id_stage.v | 53 +++--- lacpu/rtl/cpu/if_stage.v | 30 +++- lacpu/rtl/cpu/inst_decoder.v | 8 +- lacpu/rtl/cpu/lsu.v | 7 + lacpu/rtl/cpu/mem_stage.v | 40 +++-- lacpu/rtl/cpu/mycpu_top.v | 9 +- lacpu/rtl/soc_lite_top.v | 8 +- lacpu/run_vivado/la32r/la32r.xpr | 93 ++++++---- 11 files changed, 369 insertions(+), 174 deletions(-) diff --git a/lacpu/rtl/cpu/csr.hv b/lacpu/rtl/cpu/csr.hv index 72891a9..5595199 100644 --- a/lacpu/rtl/cpu/csr.hv +++ b/lacpu/rtl/cpu/csr.hv @@ -22,6 +22,7 @@ `define TID_ADDR 14'h40 `define TCFG_ADDR 14'h41 `define TVAL_ADDR 14'h42 +`define CNTC_ADDR 14'h43 `define TICLR_ADDR 14'h44 `define LLBCTL_ADDR 14'h60 `define TLBRENTRY_ADDR 14'h88 diff --git a/lacpu/rtl/cpu/csr.v b/lacpu/rtl/cpu/csr.v index 4e195d2..635e841 100644 --- a/lacpu/rtl/cpu/csr.v +++ b/lacpu/rtl/cpu/csr.v @@ -7,6 +7,8 @@ module csr( input [31:0] pc, input [31:0] src1, + input [31:0] error_va, + input csr_we, input [63:0] csr_vec, input [ 6:0] csr_op, @@ -18,41 +20,48 @@ module csr( output except_en, output [31:0] new_pc, - output [ 1:0] plv + output [ 1:0] plv_out, + output has_int_out ); - reg [31:0] crmd; //** 当前模式信息 - reg [31:0] prmd; //** 例外前模式信息 - reg [31:0] euen; // 扩展部件使能 - reg [31:0] ecfg; // 例外配置 - reg [31:0] estat; //** 例外状态 - reg [31:0] era; //** 例外返回地址 - reg [31:0] badv; // 出错虚地址 - reg [31:0] eentry; //** 例外入口地址 - reg [31:0] tlbidx; // TLB 索引 - reg [31:0] tlbehi; // TLB 表项最高位 - reg [31:0] tlbelo0; // TLB 表项低位 0 - reg [31:0] tlbelo1; // TLB 表项低位 1 - reg [31:0] asid; // 地址空间标识符 - reg [31:0] pgdl; // 低半地址空间全局目录基址 - reg [31:0] pgdh; // 高半地址空间全局目录基址 - reg [31:0] pgd; // 全局目录基址 - reg [31:0] cpuid; // 处理器编号 - reg [31:0] save0; //** 数据保存0 - reg [31:0] save1; //** 数据保存1 - reg [31:0] save2; //** 数据保存2 - reg [31:0] save3; //** 数据保存3 - reg [31:0] tid; // 定时器编号 - reg [31:0] tcfg; // 定时器配置 - reg [31:0] tval; // 定时器值 - reg [31:0] ticlr; // 定时中断清除 - reg [31:0] llbctl; // LLbit 控制 - reg [31:0] tlbrentry; // TLB 重填例外入口地址 - reg [31:0] ctag; // 高速缓存标签 - reg [31:0] dmw0; // 直接映射配置窗口0 - reg [31:0] dmw1; // 直接映射配置窗口1 + reg [31:0] crmd; // ?????? + reg [31:0] prmd; // ??????? + reg [31:0] euen; // ?????? + reg [31:0] ecfg; // ???? + reg [31:0] estat; // ???? + reg [31:0] era; // ?????? + reg [31:0] badv; // ????? + reg [31:0] eentry; // ?????? + reg [31:0] tlbidx; // TLB ?? + reg [31:0] tlbehi; // TLB ????? + reg [31:0] tlbelo0; // TLB ???? 0 + reg [31:0] tlbelo1; // TLB ???? 1 + reg [31:0] asid; // ??????? + reg [31:0] pgdl; // ???????????? + reg [31:0] pgdh; // ???????????? + reg [31:0] pgd; // ?????? + reg [31:0] cpuid; // ????? + reg [31:0] save0; // ????0 + reg [31:0] save1; // ????1 + reg [31:0] save2; // ????2 + reg [31:0] save3; // ????3 + reg [31:0] tid; // ????? + reg [31:0] tcfg; // ????? + reg [31:0] tval; // ???? + reg [31:0] ticlr; // ?????? + reg [31:0] llbctl; // LLbit ?? + reg [31:0] tlbrentry; // TLB ???????? + reg [31:0] ctag; // ?????? + reg [31:0] dmw0; // ????????0 + reg [31:0] dmw1; // ????????1 reg [31:0] csr_rdata_r; + reg timer_en; + reg [63:0] timer_64; + + reg has_int_r; + reg [ 1:0] plv_r; + wire inst_sc_w; wire inst_csrrd; wire inst_csrwr; @@ -61,6 +70,11 @@ module csr( wire inst_rdcntvl_w; wire inst_rdcntvh_w; + wire has_int; + + + wire excp_ale; + wire excp_adef; wire excp_ipe; wire excp_ine; wire inst_break; @@ -71,29 +85,53 @@ module csr( wire [ 5:0] ecode; wire [ 8:0] esubcode; + wire va_error; + wire [31:0] bad_va; - assign plv = except_en ? 2'b0 : - inst_ertn ? prmd[`PPLV] : - csr_we && (csr_addr == `CRMD_ADDR) ? csr_wdata[`PLV] : - crmd[`PLV]; + always @(posedge clk) begin + if(reset) begin + has_int_r <= 0; + plv_r <= 0; + end + else begin + has_int_r <= ((ecfg[`LIE] & estat[`IS]) != 13'b0) & crmd[`IE]; + plv_r <= except_en & !inst_ertn ? 2'b0 : + inst_ertn ? prmd[`PPLV] : + csr_we && (csr_addr == `CRMD_ADDR) ? csr_wdata[`PLV] : + crmd[`PLV]; + end + end - assign {excp_ipe, + // out TODO! + assign has_int_out = ((ecfg[`LIE] & estat[`IS]) != 13'b0) & crmd[`IE]; //has_int_r; + assign plv_out = except_en & !inst_ertn ? 2'b0 : + inst_ertn ? prmd[`PPLV] : + csr_we && (csr_addr == `CRMD_ADDR) ? csr_wdata[`PLV] : + crmd[`PLV]; //plv_r; + + assign {excp_ale, + excp_adef, + excp_ipe, excp_ine, inst_break, inst_syscall, - inst_ertn - } = csr_vec[4:0]; + inst_ertn, + has_int + } = csr_vec[7:0]; - assign {ecode,esubcode} = inst_syscall ? {`ECODE_SYS, 9'b0} : - inst_break ? {`ECODE_BRK, 9'b0} : - excp_ine ? {`ECODE_INE, 9'b0} : - excp_ipe ? {`ECODE_IPE, 9'b0} : - 15'b0; + assign {ecode, esubcode, va_error, bad_va} = excp_adef ? {`ECODE_ADEF, `ESUBCODE_ADEF, 1'b1, pc } : + has_int ? {`ECODE_INT , 9'b0 , 1'b0, 32'b0 } : + inst_syscall ? {`ECODE_SYS , 9'b0 , 1'b0, 32'b0 } : + inst_break ? {`ECODE_BRK , 9'b0 , 1'b0, 32'b0 } : + excp_ine ? {`ECODE_INE , 9'b0 , 1'b0, 32'b0 } : + excp_ipe ? {`ECODE_IPE , 9'b0 , 1'b0, 32'b0 } : + excp_ale ? {`ECODE_ALE , 9'b0 , 1'b1, error_va} : + 0; assign csr_rdata = csr_rdata_r; always @(*) begin - if(|csr_op) begin + if(|csr_op[6:4]) begin case(csr_addr) `CRMD_ADDR : csr_rdata_r <= crmd; `PRMD_ADDR : csr_rdata_r <= prmd; @@ -128,6 +166,11 @@ module csr( default : csr_rdata_r <= 32'b0; endcase end + else if(|csr_op[3:1]) begin + csr_rdata_r <= ({33{csr_op[1]}} & timer_64[31: 0]) | + ({33{csr_op[2]}} & timer_64[63:32]) | + ({33{csr_op[3]}} & tid); + end else begin //csr_rdata_r <= 32'b0; end @@ -168,7 +211,7 @@ module csr( save2 <= 0; save3 <= 0; tid <= 0; - tcfg <= 0; + tcfg <= 32'hfffffffe; tval <= 0; ticlr <= 0; llbctl <= 0; @@ -176,9 +219,11 @@ module csr( ctag <= 0; dmw0 <= 0; dmw1 <= 0; + + timer_en <= 1'b0; end - else if (except_en) begin - if(inst_syscall) begin + else if(except_en) begin + if((|csr_vec[7:0] & !inst_ertn) | excp_adef) begin crmd[ `PLV] <= 2'b0; crmd[ `IE] <= 1'b0; @@ -193,46 +238,117 @@ module csr( else if(inst_ertn) begin crmd[ `PLV] <= prmd[`PPLV]; crmd[ `IE] <= prmd[`PIE ]; - end + end + + if(va_error) begin + badv <= bad_va; + end end else if (csr_we) begin case (csr_addr) - `CRMD_ADDR : crmd <= csr_wdata_temp; - `PRMD_ADDR : prmd <= csr_wdata_temp; - `EUEN_ADDR : euen <= csr_wdata_temp; - `ECFG_ADDR : ecfg <= csr_wdata_temp; - `ESTAT_ADDR : estat <= csr_wdata_temp; - `ERA_ADDR : era <= csr_wdata_temp; - `BADV_ADDR : badv <= csr_wdata_temp; - `EENTRY_ADDR : eentry <= csr_wdata_temp; - `TLBIDX_ADDR : tlbidx <= csr_wdata_temp; - `TLBEHI_ADDR : tlbehi <= csr_wdata_temp; - `TLBELO0_ADDR : tlbelo0 <= csr_wdata_temp; - `TLBELO1_ADDR : tlbelo1 <= csr_wdata_temp; - `ASID_ADDR : asid <= csr_wdata_temp; - `PGDL_ADDR : pgdl <= csr_wdata_temp; - `PGDH_ADDR : pgdh <= csr_wdata_temp; - `PGD_ADDR : pgd <= csr_wdata_temp; - `CPUID_ADDR : cpuid <= csr_wdata_temp; - `SAVE0_ADDR : save0 <= csr_wdata_temp; - `SAVE1_ADDR : save1 <= csr_wdata_temp; - `SAVE2_ADDR : save2 <= csr_wdata_temp; - `SAVE3_ADDR : save3 <= csr_wdata_temp; - `TID_ADDR : tid <= csr_wdata_temp; - `TCFG_ADDR : tcfg <= csr_wdata_temp; - `TVAL_ADDR : tval <= csr_wdata_temp; - `TICLR_ADDR : ticlr <= csr_wdata_temp; - `LLBCTL_ADDR : llbctl <= csr_wdata_temp; - `TLBRENTRY_ADDR : tlbrentry <= csr_wdata_temp; - `CTAG_ADDR : ctag <= csr_wdata_temp; - `DMW0_ADDR : dmw0 <= csr_wdata_temp; - `DMW1_ADDR : dmw1 <= csr_wdata_temp; + `CRMD_ADDR : begin + crmd[ `PLV] <= csr_wdata_temp[ `PLV]; + crmd[ `IE] <= csr_wdata_temp[ `IE]; + crmd[ `DA] <= csr_wdata_temp[ `DA]; + crmd[ `PG] <= csr_wdata_temp[ `PG]; + crmd[`DATF] <= csr_wdata_temp[`DATF]; + crmd[`DATM] <= csr_wdata_temp[`DATM]; + end + `PRMD_ADDR : begin + prmd[`PPLV] <= csr_wdata_temp[`PPLV]; + prmd[ `PIE] <= csr_wdata_temp[ `PIE]; + end + `EUEN_ADDR : euen <= csr_wdata_temp; + `ECFG_ADDR : begin + ecfg <= csr_wdata_temp; // ???????????????? + + end + `ESTAT_ADDR : estat[1:0] <= csr_wdata_temp[1:0]; + `ERA_ADDR : era <= csr_wdata_temp; + `BADV_ADDR : badv <= csr_wdata_temp; // MORE + `EENTRY_ADDR : eentry[31:6] <= csr_wdata_temp[31:6]; + `TLBIDX_ADDR : tlbidx <= csr_wdata_temp; // PASS + `TLBEHI_ADDR : tlbehi <= csr_wdata_temp; // PASS + `TLBELO0_ADDR : tlbelo0 <= csr_wdata_temp; // PASS + `TLBELO1_ADDR : tlbelo1 <= csr_wdata_temp; // PASS + `ASID_ADDR : asid[`TLB_ASID] <= csr_wdata_temp[`TLB_ASID]; // MORE + `PGDL_ADDR : pgdl <= csr_wdata_temp; + `PGDH_ADDR : pgdh <= csr_wdata_temp; + `PGD_ADDR : pgd <= csr_wdata_temp; + //`CPUID_ADDR : cpuid <= csr_wdata_temp; + `SAVE0_ADDR : save0 <= csr_wdata_temp; + `SAVE1_ADDR : save1 <= csr_wdata_temp; + `SAVE2_ADDR : save2 <= csr_wdata_temp; + `SAVE3_ADDR : save3 <= csr_wdata_temp; + `TID_ADDR : tid <= csr_wdata_temp; + `TCFG_ADDR : begin + tcfg[ `EN] <= csr_wdata_temp[ `EN]; + tcfg[`PERIODIC] <= csr_wdata_temp[`PERIODIC]; + tcfg[ `INITVAL] <= csr_wdata_temp[ `INITVAL]; + + tval <= {csr_wdata_temp[ `INITVAL], 2'b0}; + timer_en <= csr_wdata_temp[`EN]; + end + //`TVAL_ADDR : tval <= {csr_wdata_temp[ `INITVAL], 2'b0}; + `TICLR_ADDR : begin + if(csr_wdata_temp[`CLR]) begin + estat[11] <= 1'b0; + end + end + `LLBCTL_ADDR : llbctl <= csr_wdata_temp; // PASS + `TLBRENTRY_ADDR : tlbrentry <= csr_wdata_temp; // PASS + `CTAG_ADDR : ctag <= csr_wdata_temp; + `DMW0_ADDR : begin + dmw0[`PLV0] <= csr_wdata_temp[`PLV0]; + dmw0[`PLV3] <= csr_wdata_temp[`PLV3]; + dmw0[`DMW_MAT] <= csr_wdata_temp[`DMW_MAT]; + dmw0[`PSEG] <= csr_wdata_temp[`PSEG]; + dmw0[`VSEG] <= csr_wdata_temp[`VSEG]; + end + `DMW1_ADDR : begin + dmw1[`PLV0] <= csr_wdata_temp[`PLV0]; + dmw1[`PLV3] <= csr_wdata_temp[`PLV3]; + dmw1[`DMW_MAT] <= csr_wdata_temp[`DMW_MAT]; + dmw1[`PSEG] <= csr_wdata_temp[`PSEG]; + dmw1[`VSEG] <= csr_wdata_temp[`VSEG]; + end endcase end + else begin + // estat + if(timer_en && (tval == 32'b0)) begin + estat[11] <= 1'b1; + timer_en <= tcfg[`PERIODIC]; + end + //estat[9:0] <= intrpt; // ??? + + // tval + if(timer_en) begin + if (tval != 32'b0) begin + tval <= tval - 32'b1; + end + else if (tval == 32'b0) begin + tval <= tcfg[`PERIODIC] ? {tcfg[`INITVAL], 2'b0} : 32'hffffffff; + end + end + end + end + + assign except_en = |csr_vec[7:0]; + assign new_pc = (|csr_vec[7:0] & !inst_ertn) | excp_adef ? eentry : + inst_ertn ? era : + 32'b0; // TODO! + + + + //timer_64 + always @(posedge clk) begin + if (reset) begin + timer_64 <= 64'b0; + end + else begin + timer_64 <= timer_64 + 1'b1; + end end - assign except_en = excp_ipe | excp_ine | inst_break | inst_syscall | inst_ertn; - assign new_pc = inst_syscall ? eentry : - inst_ertn ? era : - 32'b0; // TODO! endmodule \ No newline at end of file diff --git a/lacpu/rtl/cpu/exe_stage.v b/lacpu/rtl/cpu/exe_stage.v index 37b8a01..e886c2f 100755 --- a/lacpu/rtl/cpu/exe_stage.v +++ b/lacpu/rtl/cpu/exe_stage.v @@ -30,6 +30,7 @@ module exe_stage reg [DS_TO_ES_BUS_WD -1:0] ds_to_es_bus_r; wire [63:0] csr_vec; + wire [63:0] csr_vec_temp; wire [ 6:0] csr_op; wire csr_wdata_sel; wire [13:0] csr_addr; @@ -79,9 +80,10 @@ module exe_stage wire [31:0] csr_wdata; wire [63:0] csr_bus; - - assign {csr_vec ,//300:237 + wire excp_ale; + + assign {csr_vec_temp ,//300:237 csr_op ,//236:230 csr_wdata_sel ,//229:229 csr_addr ,//228:215 @@ -184,7 +186,7 @@ module exe_stage wire csr_cancel; reg csr_cancel_reg; - assign csr_cancel = |csr_vec[31:0]; + assign csr_cancel = flush ? 1'b0 : |csr_vec[31:0];// TODO! always @ (posedge clk) begin if (reset) begin @@ -209,6 +211,8 @@ module exe_stage .rkd_value (src2 ), .imm (imm ), + .excp_ale (excp_ale ), + .data_sram_en (data_sram_en_temp), .data_sram_we (data_sram_we_temp), .data_sram_addr (data_sram_addr ), @@ -220,7 +224,7 @@ module exe_stage // mul_div mul_div_top u_mul_div_top( .clk (clk ), - .reset (reset ), + .reset (reset | flush ), .stall (stall ), .stallreq (stallreq_for_mul_div), .mul_div_op (mul_div_op ), @@ -242,6 +246,8 @@ module exe_stage csr_wdata }; + assign csr_vec = {csr_vec_temp[63:8], excp_ale, csr_vec_temp[6:0]}; + assign stallreq_es = stallreq_for_mul_div; endmodule \ No newline at end of file diff --git a/lacpu/rtl/cpu/id_stage.v b/lacpu/rtl/cpu/id_stage.v index 3c755b3..b4c51a4 100755 --- a/lacpu/rtl/cpu/id_stage.v +++ b/lacpu/rtl/cpu/id_stage.v @@ -1,6 +1,6 @@ module id_stage #( - parameter FS_TO_DS_BUS_WD = 32, + parameter FS_TO_DS_BUS_WD = 65, parameter DS_TO_ES_BUS_WD = 301, parameter WS_TO_RF_BUS_WD = 38 ) @@ -16,16 +16,15 @@ module id_stage input pc_valid, input [31:0] inst_sram_rdata, - input [31:0] csr_vec_h, input [ 1:0] csr_plv, + input csr_has_int, input [FS_TO_DS_BUS_WD -1:0] fs_to_ds_bus, input [WS_TO_RF_BUS_WD -1:0] ws_to_rf_bus, output [DS_TO_ES_BUS_WD -1:0] ds_to_es_bus ); + reg [FS_TO_DS_BUS_WD -1:0] fs_to_ds_bus_r; reg pc_valid_r; - reg [31:0] fs_to_ds_bus_r; - reg [31:0] csr_vec_h_r; reg [31:0] inst_r; reg stall_flag; @@ -59,7 +58,6 @@ module id_stage wire [13:0] csr_addr; wire csr_wdata_sel; - wire [31:0] inst; wire [31:0] next_inst; @@ -81,18 +79,28 @@ module id_stage wire stallreq_load; wire stallreq_csr; - assign ds_pc = fs_to_ds_bus_r; + wire excp_adef; + wire [31:0] csr_vec_h; + wire [31:0] csr_vec_l; + wire [63:0] csr_vec; + + assign {csr_vec_h, + excp_adef, + ds_pc + } = fs_to_ds_bus_r; + + assign csr_vec = {csr_vec_h, csr_vec_l}; + assign br_flush = br_taken; + assign {rf_we , //37:37 rf_waddr, //36:32 rf_wdata //31:0 } = ws_to_rf_bus; - wire [31:0] csr_vec_l; - wire [63:0] csr_vec; + - assign csr_vec = {csr_vec_h_r, csr_vec_l}; - assign ds_to_es_bus = {csr_vec ,//300:237 + assign ds_to_es_bus = {csr_vec & {64{pc_valid_r}} ,//300:237 csr_op ,//236:230 csr_wdata_sel ,//229:229 csr_addr ,//228:215 @@ -119,32 +127,27 @@ module id_stage always @ (posedge clk)begin if (reset) begin - pc_valid_r <= 1'b0; - fs_to_ds_bus_r <= 32'b0; - csr_vec_h_r <= 32'b0; + pc_valid_r <= 1'b0; + fs_to_ds_bus_r <= 0; end else if (flush) begin - pc_valid_r <= 1'b0; - fs_to_ds_bus_r <= 32'b0; - csr_vec_h_r <= 32'b0; + pc_valid_r <= 1'b0; + fs_to_ds_bus_r <= 0; end //nop, ID stall and EX not stall else if (stall[1] & (!stall[2]))begin - pc_valid_r <= 1'b0; - fs_to_ds_bus_r <= 32'b0; - csr_vec_h_r <= 32'b0; + pc_valid_r <= 1'b0; + fs_to_ds_bus_r <= 0; end //nop, ID not stall but branch else if (!stall[1] & br_flush) begin - pc_valid_r <= 1'b0; - fs_to_ds_bus_r <= 32'b0; - csr_vec_h_r <= 32'b0; + pc_valid_r <= 1'b0; + fs_to_ds_bus_r <= 0; end // ID not stall so go on else if (!stall[1]) begin pc_valid_r <= pc_valid; fs_to_ds_bus_r <= fs_to_ds_bus; - csr_vec_h_r <= csr_vec_h; end end @@ -192,7 +195,9 @@ module id_stage .branch_op (branch_op ), .load_op (load_op ), .store_op (store_op ), + .excp_adef (excp_adef ), .csr_plv (csr_plv ), + .csr_has_int (csr_has_int ), .csr_we (csr_we ), .csr_op (csr_op ), .csr_addr (csr_addr ), @@ -220,7 +225,6 @@ module id_stage assign rj_value = rf_rdata1; assign rkd_value = rf_rdata2; - always @ (posedge clk) begin if (reset) begin ex_load_buffer <= 7'b0; @@ -250,5 +254,4 @@ module id_stage assign stallreq_csr = ex_is_csr & ex_rf_we & ((ex_rf_waddr==rj_value & rj_value!=0)|(ex_rf_waddr==rkd_value & rkd_value!=0)); assign stallreq_ds = stallreq_load | stallreq_csr; - endmodule \ No newline at end of file diff --git a/lacpu/rtl/cpu/if_stage.v b/lacpu/rtl/cpu/if_stage.v index ee299b7..beda779 100755 --- a/lacpu/rtl/cpu/if_stage.v +++ b/lacpu/rtl/cpu/if_stage.v @@ -1,7 +1,7 @@ module if_stage #( parameter BR_BUS_WD = 33, - parameter FS_TO_DS_BUS_WD = 32 + parameter FS_TO_DS_BUS_WD = 65 ) ( input clk , @@ -13,7 +13,6 @@ module if_stage input [31:0] new_pc, input timer_int, - output [31:0] csr_vec_h, output inst_sram_en , output [ 3:0] inst_sram_we , @@ -25,13 +24,21 @@ module if_stage ); reg pc_valid; reg [31:0] fs_pc; + + reg excp_adef; + reg [31:0] csr_vec_h; + wire [31:0] seq_pc; wire [31:0] next_pc; wire br_taken; wire [31:0] br_target; - assign fs_to_ds_bus = fs_pc; + + assign fs_to_ds_bus = {csr_vec_h, //64:33 + excp_adef, //32:32 + fs_pc //31:0 + }; assign {br_taken, br_target @@ -39,23 +46,28 @@ module if_stage always @ (posedge clk) begin if (reset) begin - pc_valid <= 1'b0; - fs_pc <= 32'h1bff_fffc; + pc_valid <= 1'b0; + fs_pc <= 32'h1bff_fffc; + excp_adef <= 1'b0; + csr_vec_h <= 32'b0; end else if (flush) begin pc_valid <= 1'b1; - fs_pc <= new_pc; + fs_pc <= new_pc; + excp_adef <= |new_pc[1:0]; + csr_vec_h <= 32'b0; end else if (!stall[0]) begin - pc_valid <= 1'b1; - fs_pc <= next_pc; + pc_valid <= 1'b1; + fs_pc <= next_pc; + excp_adef <= |next_pc[1:0]; + csr_vec_h <= 0; // timer_int; TODO! end end assign seq_pc = fs_pc + 3'h4; assign next_pc = br_taken ? br_target : seq_pc; - assign csr_vec_h = 0; // timer_int; TODO! assign inst_sram_en = flush | (br_taken ? 1'b0 : pc_valid); assign inst_sram_we = 4'h0; diff --git a/lacpu/rtl/cpu/inst_decoder.v b/lacpu/rtl/cpu/inst_decoder.v index e71ae37..6546aa8 100644 --- a/lacpu/rtl/cpu/inst_decoder.v +++ b/lacpu/rtl/cpu/inst_decoder.v @@ -24,7 +24,9 @@ module inst_decoder( output [ 2:0] store_op, // csr + input excp_adef, input [ 1:0] csr_plv, + input csr_has_int, output csr_we, output [ 6:0] csr_op, @@ -442,7 +444,7 @@ module inst_decoder( }; assign csr_addr = inst[23:10]; assign csr_wdata_sel = inst_csrxchg; - assign csr_vec_l = {28'b0 ,excp_ipe, excp_ine, inst_break, inst_syscall, inst_ertn}; + assign csr_vec_l = {25'b0, excp_adef, excp_ipe, excp_ine, inst_break, inst_syscall, inst_ertn, csr_has_int}; assign inst_valid = inst_add_w | inst_sub_w | @@ -519,7 +521,7 @@ module inst_decoder( // rd == 5'd6 )); //invtlb valid op - assign excp_ine = 1'b0;//~inst_valid; // TODO! + assign excp_ine = ~inst_valid; assign kernel_inst = inst_csrrd | inst_csrwr | @@ -533,7 +535,7 @@ module inst_decoder( inst_ertn ; //inst_idle ; - assign excp_ipe = kernel_inst && (csr_plv == 2'b11); // TODO! + assign excp_ipe = kernel_inst && (csr_plv == 2'b11); // rf_res from // assign sel_rf_res[0] = inst_jirl | inst_bl; diff --git a/lacpu/rtl/cpu/lsu.v b/lacpu/rtl/cpu/lsu.v index fa6eca9..39d9595 100644 --- a/lacpu/rtl/cpu/lsu.v +++ b/lacpu/rtl/cpu/lsu.v @@ -5,6 +5,7 @@ module lsu( input [31:0] rkd_value, input [31:0] imm, + output excp_ale, output data_sram_en, output [ 3:0] data_sram_we, output [31:0] data_sram_addr, @@ -42,6 +43,12 @@ module lsu( .in (addr[1:0]), .out(byte_sel ) ); + + assign excp_ale = data_sram_en & (((inst_st_b | inst_ld_b | inst_ld_bu) & 1'b0 ) | + ((inst_st_h | inst_ld_h | inst_ld_hu) & addr[0] ) | + ((inst_st_w | inst_ld_w) & (|addr[1:0]))); + + assign data_sram_en = (|store_op) | (|load_op); assign data_sram_we = inst_st_b ? byte_sel : diff --git a/lacpu/rtl/cpu/mem_stage.v b/lacpu/rtl/cpu/mem_stage.v index f454dbf..21be0d9 100755 --- a/lacpu/rtl/cpu/mem_stage.v +++ b/lacpu/rtl/cpu/mem_stage.v @@ -14,6 +14,7 @@ module mem_stage output [31:0] new_pc, output [ 1:0] csr_plv, + output csr_has_int, input [ES_TO_MS_BUS_WD -1:0] es_to_ms_bus, output [MS_TO_ES_BUS_WD -1:0] ms_to_es_bus, @@ -57,6 +58,7 @@ module mem_stage wire [13:0] csr_addr; wire [31:0] csr_wdata; + wire [31:0] src1; wire [31:0] ms_final_result; @@ -165,25 +167,27 @@ module mem_stage } = csr_bus; csr u_csr( - .clk (clk ), - .reset (reset ), - .stall (stall[3]&stall[4]), - .pc (ms_pc ), - .src1 (src1 ), - .plv (csr_plv ), - .csr_we (csr_we ), - .csr_vec (csr_vec ), - .csr_op (csr_op ), - .csr_addr (csr_addr ), - .csr_wdata_sel (csr_wdata_sel ), - .csr_wdata (csr_wdata ), - .csr_rdata (csr_rdata ), - .except_en (except_en ), - .new_pc (new_pc ) + .clk (clk ), + .reset (reset ), + .stall (stall[3]&stall[4] ), + .pc (ms_pc ), + .src1 (src1 ), + .error_va (es_result ), + .plv_out (csr_plv ), + .has_int_out (csr_has_int ), + .csr_we (csr_we ), + .csr_vec (csr_vec ), + .csr_op (csr_op ), + .csr_addr (csr_addr ), + .csr_wdata_sel (csr_wdata_sel ), + .csr_wdata (csr_wdata ), + .csr_rdata (csr_rdata ), + .except_en (except_en ), + .new_pc (new_pc ) ); - assign ms_final_result = (|load_op) ? ms_result : - (|csr_op) ? csr_result : - es_result; + assign ms_final_result = (|load_op) ? ms_result : + (|csr_op ) ? csr_result : + es_result; endmodule \ No newline at end of file diff --git a/lacpu/rtl/cpu/mycpu_top.v b/lacpu/rtl/cpu/mycpu_top.v index 1862d9d..0fc4124 100644 --- a/lacpu/rtl/cpu/mycpu_top.v +++ b/lacpu/rtl/cpu/mycpu_top.v @@ -1,6 +1,6 @@ module mycpu_top #( - parameter FS_TO_DS_BUS_WD = 32, + parameter FS_TO_DS_BUS_WD = 65, parameter DS_TO_ES_BUS_WD = 301, parameter ES_TO_MS_BUS_WD = 271, parameter MS_TO_WS_BUS_WD = 102, @@ -55,9 +55,9 @@ module mycpu_top wire [ 5:0] stall; wire except_en; wire [31:0] new_pc; - wire [31:0] csr_vec_h; wire [ 1:0] csr_plv; + wire csr_has_int; if_stage if_stage( .clk (clk ), @@ -66,7 +66,6 @@ module mycpu_top .stall (stall ), .new_pc (new_pc ), .timer_int (timer_int ), - .csr_vec_h (csr_vec_h ), .fs_to_ds_bus (fs_to_ds_bus ), .br_bus (br_bus ), .inst_sram_en (inst_sram_en ), @@ -85,8 +84,8 @@ module mycpu_top .fs_to_ds_bus (fs_to_ds_bus ), .pc_valid (inst_sram_en ), .inst_sram_rdata (inst_sram_rdata ), - .csr_vec_h (csr_vec_h ), .csr_plv (csr_plv ), + .csr_has_int (csr_has_int ), .ws_to_rf_bus (ws_to_rf_bus ), .ds_to_es_bus (ds_to_es_bus ) ); @@ -97,6 +96,7 @@ module mycpu_top .flush (flush ), .stall (stall ), .stallreq_es (stallreq_es ), + .ds_to_es_bus (ds_to_es_bus ), .es_to_ms_bus (es_to_ms_bus ), .ms_to_es_bus (ms_to_es_bus ), @@ -118,6 +118,7 @@ module mycpu_top .except_en (except_en ), .new_pc (new_pc ), .csr_plv (csr_plv ), + .csr_has_int (csr_has_int ), .es_to_ms_bus (es_to_ms_bus ), .ms_to_es_bus (ms_to_es_bus ), diff --git a/lacpu/rtl/soc_lite_top.v b/lacpu/rtl/soc_lite_top.v index 4b06fe4..9ca9e0e 100755 --- a/lacpu/rtl/soc_lite_top.v +++ b/lacpu/rtl/soc_lite_top.v @@ -15,11 +15,17 @@ module soc_lite_top reg cpu_resetn; assign pc = debug_wb_pc[15:0]; - assign cpu_clk = clk; + //assign cpu_clk = clk; always @(posedge cpu_clk) begin cpu_resetn <= resetn; end + + pll pll( + .clk_in1(clk), + .clk_out1(cpu_clk) + ); + //cpu inst sram wire cpu_inst_en; diff --git a/lacpu/run_vivado/la32r/la32r.xpr b/lacpu/run_vivado/la32r/la32r.xpr index 7ae7ed5..a7e329c 100644 --- a/lacpu/run_vivado/la32r/la32r.xpr +++ b/lacpu/run_vivado/la32r/la32r.xpr @@ -7,7 +7,7 @@