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 @@
-
+
@@ -36,13 +36,13 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
@@ -277,6 +277,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -297,7 +310,7 @@
-
+
Vivado Synthesis Defaults
@@ -309,7 +322,27 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Vivado Synthesis Defaults
@@ -321,19 +354,7 @@
-
-
-
- Vivado Synthesis Defaults
-
-
-
-
-
-
-
-
-
+
Default settings for Implementation.
@@ -348,15 +369,14 @@
+
-
+
-
- Default settings for Implementation.
-
+
@@ -371,7 +391,24 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Default settings for Implementation.