Commit 17bd62e5 authored by GuillemCabo's avatar GuillemCabo Committed by Guillem
Browse files

WIP - add FT slv_reg

Questa TB pass, FV fails
parent 49f42976
......@@ -33,6 +33,8 @@
parameter integer N_SOC_EV = 128,
// Total amount of registers (use ahb_pmu_mem_map.ods)
parameter integer N_REGS = 55,
// Fault tolerance mechanisms (FT==0 -> FT disabled)
parameter integer FT = 1,
// -- Local parameters
//haddr width
localparam integer HADDR_WIDTH = 32,
......@@ -82,7 +84,9 @@
// MCCU interruption for exceeded quota. One signal per core
output wire [MCCU_N_CORES-1:0] intr_MCCU_o,
// RDC (Request Duration Counter) interruption for exceeded quota
output wire intr_RDC_o
output wire intr_RDC_o,
// FT (Fault tolerance) interrupt, error detected but not recoverable
output wire intr_FT_o
);
//----------------------------------------------
// VIVADO: list of debug signals for ILA
......@@ -184,10 +188,17 @@ var struct packed{
//----------------------------------------------
//------------- AHB registers
//----------------------------------------------
wire [REG_WIDTH-1:0] pmu_regs_int [0:N_REGS-1];
logic [HDATA_WIDTH-1:0] dwrite_slave; //Data master to the register bank
logic [1:0] complete_transfer_status;
logic [HDATA_WIDTH-1:0] dread_slave; //response from slave
wire [$clog2(N_REGS)-1:0] slv_index;
logic [REG_WIDTH-1:0] slv_reg [0:N_REGS-1];
logic [REG_WIDTH-1:0] slv_reg_D [0:N_REGS-1];
logic [REG_WIDTH-1:0] slv_reg_Q [0:N_REGS-1];
generate
if (FT==0) begin
always_ff @(posedge clk_i) begin
if(rstn_i == 1'b0 ) begin
slv_reg<='{default:0};
......@@ -195,6 +206,160 @@ var struct packed{
slv_reg <= slv_reg_D;
end
end
//----------------------------------------------
//------------- Slave registers update
//----------------------------------------------
//Each cycle the values in slv_reg_D will be saved in slv_reg
//So if you want to update slv_reg the values for slv_reg_D shall be
//assigned in this section
//If you add aditional logic that can change the values of the registers
//the next always block have to be modified to add the aditional
//conditions under which the slv_reg shall be updated
always_comb begin
//AHB write
//Write to slv registers if slave was selected & was a write. Else
//register the values given by pmu_raw
if(address_phase.write && address_phase.select) begin
// get the values from the pmu_raw instance
slv_reg_Q = slv_reg;
slv_reg_Q [slv_index] = dwrite_slave;
slv_reg_D = pmu_regs_int;
slv_reg_D[slv_index] = dwrite_slave;
end else begin
slv_reg_D = pmu_regs_int;
slv_reg_Q = slv_reg;
end
end
assign intr_FT_o = 1'b0;
end else begin
//FT version of the registers
// Hamming bits, 6 for each 26 bits of data
localparam HAM_P=6;//protection bits
localparam HAM_D=26;//data bits
localparam HAM_M=HAM_P+HAM_D;//mesage bits
localparam N_HAM32_SLV= (((REG_WIDTH*N_REGS)+(HAM_D-1))/(HAM_D));
//interrupt FT error
wire [N_HAM32_SLV-1:0] ift_slv; //interrupt fault tolerance mechanism
//"Flat" slv_reg Q and D signals
wire [N_HAM32_SLV*HAM_D-1:0] slv_reg_fti;//fault tolerance in
wire [N_HAM32_SLV*HAM_D-1:0] slv_reg_fto;//fault tolerance out
wire [REG_WIDTH-1:0] slv_reg_ufto [0:N_REGS-1];//unpacked fault tolerance out
wire [N_HAM32_SLV*HAM_D-1:0] slv_reg_pQ ;//protected output
//"Flat" hamming messages (Data+parity bits)
wire [(HAM_M*N_HAM32_SLV)-1:0] ham_mbits_D;
wire [(HAM_M*N_HAM32_SLV)-1:0] ham_mbits_Q;
//Registers for parity bits
logic [HAM_P*N_HAM32_SLV-1:0] ham_pbits;
//Feed and send flat assigment in to original format
for (genvar i =0; i<N_REGS; i++) begin
//assign slv_register inputs to a flat hamming input
assign slv_reg_fti[(i+1)*REG_WIDTH-1:i*REG_WIDTH]=slv_reg_D[i][REG_WIDTH-1:0];
end
// SEC-DEC hamming on 26 bit data chunks
for (genvar i =0; i<(N_HAM32_SLV); i++) begin : slv_ham_enc
//encoder
//hv_o needs to inteleave protection and data bits
hamming32t26d_enc#(
)dut_hamming32t26d_enc (
.data_i(slv_reg_fti[(i+1)*HAM_D-1:i*HAM_D]),
.hv_o(ham_mbits_D[(i+1)*(HAM_M)-1:i*(HAM_M)])
);
end
//Feed data into original registers
for (genvar i =0; i<N_REGS; i++) begin
always_ff @(posedge clk_i) begin
if(rstn_i == 1'b0 ) begin
slv_reg[i]<='{default:0};
end else begin
//You could be using ham_mbits_D but code is longer
//Some of the ham_mbits_D aren't needed
slv_reg[i] <= slv_reg_fti[(i+1)*REG_WIDTH-1:REG_WIDTH*i];
end
end
assign slv_reg_pQ[(i+1)*REG_WIDTH-1:i*REG_WIDTH] = slv_reg[i];
end
// pad signals to fill an integer number of 26 bit chunks
for (genvar i =(N_REGS)*REG_WIDTH; i<N_HAM32_SLV*HAM_D; i++) begin
assign slv_reg_pQ[i] = 1'b0;
assign slv_reg_fti[i] = 1'b0;
end
//Feed encoded parity bits into extra registers
for (genvar i =0; i<N_HAM32_SLV; i++) begin
always_ff @(posedge clk_i) begin
if(rstn_i == 1'b0 ) begin
ham_pbits[(i+1)*HAM_P-1:i*HAM_P]<='{default:0};
end else begin
ham_pbits[(i+1)*HAM_P-1:i*HAM_P]<={
ham_mbits_D[i*HAM_M+16]
,ham_mbits_D[i*HAM_M+8]
,ham_mbits_D[i*HAM_M+4]
,ham_mbits_D[i*HAM_M+2]
,ham_mbits_D[i*HAM_M+1]
,ham_mbits_D[i*HAM_M+0]
};
end
end
//Get flat registered messages
assign ham_mbits_Q [(i+1)*HAM_M-1:i*HAM_M] = {
slv_reg_pQ[i*HAM_D+25:i*HAM_D+11]
,ham_pbits[i*HAM_P+5]
,slv_reg_pQ[i*HAM_D+10:i*HAM_D+4]
,ham_pbits[i*HAM_P+4]
,slv_reg_pQ[i*HAM_D+3:i*HAM_D+1]
,ham_pbits[i*HAM_P+3]
,slv_reg_pQ[i*HAM_D]
,ham_pbits[i*HAM_P+2]
,ham_pbits[i*HAM_P+1]
,ham_pbits[i*HAM_P]
};
end
for (genvar i =0; i<N_HAM32_SLV; i++) begin : slv_ham_dec
//decoder
hamming32t26d_dec#(
)dut_hamming32t26d_dec (
.data_o(slv_reg_fto[(i+1)*HAM_D-1:i*HAM_D]),
.hv_i(ham_mbits_Q[(i+1)*HAM_M-1:i*HAM_M]),
.ded_error_o(ift_slv[i])
);
end
// get a packed 2d structure to assign slv_reg
for (genvar i =0; i<N_REGS; i++) begin
assign slv_reg_ufto[i]=slv_reg_fto[(i+1)*REG_WIDTH-1:i*REG_WIDTH];
end
//----------------------------------------------
//------------- Slave registers update
//----------------------------------------------
//Each cycle the values in slv_reg_D will be saved in slv_reg
//So if you want to update slv_reg the values for slv_reg_D shall be
//assigned in this section
//If you add aditional logic that can change the values of the registers
//the next always block have to be modified to add the aditional
//conditions under which the slv_reg shall be updated
always_comb begin
//AHB write
//Write to slv registers if slave was selected & was a write. Else
//register the values given by pmu_raw
if(address_phase.write && address_phase.select) begin
//Feed and send flat assigment in to original format
//assign flat hamming outputs to slv_reg_Q
slv_reg_Q=slv_reg_ufto;
slv_reg_Q [slv_index] = dwrite_slave;
slv_reg_D = pmu_regs_int;
slv_reg_D[slv_index] = dwrite_slave;
end else begin
slv_reg_D = pmu_regs_int;
//Feed and send flat assigment in to original format
//assign flat hamming outputs to slv_reg_Q
slv_reg_Q=slv_reg_ufto;
end
end
//reduce all DED errors from hamming blocks to single interrupt
assign intr_FT_o = |ift_slv;
end
endgenerate
//----------------------------------------------
//------------- AHB control logic
......@@ -269,11 +434,7 @@ always_ff @(posedge clk_i) begin
end
//data phase - slave response
wire [$clog2(N_REGS)-1:0] slv_index;
logic [HDATA_WIDTH-1:0] dwrite_slave; //Data master to the register bank
assign slv_index = address_phase.master_addr[$clog2(N_REGS)+1:2];
logic [1:0] complete_transfer_status;
logic [HDATA_WIDTH-1:0] dread_slave; //response from slave
assign hrdata_o = dread_slave;
assign hreadyo_o = complete_transfer_status [0];
......@@ -318,7 +479,6 @@ end
//----------------------------------------------
//------------- PMU_raw instance
//----------------------------------------------
wire [REG_WIDTH-1:0] pmu_regs_int [0:N_REGS-1];
wire ahb_write_req;
assign ahb_write_req = address_phase.write && address_phase.select;
......@@ -342,33 +502,6 @@ end
.intr_RDC_o
);
//----------------------------------------------
//------------- Slave registers update
//----------------------------------------------
//Each cycle the values in slv_reg_D will be saved in slv_reg
//So if you want to update slv_reg the values for slv_reg_D shall be
//assigned in this section
//If you add aditional logic that can change the values of the registers
//the next always block have to be modified to add the aditional
//conditions under which the slv_reg shall be updated
always_comb begin
//AHB write
//Write to slv registers if slave was selected & was a write. Else
//register the values given by pmu_raw
if(address_phase.write && address_phase.select) begin
// get the values from the pmu_raw instance
slv_reg_Q = slv_reg;
slv_reg_Q [slv_index] = dwrite_slave;
slv_reg_D = pmu_regs_int;
slv_reg_D[slv_index] = dwrite_slave;
end else begin
slv_reg_D = pmu_regs_int;
slv_reg_Q = slv_reg;
end
end
/////////////////////////////////////////////////////////////////////////////////
//
// Formal Verification section begins here.
......
......@@ -277,7 +277,7 @@
for(x=0; x<N_CORES; x=x+1) begin: InterruptionQuotaHold
always @(posedge clk_i) begin
if(rstn_i == 1'b0 ) begin
interruption_quota_q[x] <= '{default:'0};
interruption_quota_q[x] <= 1'b0;
end else begin
interruption_quota_q[x] <= interruption_quota_d[x] | interruption_quota_q[x];
end
......
......@@ -71,8 +71,7 @@ module crossbar #
//
////////////////////////////////////////////////////////////////////////////////
`ifdef FORMAL
assert(N_IN >= N_OUT);
// assert(N_IN >= N_OUT);
`endif
endmodule
......
......@@ -158,7 +158,7 @@ module PMU_quota #
//Check if quota is exceeded and generate interrupt or interrupt has been
//previously triggered and never reseted
assign intr_quota_o = (suma_int > quota_limit_i )
assign intr_quota_o = (suma_int > max_width'(quota_limit_i) )
? 1'b1 : hold_intr_quota;
////////////////////////////////////////////////////////////////////////////////
......
......@@ -92,11 +92,8 @@ module hamming32t26d_dec #
//
////////////////////////////////////////////////////////////////////////////////
`ifdef FORMAL
assert (IN_WIDTH==26);
assert (N_CHECKB==5);
// assert (IN_WIDTH==26);
// assert (N_CHECKB==5);
`endif
endmodule
`default_nettype wire //allow compatibility with legacy code and xilinx ip
......@@ -97,8 +97,8 @@ module hamming32t26d_enc #
//
////////////////////////////////////////////////////////////////////////////////
`ifdef FORMAL
assert (IN_WIDTH==26);
assert (N_CHECKB==5);
// assert (IN_WIDTH==26);
// assert (N_CHECKB==5);
`endif
endmodule
......
......@@ -35,6 +35,9 @@ verific -sv PMU_overflow.sv
verific -sv PMU_quota.sv
verific -sv MCCU.sv
verific -sv RDC.sv
verific -sv hamming32t26d_enc.sv
verific -sv hamming32t26d_dec.sv
verific -sv crossbar.sv
verific -import -extnets -all pmu_ahb
prep -top pmu_ahb
......@@ -52,3 +55,6 @@ prep -top pmu_ahb
../../../submodules/quota/PMU_quota.sv
../../../submodules/MCCU/hdl/MCCU.sv
../../../submodules/RDC/hdl/RDC.sv
../../../submodules/seu_ip/hamming32t26d_enc.sv
../../../submodules/seu_ip/hamming32t26d_dec.sv
../../../submodules/crossbar/hdl/crossbar.sv
......@@ -3,7 +3,7 @@ TOP=../../..
vlib pmu_ahb
vmap work $PWD/pmu_ahb
vlog +acc=rn +incdir+$TOP/hdl/ $TOP/hdl/pmu_ahb.sv $TOP/hdl/PMU_raw.sv $TOP/submodules/MCCU/hdl/* $TOP/submodules/crossbar/hdl/*.sv $TOP/submodules/RDC/hdl/*.sv $TOP/submodules/overflow/*.sv $TOP/submodules/quota/*.sv $TOP/submodules/counters/*.sv tb_pmu_ahb.sv ./colors.vh
vlog +acc=rn +incdir+$TOP/hdl/ $TOP/hdl/pmu_ahb.sv $TOP/hdl/PMU_raw.sv $TOP/submodules/MCCU/hdl/* $TOP/submodules/crossbar/hdl/*.sv $TOP/submodules/RDC/hdl/*.sv $TOP/submodules/overflow/*.sv $TOP/submodules/quota/*.sv $TOP/submodules/counters/*.sv tb_pmu_ahb.sv ./colors.vh $TOP/submodules/seu_ip/hamming32t26d_*.sv
vmake pmu_ahb/ > Makefile
if [ -z "$1" ]
......
......@@ -60,6 +60,8 @@ reg tb_fail = 0;
.N_REGS(TB_TOTAL_NREGS),
.MCCU_N_CORES(4),
.N_SOC_EV (TB_N_SOC_EV)
.FT(1),
.N_REGS(47)
)
dut_pmu_ahb
(
......@@ -82,7 +84,8 @@ reg tb_fail = 0;
.intr_overflow_o(),
.intr_quota_o(),
.intr_MCCU_o(),
.intr_RDC_o()
.intr_RDC_o(),
.intr_FT_o()
);
//***clk_gen***
......@@ -97,6 +100,7 @@ reg tb_fail = 0;
hsel_i = 0;
htrans_i = 2'b00;
#CLK_PERIOD;
#CLK_PERIOD;
rstn_i <= 1'b1;
#CLK_PERIOD;
$display("Done");
......
......@@ -3,8 +3,8 @@ quietly WaveActivateNextPane {} 0
add wave -noupdate /tb_pmu_ahb/dut_pmu_ahb/inst_pmu_raw/regs_i
add wave -noupdate /tb_pmu_ahb/dut_pmu_ahb/inst_pmu_raw/regs_o
add wave -noupdate /tb_pmu_ahb/dut_pmu_ahb/inst_pmu_raw/crossbar_cfg
add wave -noupdate -expand /tb_pmu_ahb/dut_pmu_ahb/pmu_regs_int
add wave -noupdate -expand /tb_pmu_ahb/dut_pmu_ahb/state
add wave -noupdate /tb_pmu_ahb/dut_pmu_ahb/pmu_regs_int
add wave -noupdate /tb_pmu_ahb/dut_pmu_ahb/state
add wave -noupdate /tb_pmu_ahb/dut_pmu_ahb/next
add wave -noupdate -radix unsigned -radixshowbase 0 /tb_pmu_ahb/dut_pmu_ahb/slv_index
add wave -noupdate /tb_pmu_ahb/dut_pmu_ahb/hwrite_i
......@@ -13,7 +13,7 @@ add wave -noupdate /tb_pmu_ahb/dut_pmu_ahb/clk_i
add wave -noupdate /tb_pmu_ahb/dut_pmu_ahb/rstn_i
add wave -noupdate /tb_pmu_ahb/dut_pmu_ahb/haddr_i
add wave -noupdate /tb_pmu_ahb/htrans_i
add wave -noupdate -expand /tb_pmu_ahb/dut_pmu_ahb/events_i
add wave -noupdate /tb_pmu_ahb/dut_pmu_ahb/events_i
add wave -noupdate /tb_pmu_ahb/dut_pmu_ahb/inst_pmu_raw/inst_counters/clk_i
add wave -noupdate /tb_pmu_ahb/dut_pmu_ahb/inst_pmu_raw/inst_counters/rstn_i
add wave -noupdate /tb_pmu_ahb/dut_pmu_ahb/inst_pmu_raw/inst_counters/softrst_i
......@@ -21,11 +21,27 @@ add wave -noupdate /tb_pmu_ahb/dut_pmu_ahb/inst_pmu_raw/inst_counters/en_i
add wave -noupdate /tb_pmu_ahb/dut_pmu_ahb/inst_pmu_raw/inst_counters/we_i
add wave -noupdate /tb_pmu_ahb/dut_pmu_ahb/inst_pmu_raw/inst_counters/regs_i
add wave -noupdate /tb_pmu_ahb/dut_pmu_ahb/inst_pmu_raw/inst_counters/regs_o
add wave -noupdate -expand /tb_pmu_ahb/dut_pmu_ahb/inst_pmu_raw/inst_counters/events_i
add wave -noupdate /tb_pmu_ahb/dut_pmu_ahb/inst_pmu_raw/inst_counters/events_i
add wave -noupdate /tb_pmu_ahb/dut_pmu_ahb/inst_pmu_raw/inst_counters/slv_reg
add wave -noupdate /tb_pmu_ahb/dut_pmu_ahb/inst_pmu_raw/inst_counters/adder_out
add wave -noupdate /tb_pmu_ahb/dut_pmu_ahb/intr_FT_o
add wave -noupdate /tb_pmu_ahb/dut_pmu_ahb/genblk1/HAM_P
add wave -noupdate /tb_pmu_ahb/dut_pmu_ahb/genblk1/HAM_D
add wave -noupdate /tb_pmu_ahb/dut_pmu_ahb/genblk1/HAM_M
add wave -noupdate /tb_pmu_ahb/dut_pmu_ahb/genblk1/N_HAM32_SLV
add wave -noupdate /tb_pmu_ahb/dut_pmu_ahb/genblk1/ift_slv
add wave -noupdate /tb_pmu_ahb/dut_pmu_ahb/genblk1/slv_reg_fti
add wave -noupdate /tb_pmu_ahb/dut_pmu_ahb/genblk1/slv_reg_fto
add wave -noupdate /tb_pmu_ahb/dut_pmu_ahb/genblk1/slv_reg_ufto
add wave -noupdate /tb_pmu_ahb/dut_pmu_ahb/genblk1/slv_reg_pQ
add wave -noupdate /tb_pmu_ahb/dut_pmu_ahb/genblk1/ham_mbits_D
add wave -noupdate /tb_pmu_ahb/dut_pmu_ahb/genblk1/ham_mbits_Q
add wave -noupdate /tb_pmu_ahb/dut_pmu_ahb/genblk1/ham_pbits
add wave -noupdate /tb_pmu_ahb/dut_pmu_ahb/slv_reg
add wave -noupdate /tb_pmu_ahb/dut_pmu_ahb/slv_reg_D
add wave -noupdate /tb_pmu_ahb/dut_pmu_ahb/slv_reg_Q
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {54000 ps} 0}
WaveRestoreCursors {{Cursor 1} {5996 ps} 0}
quietly wave cursor active 1
configure wave -namecolwidth 299
configure wave -valuecolwidth 252
......@@ -41,4 +57,4 @@ configure wave -griddelta 40
configure wave -timeline 0
configure wave -timelineunits ps
update
WaveRestoreZoom {0 ps} {115500 ps}
WaveRestoreZoom {0 ps} {119739 ps}
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