Commit 8ae3e026 authored by Tristan Gingold's avatar Tristan Gingold

rtl: add fix_ecc instruction

parent 706d34d2
......@@ -125,6 +125,7 @@ module urv_cpu
wire d2x_shifter_sign;
wire d2x_is_load, d2x_is_store, d2x_is_undef;
wire d2x_is_write_ecc;
wire d2x_is_fix_ecc;
wire [31:0] d2x_imm;
wire d2x_is_signed_alu_op;
wire d2x_is_add_o;
......@@ -243,6 +244,7 @@ module urv_cpu
.x_is_store_o(d2x_is_store),
.x_is_undef_o(d2x_is_undef),
.x_is_write_ecc_o(d2x_is_write_ecc),
.x_is_fix_ecc_o(d2x_is_fix_ecc),
.x_is_multiply_o(d2x_is_multiply),
.x_is_divide_o(d2x_is_divide),
.x_rd_source_o(d2x_rd_source),
......@@ -332,6 +334,7 @@ module urv_cpu
.d_is_store_i(d2x_is_store),
.d_is_undef_i(d2x_is_undef),
.d_is_write_ecc_i(d2x_is_write_ecc),
.d_is_fix_ecc_i(d2x_is_fix_ecc),
.d_is_multiply_i(d2x_is_multiply),
.d_is_divide_i(d2x_is_divide),
.d_alu_op1_i(d2x_alu_op1),
......
......@@ -63,6 +63,7 @@ module urv_decode
output reg x_is_store_o,
output reg x_is_undef_o,
output reg x_is_write_ecc_o,
output reg x_is_fix_ecc_o,
output reg [2:0] x_rd_source_o,
output x_rd_write_o,
output reg [11:0] x_csr_sel_o,
......@@ -307,6 +308,7 @@ module urv_decode
x_is_mul <= d_is_mul && g_with_hw_mul;
x_is_write_ecc_o <= d_opcode == `OPC_CUST2 && d_fun == `FUNC_WRECC;
x_is_fix_ecc_o <= d_opcode == `OPC_CUST2 && d_fun == `FUNC_FIXECC;
case (d_opcode)
`OPC_BRANCH:
......@@ -408,10 +410,10 @@ module urv_decode
x_csr_imm_o <= f_ir_i[19:15];
x_csr_sel_o <= f_ir_i[31:20];
x_is_csr_o <= (d_opcode == `OPC_SYSTEM) && (d_fun != 0);
x_is_mret_o <= (d_opcode == `OPC_SYSTEM) && (d_fun == 0) && (f_ir_i [31:20] == 12'b0011000_00010);
x_is_mret_o <= (d_opcode == `OPC_SYSTEM) && (d_fun == 0) && (f_ir_i [31:20] == `SYS_IMM_MRET);
if(g_with_hw_debug)
x_is_ebreak_o <= (d_opcode == `OPC_SYSTEM) && (d_fun == 0) && (f_ir_i [31:20] == 12'b0000000_00001);
x_is_ebreak_o <= (d_opcode == `OPC_SYSTEM) && (d_fun == 0) && (f_ir_i [31:20] == `SYS_IMM_EBREAK);
else
x_is_ebreak_o <= 1'b0;
end
......
......@@ -75,6 +75,7 @@
`define FUNC_REMU 3'b111
// funct3 for OPC_SYSTEM
`define CSR_OP_PRIV 3'b000
`define CSR_OP_CSRRW 3'b001
`define CSR_OP_CSRRS 3'b010
`define CSR_OP_CSRRC 3'b011
......@@ -87,6 +88,10 @@
`define FUNC_WRECC `FUNC_SL
`define FUNC_FIXECC `FUNC_SR
// Imm for OPC_SYSTEM, fun3 = 0
`define SYS_IMM_MRET 12'b0011000_00010
`define SYS_IMM_EBREAK 12'b0000000_00001
`define RD_SOURCE_ALU 3'b000
`define RD_SOURCE_SHIFTER 3'b010
`define RD_SOURCE_MULTIPLY 3'b001
......
......@@ -69,6 +69,7 @@ module urv_exec
input d_is_multiply_i,
input d_is_undef_i,
input d_is_write_ecc_i,
input d_is_fix_ecc_i,
input [31:0] d_alu_op1_i,
input [31:0] d_alu_op2_i,
......@@ -270,6 +271,7 @@ module urv_exec
wire [32:0] alu_sub = alu_addsub_op1 - alu_addsub_op2;
// the rest of the ALU
// FIXECC and WRECC uses 'fun' bits used by shift
always@*
case (d_fun_i)
`FUNC_ADD: alu_result <= d_is_add_i ? alu_add[31:0] : alu_sub[31:0];
......@@ -402,8 +404,9 @@ module urv_exec
x_interrupt <= 0;
x_exception_cause <= `CAUSE_ILLEGAL_INSN;
end
else if ((d_use_rs1_i && rf_rs1_ecc_err_i)
|| (d_use_rs2_i && rf_rs2_ecc_err_i))
else if (!d_is_fix_ecc_i
&& ((d_use_rs1_i && rf_rs1_ecc_err_i)
|| (d_use_rs2_i && rf_rs2_ecc_err_i)))
begin
// Ecc error
x_exception <= 1;
......
......@@ -59,7 +59,7 @@ module urv_regmem
integer i;
for(i=0;i<32; i=i+1) begin
ram[i] = 0;
ram[i] = 32'h0;
end
end
// synthesis translate_on
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment