Commit c824038b authored by Tristan Gingold's avatar Tristan Gingold

rtl: writeecc set per bank ecc

parent f54d0098
......@@ -111,6 +111,7 @@ module urv_cpu
wire [4:0] rf_rd;
wire [31:0] rf_rd_value;
wire [6:0] rf_rd_ecc;
wire [1:0] rf_rd_ecc_flip;
wire rf_rd_write;
// D->X1 stage interface
......@@ -149,7 +150,7 @@ module urv_cpu
wire x2w_load;
wire [1:0] x2w_rd_source;
wire x2w_valid;
wire x2w_ecc_flip;
wire [1:0] x2w_ecc_flip;
// Register file signals
wire [31:0] x_rs2_value, x_rs1_value;
......@@ -281,6 +282,7 @@ module urv_cpu
.w_rd_i(rf_rd),
.w_rd_value_i(rf_rd_value),
.w_rd_ecc_i(rf_rd_ecc),
.w_rd_ecc_flip_i(rf_rd_ecc_flip),
.w_rd_store_i(rf_rd_write),
.w_bypass_rd_write_i(rf_bypass_rd_write),
......@@ -413,6 +415,7 @@ module urv_cpu
// to register file
.rf_rd_value_o(rf_rd_value),
.rf_rd_ecc_o(rf_rd_ecc),
.rf_rd_ecc_flip_o(rf_rd_ecc_flip),
.rf_rd_o(rf_rd),
.rf_rd_write_o(rf_rd_write)
);
......
......@@ -101,7 +101,7 @@ module urv_exec
output reg [1:0] w_rd_source_o,
output [31:0] w_rd_shifter_o,
output [31:0] w_rd_multiply_o,
output reg w_ecc_flip_o,
output reg [1:0] w_ecc_flip_o,
// Data memory I/F (address/store)
......@@ -509,7 +509,7 @@ module urv_exec
f_dbg_toggle_o <= 0;
w_load_o <= 0;
w_store_o <= 0;
w_ecc_flip_o <= 0;
w_ecc_flip_o <= 2'b0;
// Values so that 0 could be written to register 0.
w_rd_value_o <= 0;
w_rd_o <= 0;
......@@ -527,7 +527,7 @@ module urv_exec
f_branch_target_o <= branch_target;
w_rd_o <= d_rd_i;
w_rd_value_o <= rd_value;
w_ecc_flip_o <= d_is_write_ecc_i & rs2[0];
w_ecc_flip_o <= {2{d_is_write_ecc_i}} & rs2[1:0];
f_branch_take <= branch_take && !x_kill_i && d_valid_i;
f_dbg_toggle_o <= g_with_hw_debug && d_is_ebreak_i && !x_kill_i && d_valid_i;
......
......@@ -90,6 +90,7 @@ module urv_regfile
input [4:0] w_rd_i,
input [31:0] w_rd_value_i,
input [6:0] w_rd_ecc_i,
input [1:0] w_rd_ecc_flip_i,
input w_rd_store_i,
input w_bypass_rd_write_i,
......@@ -98,6 +99,8 @@ module urv_regfile
localparam g_width = 32 + (g_with_ecc ? 7 : 0);
wire [g_width-1:0] w_rd_value_1;
wire [g_width-1:0] w_rd_value_2;
wire [g_width-1:0] rs1_regfile;
wire [g_width-1:0] rs2_regfile;
wire write = w_rd_store_i;
......@@ -108,11 +111,20 @@ module urv_regfile
// Value to be written in the register file
wire [g_width-1:0] w_rd_value;
assign w_rd_value = g_with_ecc ? {w_rd_ecc_i, w_rd_value_i} : w_rd_value_i;
generate
if (g_with_ecc) begin
assign w_rd_value_1 = {w_rd_ecc_i ^ w_rd_ecc_flip_i[0], w_rd_value_i};
assign w_rd_value_2 = {w_rd_ecc_i ^ w_rd_ecc_flip_i[1], w_rd_value_i};
end
else begin
assign w_rd_value_1 = w_rd_value_i;
assign w_rd_value_2 = w_rd_value_i;
end
endgenerate
urv_regmem
#(.g_width(g_width))
bank0
bank1
(
.clk_i(clk_i),
.en1_i(!d_stall_i),
......@@ -120,12 +132,12 @@ module urv_regfile
.q1_o(rs1_regfile),
.a2_i(w_rd_i),
.d2_i(w_rd_value),
.d2_i(w_rd_value_1),
.we2_i (write));
urv_regmem
#(.g_width(g_width))
bank1
bank2
(
.clk_i(clk_i),
.en1_i(!d_stall_i),
......@@ -133,7 +145,7 @@ module urv_regfile
.q1_o(rs2_regfile),
.a2_i (w_rd_i),
.d2_i (w_rd_value),
.d2_i (w_rd_value_2),
.we2_i (write)
);
......
......@@ -52,7 +52,7 @@ module urv_writeback
input [31:0] x_shifter_rd_value_i,
input [31:0] x_multiply_rd_value_i,
input [1:0] x_rd_source_i,
input x_ecc_flip_i,
input [1:0] x_ecc_flip_i,
input [31:0] dm_data_l_i,
input dm_load_done_i,
......@@ -61,6 +61,7 @@ module urv_writeback
output [31:0] rf_rd_value_o,
output [4:0] rf_rd_o,
output [6:0] rf_rd_ecc_o,
output [1:0] rf_rd_ecc_flip_o,
output rf_rd_write_o
);
......@@ -68,45 +69,43 @@ module urv_writeback
// generate load value
always@*
begin
case (x_fun_i)
`LDST_B:
case ( x_dm_addr_i [1:0] )
2'b00: load_value <= {{24{dm_data_l_i[7]}}, dm_data_l_i[7:0] };
2'b01: load_value <= {{24{dm_data_l_i[15]}}, dm_data_l_i[15:8] };
2'b10: load_value <= {{24{dm_data_l_i[23]}}, dm_data_l_i[23:16] };
2'b11: load_value <= {{24{dm_data_l_i[31]}}, dm_data_l_i[31:24] };
default: load_value <= 32'hx;
endcase // case ( x_dm_addr_i [1:0] )
`LDST_BU:
case ( x_dm_addr_i [1:0] )
2'b00: load_value <= {24'h0, dm_data_l_i[7:0] };
2'b01: load_value <= {24'h0, dm_data_l_i[15:8] };
2'b10: load_value <= {24'h0, dm_data_l_i[23:16] };
2'b11: load_value <= {24'h0, dm_data_l_i[31:24] };
default: load_value <= 32'hx;
endcase // case ( x_dm_addr_i [1:0] )
`LDST_H:
case ( x_dm_addr_i [1:0] )
2'b00, 2'b01: load_value <= {{16{dm_data_l_i[15]}}, dm_data_l_i[15:0] };
2'b10, 2'b11: load_value <= {{16{dm_data_l_i[31]}}, dm_data_l_i[31:16] };
default: load_value <= 32'hx;
endcase // case ( x_dm_addr_i [1:0] )
`LDST_HU:
case ( x_dm_addr_i [1:0] )
2'b00, 2'b01: load_value <= {16'h0, dm_data_l_i[15:0] };
2'b10, 2'b11: load_value <= {16'h0, dm_data_l_i[31:16] };
default: load_value <= 32'hx;
endcase // case ( x_dm_addr_i [1:0] )
`LDST_L: load_value <= dm_data_l_i;
default: load_value <= 32'hx;
endcase // case (d_fun_i)
end // always@ *
case (x_fun_i)
`LDST_B:
case ( x_dm_addr_i [1:0] )
2'b00: load_value <= {{24{dm_data_l_i[7]}}, dm_data_l_i[7:0] };
2'b01: load_value <= {{24{dm_data_l_i[15]}}, dm_data_l_i[15:8] };
2'b10: load_value <= {{24{dm_data_l_i[23]}}, dm_data_l_i[23:16] };
2'b11: load_value <= {{24{dm_data_l_i[31]}}, dm_data_l_i[31:24] };
default: load_value <= 32'hx;
endcase // case ( x_dm_addr_i [1:0] )
`LDST_BU:
case ( x_dm_addr_i [1:0] )
2'b00: load_value <= {24'h0, dm_data_l_i[7:0] };
2'b01: load_value <= {24'h0, dm_data_l_i[15:8] };
2'b10: load_value <= {24'h0, dm_data_l_i[23:16] };
2'b11: load_value <= {24'h0, dm_data_l_i[31:24] };
default: load_value <= 32'hx;
endcase // case ( x_dm_addr_i [1:0] )
`LDST_H:
case ( x_dm_addr_i [1] )
1'b0: load_value <= {{16{dm_data_l_i[15]}}, dm_data_l_i[15:0] };
1'b1: load_value <= {{16{dm_data_l_i[31]}}, dm_data_l_i[31:16] };
default: load_value <= 32'hx;
endcase // case ( x_dm_addr_i [1:0] )
`LDST_HU:
case ( x_dm_addr_i [1] )
1'b0: load_value <= {16'h0, dm_data_l_i[15:0] };
1'b1: load_value <= {16'h0, dm_data_l_i[31:16] };
default: load_value <= 32'hx;
endcase // case ( x_dm_addr_i [1:0] )
`LDST_L: load_value <= dm_data_l_i;
default: load_value <= 32'hx;
endcase // case (d_fun_i)
reg rf_rd_write;
reg [31:0] rf_rd_value;
......@@ -141,7 +140,8 @@ module urv_writeback
urv_ecc gen_ecc
(.dat_i(rf_rd_value),
.ecc_o(rf_rd_ecc));
assign rf_rd_ecc_o = rf_rd_ecc ^ x_ecc_flip_i;
assign rf_rd_ecc_o = rf_rd_ecc;
assign rf_rd_ecc_flip_o = x_ecc_flip_i;
end
else
assign rf_rd_ecc_o = 6'bx;
......
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