🐛 Couple of CSR fixes

This commit is contained in:
Florian Zaruba 2017-06-06 21:14:22 +02:00
parent 00e500f08c
commit fbd51d1243
3 changed files with 39 additions and 20 deletions

View file

@ -213,8 +213,8 @@ module csr_regfile #(
CSR_MSTATUS: begin
mstatus_n = csr_wdata;
mstatus_n.sxl = 2'b0;
mstatus_n.uxl = 2'b0;
mstatus_n.sxl = 2'b10;
mstatus_n.uxl = 2'b10;
// hardwired zero registers
mstatus_n.sd = 1'b0;
mstatus_n.xs = 2'b0;
@ -308,28 +308,36 @@ module csr_regfile #(
priv_lvl_n = trap_to_priv_lvl;
end
// return from exception
// -----------------------
// Return from Exception
// -----------------------
// When executing an xRET instruction, supposing xPP holds the value y, xIE is set to xPIE; the privilege
// mode is changed to y; xPIE is set to 1; and xPP is set to U
if (mret) begin
// return from exception, IF doesn't care from where we are returning
eret_o = 1'b1;
// return to the previous privilege level and restore all enable flags
// get the previous machine interrupt enable flag
mstatus_n.mie = mstatus_q.mpie;
mstatus_n.mie = mstatus_q.mpie;
// restore the previous privilege level
priv_lvl_n = mstatus_q.mpp;
priv_lvl_n = mstatus_q.mpp;
// set mpp to user mode
mstatus_n.mpp = PRIV_LVL_U;
mstatus_n.mpp = PRIV_LVL_U;
// set mpie to 1
mstatus_n.mpie = 1'b1;
end
if (sret) begin
// return from exception, IF doesn't care from where we are returning
eret_o = 1'b1;
// return the previous supervisor interrupt enable flag
mstatus_n.sie = mstatus_n.spie;
mstatus_n.sie = mstatus_n.spie;
// restore the previous privilege level
priv_lvl_n = priv_lvl_t'({1'b0, mstatus_n.spp});
priv_lvl_n = priv_lvl_t'({1'b0, mstatus_n.spp});
// set spp to user mode
mstatus_n.spp = logic'(PRIV_LVL_U);
mstatus_n.spp = logic'(PRIV_LVL_U);
// set spie to 1
mstatus_n.spie = 1'b1;
end
end
// ---------------------------

View file

@ -137,17 +137,17 @@ module decoder (
if (instr.itype.rs1 == 5'b0)
instruction_o.op = CSR_READ;
else
instruction_o.op = CSR_SET;
instruction_o.op = CSR_CLEAR;
end
// use zimm and iimm
3'b101: begin// CSRRWI
instruction_o.rs1 = 5'b0;
instruction_o.rs1 = instr.itype.rs1;
imm_select = IIMM;
instruction_o.use_zimm = 1'b1;
instruction_o.op = CSR_WRITE;
end
3'b110: begin// CSRRSI
instruction_o.rs1 = 5'b0;
instruction_o.rs1 = instr.itype.rs1;
imm_select = IIMM;
instruction_o.use_zimm = 1'b1;
// this is just a read
@ -157,7 +157,7 @@ module decoder (
instruction_o.op = CSR_SET;
end
3'b111: begin// CSRRCI
instruction_o.rs1 = 5'b0;
instruction_o.rs1 = instr.itype.rs1;
imm_select = IIMM;
instruction_o.use_zimm = 1'b1;
// this is just a read

View file

@ -262,14 +262,25 @@ class instruction_trace_item;
function string printCSRInstr(input string mnemonic);
result_regs.push_back(sbe.rd);
if (instr[14] == 0) begin
read_regs.push_back(sbe.rs1);
if (sbe.rd != 0 && sbe.rs1 != 0) begin
return $sformatf("%-16s %s, %s, %s", mnemonic, regAddrToStr(sbe.rd), regAddrToStr(sbe.rs1), csrAddrToStr(sbe.result[11:0]));
// don't display instructions which write to zero
end else if (sbe.rd == 0) begin
return $sformatf("%-16s %s, %s", mnemonic, regAddrToStr(sbe.rs1), csrAddrToStr(sbe.result[11:0]));
end else if (sbe.rs1 == 0) begin
return $sformatf("%-16s %s, %s", mnemonic, regAddrToStr(sbe.rd), csrAddrToStr(sbe.result[11:0]));
if (sbe.rd != 0 && sbe.rs1 != 0) begin
return $sformatf("%-16s %s, %s, %s", mnemonic, regAddrToStr(sbe.rd), regAddrToStr(sbe.rs1), csrAddrToStr(sbe.result[11:0]));
// don't display instructions which write to zero
end else if (sbe.rd == 0) begin
return $sformatf("%-16s %s, %s", mnemonic, regAddrToStr(sbe.rs1), csrAddrToStr(sbe.result[11:0]));
end else if (sbe.rs1 == 0) begin
return $sformatf("%-16s %s, %s", mnemonic, regAddrToStr(sbe.rd), csrAddrToStr(sbe.result[11:0]));
end
end else begin
if (sbe.rd != 0 && sbe.rs1 != 0) begin
return $sformatf("%-16s %s, %d, %s", mnemonic, regAddrToStr(sbe.rd), $unsigned(sbe.rs1), csrAddrToStr(sbe.result[11:0]));
// don't display instructions which write to zero
end else if (sbe.rd == 0) begin
return $sformatf("%-16s %d, %s", mnemonic, $unsigned(sbe.rs1), csrAddrToStr(sbe.result[11:0]));
end else if (sbe.rs1 == 0) begin
return $sformatf("%-16s %s, %s", mnemonic, regAddrToStr(sbe.rd), csrAddrToStr(sbe.result[11:0]));
end
end
endfunction // printCSRInstr