Commit c9ce6bfc authored by GuillemCabo's avatar GuillemCabo Committed by Guillem
Browse files

add protected regs as individual modules; add synth results

add plots

results don't look right

correct pass condition SBF test

add 32b hamming and fix tb bugs
parent f0891909
pmu_ahb/
AXI_PMU_interface_v1_0_S00_AXI/
AXI_PMU/
dummy_ahb/
PMU_raw/
......@@ -3,4 +3,6 @@
!*.sh
!*.gtkw
!*.sby
seu_ip/hamming32t26d_dec/
seu_ip/hamming32t26d_enc/
seu_ip/way3_voter/
//-----------------------------------------------------
// ProjectName: De-RISC/SELENE
// Function : Single error corection, double error detection
// Description: This module takes 11 bits of incomming data and computes the checkbits
// for Hamming codes.
// Description: This module takes 16 bit hamming encoded package and
// outputs the corrected data
//
// Coder : G.Cabo
// References : Ben Eater "What is error correction? Hamming codes in hardware" YT
......@@ -23,12 +23,6 @@ module hamming16t11d_dec #
localparam integer N_CHECKB = $clog2(IN_WIDTH) //4
)
(
// Global Clock Signal
//input wire clk_i,
// Global Reset Signal. This Signal is Active LOW
//input wire rstn_i,
// Enable Signal.
//input wire en_i,
// Corrected data
output wire [IN_WIDTH-1:0] data_o,
// Hamming vector
......@@ -36,31 +30,7 @@ module hamming16t11d_dec #
// Double error detection signal
output wire ded_error_o
);
//logic [N_CHECKB-1:0] hcheck_int; // hamming parity bits
//logic ocheck_int; // Overall parity bit
//logic [IN_WIDTH-1:0] data_int; // Encoded data
/*
//Rearrange ingputs
//Data
assign data_int[0]=hv_i[3];
assign data_int[1]=hv_i[5];
assign data_int[2]=hv_i[6];
assign data_int[3]=hv_i[7];
assign data_int[4]=hv_i[9];
assign data_int[5]=hv_i[10];
assign data_int[6]=hv_i[11];
assign data_int[7]=hv_i[12];
assign data_int[8]=hv_i[13];
assign data_int[9]=hv_i[14];
assign data_int[10]=hv_i[15];
//Checkbits
assign ocheck_int=hv_i[0];
assign hcheck_int[0]=hv_i[1];
assign hcheck_int[1]=hv_i[2];
assign hcheck_int[2]=hv_i[4];
assign hcheck_int[3]=hv_i[8];
*/
//Locate errors errors
//Locate errors
logic [N_CHECKB-1:0] region_int;//Each parity "region" and overall.
assign region_int[0] = ^{hv_i[1],hv_i[3],hv_i[5],hv_i[7] ,hv_i[9],hv_i[11],hv_i[13],hv_i[15]};
assign region_int[1] = ^{hv_i[2],hv_i[3],hv_i[6],hv_i[7] ,hv_i[10],hv_i[11],hv_i[14],hv_i[15]};
......
......@@ -23,12 +23,6 @@ module hamming16t11d_enc #
localparam integer N_CHECKB = $clog2(IN_WIDTH) //4
)
(
// Global Clock Signal
//input wire clk_i,
// Global Reset Signal. This Signal is Active LOW
//input wire rstn_i,
// Enable Signal.
//input wire en_i,
// Signal at register input
input wire [IN_WIDTH-1:0] data_i,
// Hamming vector
......
//-----------------------------------------------------
// ProjectName: De-RISC/SELENE
// Function : Single error corection, double error detection
// Description: This module takes 32 bit hamming encoded package and
// outputs the corrected data
//
// Coder : G.Cabo
// References : Ben Eater "What is error correction? Hamming codes in hardware" YT
`default_nettype none
`timescale 1 ns / 1 ps
`ifndef SYNT
`ifdef FORMAL
`define ASSERTIONS
`endif
`endif
module hamming32t26d_dec #
(
// Width of sampled signal
localparam integer IN_WIDTH = 26,
// Number of hamming bits, overall parity bit not included
localparam integer N_CHECKB = $clog2(IN_WIDTH) //5
)
(
// Corrected data
output wire [IN_WIDTH-1:0] data_o,
// Hamming vector
input wire [IN_WIDTH+N_CHECKB:0] hv_i,
// Double error detection signal
output wire ded_error_o
);
//Locate errors
logic [N_CHECKB-1:0] region_int;//Each parity "region" and overall.
assign region_int[0] = ^{hv_i[1],hv_i[3],hv_i[5],hv_i[7],
hv_i[9],hv_i[11],hv_i[13],hv_i[15],
hv_i[17],hv_i[19],hv_i[21],hv_i[23],
hv_i[25],hv_i[27],hv_i[29],hv_i[31]};
assign region_int[1] = ^{hv_i[2],hv_i[3],hv_i[6],hv_i[7],
hv_i[10],hv_i[11],hv_i[14],hv_i[15],
hv_i[18],hv_i[19], hv_i[22],hv_i[23],
hv_i[26],hv_i[27], hv_i[30],hv_i[31] };
assign region_int[2] = ^{hv_i[4],hv_i[5],hv_i[6],hv_i[7],
hv_i[12],hv_i[13],hv_i[14],hv_i[15],
hv_i[20],hv_i[21],hv_i[22],hv_i[23],
hv_i[28],hv_i[29],hv_i[30],hv_i[31]};
assign region_int[3] = ^{hv_i[8],hv_i[9],hv_i[10],hv_i[11],hv_i[12],hv_i[13],hv_i[14],hv_i[15],
hv_i[24],hv_i[25],hv_i[26],hv_i[27],hv_i[28],hv_i[29],hv_i[30],hv_i[31]};
assign region_int[4] = ^{hv_i[16],hv_i[17],hv_i[18],hv_i[19],hv_i[20],hv_i[21],hv_i[22],hv_i[23],
hv_i[24],hv_i[25],hv_i[26],hv_i[27],hv_i[28],hv_i[29],hv_i[30],hv_i[31]};
assign ded_error_o = ~(^hv_i) & (region_int!=0);
//no errors -> data correct
//One or Two region parity bit -> recoverable
//Overall parity 1 -> two errors non-recoverable
//Flip data that needs correction
assign data_o[0]= (3==region_int)? ~hv_i[3] : hv_i[3];
assign data_o[1]= (5==region_int)? ~hv_i[5] : hv_i[5];
assign data_o[2]= (6==region_int)? ~hv_i[6] : hv_i[6];
assign data_o[3]= (7==region_int)? ~hv_i[7] : hv_i[7];
assign data_o[4]= (9==region_int)? ~hv_i[9] : hv_i[9];
assign data_o[5]= (10==region_int)? ~hv_i[10] : hv_i[10];
assign data_o[6]= (11==region_int)? ~hv_i[11] : hv_i[11];
assign data_o[7]= (12==region_int)? ~hv_i[12] : hv_i[12];
assign data_o[8]= (13==region_int)? ~hv_i[13] : hv_i[13];
assign data_o[9]= (14==region_int)? ~hv_i[14] : hv_i[14];
assign data_o[10]= (15==region_int)? ~hv_i[15] : hv_i[15];
assign data_o[11]= (17==region_int)? ~hv_i[17] : hv_i[17];
assign data_o[12]= (18==region_int)? ~hv_i[18] : hv_i[18];
assign data_o[13]= (19==region_int)? ~hv_i[19] : hv_i[19];
assign data_o[14]= (20==region_int)? ~hv_i[20] : hv_i[20];
assign data_o[15]= (21==region_int)? ~hv_i[21] : hv_i[21];
assign data_o[16]= (22==region_int)? ~hv_i[22] : hv_i[22];
assign data_o[17]= (23==region_int)? ~hv_i[23] : hv_i[23];
assign data_o[18]= (24==region_int)? ~hv_i[24] : hv_i[24];
assign data_o[19]= (25==region_int)? ~hv_i[25] : hv_i[25];
assign data_o[20]= (26==region_int)? ~hv_i[26] : hv_i[26];
assign data_o[21]= (27==region_int)? ~hv_i[27] : hv_i[27];
assign data_o[22]= (28==region_int)? ~hv_i[28] : hv_i[28];
assign data_o[23]= (29==region_int)? ~hv_i[29] : hv_i[29];
assign data_o[24]= (30==region_int)? ~hv_i[30] : hv_i[30];
assign data_o[25]= (31==region_int)? ~hv_i[31] : hv_i[31];
////////////////////////////////////////////////////////////////////////////////
//
// Formal Verification section begins here.
//
////////////////////////////////////////////////////////////////////////////////
`ifdef FORMAL
assert (IN_WIDTH==26);
assert (N_CHECKB==5);
`endif
endmodule
`default_nettype wire //allow compatibility with legacy code and xilinx ip
//-----------------------------------------------------
// ProjectName: De-RISC/SELENE
// Function : Single error corection, double error detection
// Description: This module takes 26 bits of incomming data and computes the checkbits
// for Hamming codes.
//
// Coder : G.Cabo
// References : Ben Eater "What is error correction? Hamming codes in hardware" YT
`default_nettype none
`timescale 1 ns / 1 ps
`ifndef SYNT
`ifdef FORMAL
`define ASSERTIONS
`endif
`endif
module hamming32t26d_enc #
(
// Width of sampled signal
localparam integer IN_WIDTH = 26,
// Number of hamming bits
localparam integer N_CHECKB = $clog2(IN_WIDTH) //4
)
(
// Signal at register input
input wire [IN_WIDTH-1:0] data_i,
// Hamming vector
output wire [IN_WIDTH+N_CHECKB:0] hv_o
);
logic [N_CHECKB-1:0] hcheck_int; // hamming parity bits
logic ocheck_int; // Overall parity bit
//Rearrange ingputs
//Data
assign hv_o[3]=data_i[0];
assign hv_o[5]=data_i[1];
assign hv_o[6]=data_i[2];
assign hv_o[7]=data_i[3];
assign hv_o[9]=data_i[4];
assign hv_o[10]=data_i[5];
assign hv_o[11]=data_i[6];
assign hv_o[12]=data_i[7];
assign hv_o[13]=data_i[8];
assign hv_o[14]=data_i[9];
assign hv_o[15]=data_i[10];
assign hv_o[17]=data_i[11];
assign hv_o[18]=data_i[12];
assign hv_o[19]=data_i[13];
assign hv_o[20]=data_i[14];
assign hv_o[21]=data_i[15];
assign hv_o[22]=data_i[16];
assign hv_o[23]=data_i[17];
assign hv_o[24]=data_i[18];
assign hv_o[25]=data_i[19];
assign hv_o[26]=data_i[20];
assign hv_o[27]=data_i[21];
assign hv_o[28]=data_i[22];
assign hv_o[29]=data_i[23];
assign hv_o[30]=data_i[24];
assign hv_o[31]=data_i[25];
//Checkbits
assign hv_o[0]=ocheck_int;
assign hv_o[1]=hcheck_int[0];
assign hv_o[2]=hcheck_int[1];
assign hv_o[4]=hcheck_int[2];
assign hv_o[8]=hcheck_int[3];
assign hv_o[16]=hcheck_int[4];
//compute checkbits
assign hcheck_int[0] = ^{hv_o[3],hv_o[5],hv_o[7],
hv_o[9],hv_o[11],hv_o[13],hv_o[15],
hv_o[17],hv_o[19],hv_o[21],hv_o[23],
hv_o[25],hv_o[27],hv_o[29],hv_o[31]};
assign hcheck_int[1] = ^{hv_o[3],hv_o[6],hv_o[7],
hv_o[10],hv_o[11],hv_o[14],hv_o[15],
hv_o[18],hv_o[19], hv_o[22],hv_o[23],
hv_o[26],hv_o[27], hv_o[30],hv_o[31] };
assign hcheck_int[2] = ^{hv_o[5],hv_o[6],hv_o[7],
hv_o[12],hv_o[13],hv_o[14],hv_o[15],
hv_o[20],hv_o[21],hv_o[22],hv_o[23],
hv_o[28],hv_o[29],hv_o[30],hv_o[31]};
assign hcheck_int[3] = ^{hv_o[9],hv_o[10],hv_o[11],hv_o[12],hv_o[13],hv_o[14],hv_o[15],
hv_o[24],hv_o[25],hv_o[26],hv_o[27],hv_o[28],hv_o[29],hv_o[30],hv_o[31]};
assign hcheck_int[4] = ^{hv_o[17],hv_o[18],hv_o[19],hv_o[20],hv_o[21],hv_o[22],hv_o[23],
hv_o[24],hv_o[25],hv_o[26],hv_o[27],hv_o[28],hv_o[29],hv_o[30],hv_o[31]};
assign ocheck_int = ^hv_o[31:1];
////////////////////////////////////////////////////////////////////////////////
//
// Formal Verification section begins here.
//
////////////////////////////////////////////////////////////////////////////////
`ifdef FORMAL
assert (IN_WIDTH==26);
assert (N_CHECKB==5);
`endif
endmodule
`default_nettype wire //allow compatibility with legacy code and xilinx ip
//-----------------------------------------------------
// ProjectName: De-RISC/SELENE
// Function : Instance of register with hamming SECDEC protection
// Description:
//
// Coder : G.Cabo
// References :
`default_nettype none
`timescale 1 ns / 1 ps
`ifndef SYNT
`ifdef FORMAL
`define ASSERTIONS
`endif
`endif
module ham_reg #
(
// Width of sampled signal
parameter integer IN_WIDTH = 11
)
(
// Global Clock Signal
input wire clk_i,
// Global Reset Signal. This Signal is Active LOW
input wire rstn_i,
// data input
input wire [IN_WIDTH-1:0] din_i,
// data out
output wire [IN_WIDTH-1:0] dout_o,
// Two errors detected NON corrected
output wire error_o
);
logic [16-1:0] ham_preg;
logic [16-1:0] ham_preg_d;
logic [16-1:0] ham_preg_q;
logic [11-1:0] ham_dout;
logic ham_error;
//encoder
hamming16t11d_enc#(
)dut_hamming16t11d_enc (
.data_i(din_i[11-1:0]),
.hv_o(ham_preg_d)
);
// Instance of protected register and output wires
always_ff @(posedge clk_i) begin
if(!rstn_i) begin
ham_preg <= '{default:'0};
end else begin
ham_preg <= ham_preg_d ;
end
end
assign ham_preg_q = ham_preg;
//decoder
hamming16t11d_dec#(
)dut_hamming16t11d_dec (
.data_o(ham_dout),
.hv_i(ham_preg_q),
.ded_error_o(ham_error)
);
assign dout_o = ham_dout;
assign error_o = ham_error;
////////////////////////////////////////////////////////////////////////////////
//
// Formal Verification section begins here.
//
////////////////////////////////////////////////////////////////////////////////
`ifdef FORMAL
`endif
endmodule
`default_nettype wire //allow compatibility with legacy code and xilinx ip
......@@ -50,85 +50,55 @@ module instances #
// Global Reset Signal. This Signal is Active LOW
input wire rstn_i,
// data input
input wire [IN_WIDTH-1:0] din_i
input wire [IN_WIDTH-1:0] din_i,
//Output signals from IPs
output logic com_error,
output logic [IN_WIDTH-1:0] trip_dout,
output logic trip_error1,
output logic trip_error2,
output logic sbf_error,
output logic [11-1:0] ham_dout,
output logic ham_error
);
// Time delayed error detection for COMB - Multiple bits error detection
// Triplicated register - Multiple bits error detection
generate begin:triple
logic [IN_WIDTH-1:0] trip0_preg;
logic [IN_WIDTH-1:0] trip1_preg;
logic [IN_WIDTH-1:0] trip2_preg;
logic [IN_WIDTH-1:0] trip_preg_d;
logic [IN_WIDTH-1:0] trip0_preg_q;
logic [IN_WIDTH-1:0] trip1_preg_q;
logic [IN_WIDTH-1:0] trip2_preg_q;
logic trip_error1;
logic trip_error2;
logic [IN_WIDTH-1:0] trip_dout;
assign trip_preg_d = din_i;
assign trip0_preg_q = trip0_preg;
assign trip1_preg_q = trip1_preg;
assign trip2_preg_q = trip2_preg;
always_ff @(posedge clk_i) begin
if(!rstn_i) begin
trip0_preg <= '{default:'0};
trip1_preg <= '{default:'0};
trip2_preg <= '{default:'0};
end else begin
trip0_preg <= trip_preg_d;
trip1_preg <= trip_preg_d;
trip1_preg <= trip_preg_d;
end
end
way3_voter #(
com_tr #(
.IN_WIDTH(IN_WIDTH)
)dut_way3(
.in0(trip0_preg_q),
.in1(trip1_preg_q),
.in2(trip2_preg_q),
.out(trip_dout),
.error1_o(trip_error1),
.error2_o(trip_error2)
)dut_com_tr (
.clk_i(clk_i),
.dclk_i(dclk_i),
.rstn_i(rstn_i),
.signal_i(din_i),
.error_o(com_error)
);
end
endgenerate
// Parity bit - Single error detection
// Protected register and auxiliar logic
generate begin:sbf
logic [IN_WIDTH-1:0] sbf_preg;
logic [IN_WIDTH-1:0] sbf_preg_d;
logic [IN_WIDTH-1:0] sbf_preg_q;
logic sbf_error;
assign sbf_preg_d = din_i;
always_ff @(posedge clk_i) begin
if(!rstn_i) begin
sbf_preg <= '{default:'0};
end else begin
sbf_preg <= sbf_preg_d;
end
end
assign sbf_preg_q = sbf_preg;
//***Module***
reg_sbf #(
.IN_WIDTH(IN_WIDTH)
)dut_reg_sbf (
.clk_i(clk_i),
.rstn_i(rstn_i),
.regi_i(sbf_preg_d),
.rego_i(sbf_preg_q),
.error_o(sbf_error)
// Triplicated register - Multiple bits error detection
triple_reg#(.IN_WIDTH(IN_WIDTH)
)dut_trip(
.clk_i(clk_i),
.rstn_i(rstn_i),
.din_i(din_i),
.dout_o(trip_dout),
.error1_o(trip_error1),
.error2_o(trip_error2)
);
end
endgenerate
// Parity bit - Single error detection
sbf_reg#(.IN_WIDTH(IN_WIDTH)
)dut_sbf(
.clk_i(clk_i),
.rstn_i(rstn_i),
.din_i(din_i),
.error_o(sbf_error)
);
// Hamming - SECDEC
//TODO: Hamming is not parametrtic
ham_reg#(.IN_WIDTH(11)
)dut_ham(
.clk_i(clk_i),
.rstn_i(rstn_i),
.din_i(din_i[10:0]),
.dout_o(ham_dout),
.error_o(ham_error)
);
////////////////////////////////////////////////////////////////////////////////
//
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -13,6 +13,5 @@ wait
echo "1/1 runs done"
echo "Done! Reporting area & cycle time"
cd logs
ack "Chip area for top module "
ack "Delay "
ack "netlist of module"\|"Delay"\|"area"
cd ..
//-----------------------------------------------------
// ProjectName: De-RISC/SELENE
// Function : Instance of register with parity bit detection
// Description:
//
// Coder : G.Cabo
// References :
`default_nettype none
`timescale 1 ns / 1 ps
`ifndef SYNT
`ifdef FORMAL
`define ASSERTIONS
`endif
`endif
module sbf_reg #
(
// Width of sampled signal
parameter integer IN_WIDTH = 4
)
(
// Global Clock Signal
input wire clk_i,
// Global Reset Signal. This Signal is Active LOW
input wire rstn_i,
// data input
input wire [IN_WIDTH-1:0] din_i,
// error detected
output wire error_o
);
logic [IN_WIDTH-1:0] sbf_preg;
logic [IN_WIDTH-1:0] sbf_preg_d;
logic [IN_WIDTH-1:0] sbf_preg_q;
logic sbf_error;
assign sbf_preg_d = din_i;
always_ff @(posedge clk_i) begin
if(!rstn_i) begin
sbf_preg <= '{default:'0};
end else begin
sbf_preg <= sbf_preg_d;
end
end
assign sbf_preg_q = sbf_preg;
reg_sbf #(
.IN_WIDTH(IN_WIDTH)
)dut_reg_sbf (
.clk_i(clk_i),
.rstn_i(rstn_i),
.regi_i(sbf_preg_d),
.rego_i(sbf_preg_q),
.error_o(error_o)
);
////////////////////////////////////////////////////////////////////////////////
//
// Formal Verification section begins here.
//
////////////////////////////////////////////////////////////////////////////////
`ifdef FORMAL
`endif
endmodule
`default_nettype wire //allow compatibility with legacy code and xilinx ip
This diff is collapsed.