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

rtl: add fix_ecc instruction

parent 706d34d2
...@@ -125,6 +125,7 @@ module urv_cpu ...@@ -125,6 +125,7 @@ module urv_cpu
wire d2x_shifter_sign; wire d2x_shifter_sign;
wire d2x_is_load, d2x_is_store, d2x_is_undef; wire d2x_is_load, d2x_is_store, d2x_is_undef;
wire d2x_is_write_ecc; wire d2x_is_write_ecc;
wire d2x_is_fix_ecc;
wire [31:0] d2x_imm; wire [31:0] d2x_imm;
wire d2x_is_signed_alu_op; wire d2x_is_signed_alu_op;
wire d2x_is_add_o; wire d2x_is_add_o;
...@@ -243,6 +244,7 @@ module urv_cpu ...@@ -243,6 +244,7 @@ module urv_cpu
.x_is_store_o(d2x_is_store), .x_is_store_o(d2x_is_store),
.x_is_undef_o(d2x_is_undef), .x_is_undef_o(d2x_is_undef),
.x_is_write_ecc_o(d2x_is_write_ecc), .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_multiply_o(d2x_is_multiply),
.x_is_divide_o(d2x_is_divide), .x_is_divide_o(d2x_is_divide),
.x_rd_source_o(d2x_rd_source), .x_rd_source_o(d2x_rd_source),
...@@ -332,6 +334,7 @@ module urv_cpu ...@@ -332,6 +334,7 @@ module urv_cpu
.d_is_store_i(d2x_is_store), .d_is_store_i(d2x_is_store),
.d_is_undef_i(d2x_is_undef), .d_is_undef_i(d2x_is_undef),
.d_is_write_ecc_i(d2x_is_write_ecc), .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_multiply_i(d2x_is_multiply),
.d_is_divide_i(d2x_is_divide), .d_is_divide_i(d2x_is_divide),
.d_alu_op1_i(d2x_alu_op1), .d_alu_op1_i(d2x_alu_op1),
......
...@@ -63,6 +63,7 @@ module urv_decode ...@@ -63,6 +63,7 @@ module urv_decode
output reg x_is_store_o, output reg x_is_store_o,
output reg x_is_undef_o, output reg x_is_undef_o,
output reg x_is_write_ecc_o, output reg x_is_write_ecc_o,
output reg x_is_fix_ecc_o,
output reg [2:0] x_rd_source_o, output reg [2:0] x_rd_source_o,
output x_rd_write_o, output x_rd_write_o,
output reg [11:0] x_csr_sel_o, output reg [11:0] x_csr_sel_o,
...@@ -307,6 +308,7 @@ module urv_decode ...@@ -307,6 +308,7 @@ module urv_decode
x_is_mul <= d_is_mul && g_with_hw_mul; 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_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) case (d_opcode)
`OPC_BRANCH: `OPC_BRANCH:
...@@ -408,10 +410,10 @@ module urv_decode ...@@ -408,10 +410,10 @@ module urv_decode
x_csr_imm_o <= f_ir_i[19:15]; x_csr_imm_o <= f_ir_i[19:15];
x_csr_sel_o <= f_ir_i[31:20]; x_csr_sel_o <= f_ir_i[31:20];
x_is_csr_o <= (d_opcode == `OPC_SYSTEM) && (d_fun != 0); 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) 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 else
x_is_ebreak_o <= 1'b0; x_is_ebreak_o <= 1'b0;
end end
......
...@@ -75,6 +75,7 @@ ...@@ -75,6 +75,7 @@
`define FUNC_REMU 3'b111 `define FUNC_REMU 3'b111
// funct3 for OPC_SYSTEM // funct3 for OPC_SYSTEM
`define CSR_OP_PRIV 3'b000
`define CSR_OP_CSRRW 3'b001 `define CSR_OP_CSRRW 3'b001
`define CSR_OP_CSRRS 3'b010 `define CSR_OP_CSRRS 3'b010
`define CSR_OP_CSRRC 3'b011 `define CSR_OP_CSRRC 3'b011
...@@ -87,6 +88,10 @@ ...@@ -87,6 +88,10 @@
`define FUNC_WRECC `FUNC_SL `define FUNC_WRECC `FUNC_SL
`define FUNC_FIXECC `FUNC_SR `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_ALU 3'b000
`define RD_SOURCE_SHIFTER 3'b010 `define RD_SOURCE_SHIFTER 3'b010
`define RD_SOURCE_MULTIPLY 3'b001 `define RD_SOURCE_MULTIPLY 3'b001
......
...@@ -69,6 +69,7 @@ module urv_exec ...@@ -69,6 +69,7 @@ module urv_exec
input d_is_multiply_i, input d_is_multiply_i,
input d_is_undef_i, input d_is_undef_i,
input d_is_write_ecc_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_op1_i,
input [31:0] d_alu_op2_i, input [31:0] d_alu_op2_i,
...@@ -270,6 +271,7 @@ module urv_exec ...@@ -270,6 +271,7 @@ module urv_exec
wire [32:0] alu_sub = alu_addsub_op1 - alu_addsub_op2; wire [32:0] alu_sub = alu_addsub_op1 - alu_addsub_op2;
// the rest of the ALU // the rest of the ALU
// FIXECC and WRECC uses 'fun' bits used by shift
always@* always@*
case (d_fun_i) case (d_fun_i)
`FUNC_ADD: alu_result <= d_is_add_i ? alu_add[31:0] : alu_sub[31:0]; `FUNC_ADD: alu_result <= d_is_add_i ? alu_add[31:0] : alu_sub[31:0];
...@@ -402,8 +404,9 @@ module urv_exec ...@@ -402,8 +404,9 @@ module urv_exec
x_interrupt <= 0; x_interrupt <= 0;
x_exception_cause <= `CAUSE_ILLEGAL_INSN; x_exception_cause <= `CAUSE_ILLEGAL_INSN;
end end
else if ((d_use_rs1_i && rf_rs1_ecc_err_i) else if (!d_is_fix_ecc_i
|| (d_use_rs2_i && rf_rs2_ecc_err_i)) && ((d_use_rs1_i && rf_rs1_ecc_err_i)
|| (d_use_rs2_i && rf_rs2_ecc_err_i)))
begin begin
// Ecc error // Ecc error
x_exception <= 1; x_exception <= 1;
......
...@@ -59,7 +59,7 @@ module urv_regmem ...@@ -59,7 +59,7 @@ module urv_regmem
integer i; integer i;
for(i=0;i<32; i=i+1) begin for(i=0;i<32; i=i+1) begin
ram[i] = 0; ram[i] = 32'h0;
end end
end end
// synthesis translate_on // 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