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