blob: b292d5181a000c4bb205e5bb92e80654c0c6a9cf [file] [log] [blame]
`default_nettype none
//-----------------------------------------------------
// Project Name : Register File
// Function : Rergiter bank data
// Description : This is the main processor
// Coder : Ivan Rodriguez Ferrandez AND Alvaro Jover-Alvarez
//***Headers***
//***Module***
module register_data #(
parameter integer WORD_SIZE = 32,
parameter integer REGISTERS = 32,
parameter integer SEGMENTS = 8 ,
parameter integer REGDIRSIZE = 5,
parameter integer ECCBITS = 7,
parameter integer WHISBONE_ADR = 32,
parameter [31:0] ADDRBASE = 32'h3000_0000,
parameter [31:0] REGISTERDATA = ADDRBASE
)
(
`ifdef USE_POWER_PINS
inout vdda1, // User area 1 3.3V supply
inout vdda2, // User area 2 3.3V supply
inout vssa1, // User area 1 analog ground
inout vssa2, // User area 2 analog ground
inout vccd1, // User area 1 1.8V supply
inout vccd2, // User area 2 1.8v supply
inout vssd1, // User area 1 digital ground
inout vssd2, // User area 2 digital ground
`endif
input clk_i,
input rst_i ,
input [WORD_SIZE + ECCBITS - 1 : 0] data_to_register_i,
//input [((REGISTERS/ SEGMENTS) * (WORD_SIZE + ECCBITS)) - 1 : 0] data_to_register_i, // 156 interface
input [REGDIRSIZE - 1 : 0] register_i ,
input [WHISBONE_ADR - 1 : 0] whisbone_addr_i,
input operation_type_i,
input wregister_i ,
input rregister_i ,
input valid_i,
input [3 : 0] wstrb_i,
input [WORD_SIZE -1 : 0] wdata_i,
input wbs_we_i,
output reg [WORD_SIZE + ECCBITS -1: 0] store_data_o ,
//output reg [((REGISTERS/ SEGMENTS) * (WORD_SIZE + ECCBITS)) - 1 : 0] store_data_o , // 156 interface
output reg ready_o,
output reg [WORD_SIZE - 1 : 0] rdata_o,
output reg [1:0] triple_redundat_validation_o
);
//***Internal logic generated by compiler***
//***Dumped Internal logic***
// wires
wire [WORD_SIZE - 1 : 0] nand_1;
wire [WORD_SIZE - 1 : 0] nand_2;
wire [WORD_SIZE - 1 : 0] nand_3;
wire [WORD_SIZE - 1 : 0] xor_1;
wire [WORD_SIZE - 1 : 0] xor_2;
wire [WORD_SIZE - 1 : 0] xor_3;
wire xor_reduce_1;
wire xor_reduce_2;
wire xor_reduce_3;
wire correted_triple;
wire uncorreted_triple;
// register bank
reg [((REGISTERS/ SEGMENTS) * (WORD_SIZE + ECCBITS)) - 1 : 0 ] r[0:SEGMENTS-1];
//triple_redunancy calculation
assign nand_1 = rregister_i & operation_type_i ? r[register_i[REGDIRSIZE - 1: 2]][31:0] ~& r[register_i[REGDIRSIZE - 1: 2]][63:32]: {WORD_SIZE + ECCBITS{1'b0}};
assign nand_2 = rregister_i & operation_type_i ? r[register_i[REGDIRSIZE - 1: 2]][63:32] ~& r[register_i[REGDIRSIZE - 1: 2]][95:64]: {WORD_SIZE + ECCBITS{1'b0}};
assign nand_3 = rregister_i & operation_type_i ? r[register_i[REGDIRSIZE - 1: 2]][31:0] ~& r[register_i[REGDIRSIZE - 1: 2]][95:64]: {WORD_SIZE + ECCBITS{1'b0}};
//triple_redunancy status
assign xor_1 = rregister_i & operation_type_i ? r[register_i[REGDIRSIZE - 1: 2]][31:0] ^ r[register_i[REGDIRSIZE - 1: 2]][63:32] : {WORD_SIZE + ECCBITS{1'b0}};
assign xor_2 = rregister_i & operation_type_i ? r[register_i[REGDIRSIZE - 1: 2]][63:32] ^ r[register_i[REGDIRSIZE - 1: 2]][95:64]: {WORD_SIZE + ECCBITS{1'b0}};
assign xor_3 = rregister_i & operation_type_i ? r[register_i[REGDIRSIZE - 1: 2]][31:0] ^ r[register_i[REGDIRSIZE - 1: 2]][95:64]: {WORD_SIZE + ECCBITS{1'b0}};
assign xor_reduce_1 = |xor_1;
assign xor_reduce_2 = |xor_2;
assign xor_reduce_3 = |xor_3;
always @(posedge clk_i) begin
// calculate last parity bit
if (rst_i) begin
r[0] = {((REGISTERS/ SEGMENTS) * (WORD_SIZE + ECCBITS)){1'b0}};
r[1] = {((REGISTERS/ SEGMENTS) * (WORD_SIZE + ECCBITS)){1'b0}};
r[2] = {((REGISTERS/ SEGMENTS) * (WORD_SIZE + ECCBITS)){1'b0}};
r[3] = {((REGISTERS/ SEGMENTS) * (WORD_SIZE + ECCBITS)){1'b0}};
r[4] = {((REGISTERS/ SEGMENTS) * (WORD_SIZE + ECCBITS)){1'b0}};
r[5] = {((REGISTERS/ SEGMENTS) * (WORD_SIZE + ECCBITS)){1'b0}};
r[6] = {((REGISTERS/ SEGMENTS) * (WORD_SIZE + ECCBITS)){1'b0}};
r[7] = {((REGISTERS/ SEGMENTS) * (WORD_SIZE + ECCBITS)){1'b0}};
ready_o <= 1'b0;
store_data_o <= {WORD_SIZE + ECCBITS{1'b0}};
triple_redundat_validation_o <= 2'b00;
end
else if (rregister_i & ~operation_type_i) begin
case (register_i[1:0])
2'b00: begin
store_data_o <= r[register_i[REGDIRSIZE - 1: 2]][38:0];
end
2'b01: begin
store_data_o <= r[register_i[REGDIRSIZE - 1: 2]][77:39];
end
2'b10: begin
store_data_o <= r[register_i[REGDIRSIZE - 1: 2]][116:78];
end
2'b11: begin
store_data_o <= r[register_i[REGDIRSIZE - 1: 2]][155:117];
end
endcase
triple_redundat_validation_o <= 2'b00;
end
else if (rregister_i & operation_type_i) begin
triple_redundat_validation_o[0] <= (xor_reduce_1 ^ xor_reduce_2) | (xor_reduce_2 ^ xor_reduce_3);
triple_redundat_validation_o[1] <= xor_reduce_1 & xor_reduce_2 & xor_reduce_3 ;
store_data_o[31:0] <= ~(nand_1 & nand_2 & nand_3);
//store_data_o <= ~((r[register_i[REGDIRSIZE - 1: 2]][31:0] ~& r[register_i[REGDIRSIZE - 1: 2]][63:32]) & (r[register_i[REGDIRSIZE - 1: 2]][63:32] ~& r[register_i[REGDIRSIZE - 1: 2]][95:64]) & (r[register_i[REGDIRSIZE - 1: 2]][31:0] ~& r[register_i[REGDIRSIZE - 1: 2]][95:64]));
end
else if (wregister_i & ~operation_type_i) begin
// Sore data
case (register_i[1:0])
2'b00: begin
r[register_i[REGDIRSIZE - 1: 2]][38:0] <= data_to_register_i;
end
2'b01: begin
r[register_i[REGDIRSIZE - 1: 2]][77:39] <= data_to_register_i;
end
2'b10: begin
r[register_i[REGDIRSIZE - 1: 2]][116:78] <= data_to_register_i;
end
2'b11: begin
r[register_i[REGDIRSIZE - 1: 2]][155:117] <= data_to_register_i;
end
endcase
store_data_o <= {WORD_SIZE + ECCBITS{1'b0}};
triple_redundat_validation_o <= 2'b00;
end
else if (wregister_i & operation_type_i) begin
r[register_i[REGDIRSIZE - 1: 2]][95:0] <= {data_to_register_i[31:0],data_to_register_i[31:0],data_to_register_i[31:0]};
store_data_o <= {WORD_SIZE + ECCBITS{1'b0}};
triple_redundat_validation_o <= 2'b00;
end
if (valid_i) begin
case (whisbone_addr_i)
REGISTERDATA: begin // the test register is 30 now in order to acomodate testing of the ECC and triple redundacy
ready_o <= 1'b1;
if (wbs_we_i) begin
if (wstrb_i[0]) r[7][85:78] <= wdata_i[7:0];
if (wstrb_i[1]) r[7][93:86] <= wdata_i[15:8];
if (wstrb_i[2]) r[7][101:94] <= wdata_i[23:16];
if (wstrb_i[3]) r[7][109:102] <= wdata_i[31:24];
end
else begin
rdata_o <= {r[7][148:117]};
end
end
ADDRBASE + 4: begin ready_o <= 1'b1; end
ADDRBASE + 8: begin ready_o <= 1'b1; end
ADDRBASE + 16: begin ready_o <= 1'b1; end
default: ready_o <= 1'b0;
endcase
end
end
endmodule