Commit 3d06576e authored by GuillemCabo's avatar GuillemCabo Committed by Guillem
Browse files

add FT MCCU, move TB MCCU & crossbar, update doc, add resource logs

parent 67bc278e
......@@ -12,7 +12,9 @@ rm -f $LOG
# Go to target folder
cd ../tb/questa_sim/ || exit 1
# Declare folders of tests to be executed
declare -a StringArray=("tb_axi_pmu/" "tb_pmu_ahb/" "tb_pmu_raw/" "tb_com_tr/" "tb_hamming16td11/" "tb_hamming32td26/" "tb_reg_sbf/")
declare -a StringArray=("tb_axi_pmu/" "tb_com_tr/" "tb_hamming16td11/" "tb_hamming32td26/"
"tb_pmu_ahb/" "tb_pmu_raw/" "tb_reg_sbf/" "tb_MCCU" "tb_crossbar"
"tb_com_tr/")
# Iterate the string array using for loop
for val in ${StringArray[@]}; do
......
......@@ -81,8 +81,8 @@ Since transients shall occur at the clock's rising edge to allow the counters to
\item \underline{Fail mode:} \textit{quota\_int} is an internal register. It is forwarded to top modules with \textit{quota\_o}. \textit{quota\_int} can suffer permanent faults that are not cleared automatically. This failure mode may result in interrupts not triggering or triggering early. \textbf{Priority High}.\\
\underline{Corrective action:} Replicating the internal register \textit{quota\_int} has a low overhead. Two instances will provide error detection, but tree instances are recommended, allowing for seamless recovery if a failure occurs.\\
\\
\item \underline{Fail mode:}\textit{update\_quota\_i} transient errors can result in incorrect configurations due to unexpected or dropped updates. Misconfiguration affects \textit{quota\_int} and thus the resulting interrupts.\textbf{ Priority high.}\\
\underline{Corrective action:}\\
\item \underline{Fail mode:}\textit{update\_quota\_i} transient errors can result in incorrect configurations due to unexpected or dropped updates. Misconfiguration affects \textit{quota\_int} and thus the resulting interrupts.\textbf{ Low priority.}\\
\underline{Corrective action:} Software can read quota\_o values after each write to ensure no transients have occurred.\\
\\
\item \underline{Fail mode:} \textit{quota\_o} is a wire that takes the value of \textit{quota\_int}. Given that \textit{quota\_int} is protected against permanent upsets, a transient error on the output line may cause incorrect readings for a single cycle.\textit{ Quota\_o} is not used as a control signal and does not affect interrupt generation. \textbf{Priority low}.\\
\underline{Corrective action:} \textit{quota\_o} is signaled to the user-accessible registers to provide more information. Several readings could be performed in quick succession and determine if there was an update. Note that the values will be updated at each cycle if the unit is active. If transients over this signal are a real concern for a particular implementation, hardware error detection is recommended. \\
......
No preview for this file type
......@@ -574,7 +574,7 @@ end
MCCU_enable_int <= regs_i[BASE_MCCU_CFG][0];
end
end
logic MCCU_intr_FT1, MCCU_intr_FT2;
MCCU # (
// Width of data registers
.DATA_WIDTH (REG_WIDTH),
......@@ -582,6 +582,8 @@ end
.WEIGHTS_WIDTH (MCCU_WEIGHTS_WIDTH),
//Cores. Change this may break Verilator TB
.N_CORES (MCCU_N_CORES),
// Fault tolerance mechanisms (FT==0 -> FT disabled)
.FT (FT),
//Signals per core. Change this may break Verilator TB
.CORE_EVENTS (MCCU_N_EVENTS)
)
......@@ -594,6 +596,8 @@ end
.update_quota_i (MCCU_update_quota_int),//Software map
.quota_o (regs_o[BASE_MCCU_QUOTA:END_MCCU_QUOTA]),//write back to a read register
.events_weights_i (MCCU_events_weights_int),//core_events times WEIGHTS_WIDTH registers
.intr_FT1_o (MCCU_intr_FT1),
.intr_FT2_o (MCCU_intr_FT2),
.interruption_quota_o (MCCU_intr_up)//N_CORES output signals Add this to top or single toplevel interrupt and an interrupt vector that identifies the source?
// Individual interrupts allow each core to
// handle their own interrupts , therefore
......@@ -804,13 +808,15 @@ end
// Codestyle. All scopes start with a capital letter
assign intr_FT1_o = |{
Rdctrip.MCCU_watermark_fte1,Rdctrip.intr_RDC_fte1,
Rdctrip.interruption_rdc_fte1,Rdctrip.RDC_enable_fte1
Rdctrip.interruption_rdc_fte1,Rdctrip.RDC_enable_fte1,
MCCU_intr_FT1
};
//Gather all the signals of uncorrected errors from FT scopes
// Codestyle. All scopes start with a capital letter
assign intr_FT2_o = |{
Rdctrip.MCCU_watermark_fte2,Rdctrip.intr_RDC_fte2,
Rdctrip.interruption_rdc_fte2,Rdctrip.RDC_enable_fte2
Rdctrip.interruption_rdc_fte2,Rdctrip.RDC_enable_fte2,
MCCU_intr_FT2
};
end
/////////////////////////////////////////////////////////////////////////////////
......
......@@ -26,6 +26,8 @@
parameter integer WEIGHTS_WIDTH = 8,
//Cores. Change this may break Verilator TB
parameter integer N_CORES =2,
// Fault tolerance mechanisms (FT==0 -> FT disabled)
parameter integer FT = 1,
//Signals per core. Change this may break Verilator TB
parameter integer CORE_EVENTS =4
)
......@@ -49,7 +51,11 @@
input wire [WEIGHTS_WIDTH-1:0] events_weights_i [0:N_CORES-1]
[0:CORE_EVENTS-1],
//Quota interruption
output wire interruption_quota_o[N_CORES-1:0]
output wire interruption_quota_o[N_CORES-1:0],
// FT (Fault tolerance) interrupt, error detected and recovered
output wire intr_FT1_o,
// FT (Fault tolerance) interrupt, error detected but not recoverable
output wire intr_FT2_o
);
//Parameters required for additions and substractions of quotas.
//OVERFLOW_PROT can be reduced. It needs to be a bit larger than
......@@ -63,10 +69,7 @@
localparam O_W_0PAD = OVERFLOW_PROT-WEIGHTS_WIDTH;
//internal signals
reg [DATA_WIDTH-1:0] quota_int [0:N_CORES-1];//Quota set by external registers
wire [WEIGHTS_WIDTH-1:0] events_weights_int [0:N_CORES-1] [0:CORE_EVENTS-1];
reg [OVERFLOW_PROT-1:0] ccc_suma_int [0:N_CORES-1];//Addition of current cycle
//consumed quota
`ifdef DEBUG
reg [OVERFLOW_PROT-1:0] debug_ccc_suma_int;//Just one core
reg [OVERFLOW_PROT-1:0] debug_ccc_suma_loop_int;//Just one core
......@@ -78,172 +81,350 @@
Generate one mechanism to monitor the quota for each of the cores in the
SOC,
----------*/
integer i;
integer j;
// generate begin : GeneratedQuotaMonitor
always @(posedge clk_i) begin: syncReset
/*----------
Auxiliar variables
----------*/
longint tmp_ccc_suma_int;//temporal addition of ccc_suma_int
/*----------
Reset
----------*/
if(rstn_i == 1'b0 ) begin
if (FT==0) begin : Nft_suma
// Define internal signals within generate scope
reg [OVERFLOW_PROT-1:0] ccc_suma_int [0:N_CORES-1];//Addition of current cycle
//consumed quota
reg [DATA_WIDTH-1:0] quota_int [0:N_CORES-1];//Quota set by external registers
integer i;
integer j;
// generate begin : GeneratedQuotaMonitor
always @(posedge clk_i) begin: syncReset
/*----------
sync reset Quota
Auxiliar variables
----------*/
for (i=0; i<N_CORES; i=i+1) begin : ResetQuota
quota_int[i] <={DATA_WIDTH{1'b0}};
end
longint tmp_ccc_suma_int;//temporal addition of ccc_suma_int
/*----------
sync reset current cycle consumed quota
Reset
----------*/
for (i=0; i<N_CORES; i=i+1) begin : ResetCCCQuota
ccc_suma_int[i] <={OVERFLOW_PROT{1'b0}};
end
/*----------
sync reset debug registers
----------*/
`ifdef DEBUG
debug_ccc_suma_int <= {OVERFLOW_PROT{1'b0}};
debug_ccc_suma_loop_int <= {OVERFLOW_PROT{1'b0}};
for (i=0; i<N_CORES; i=i+1) begin : ResetDebugEvents
debug_events_weights_int [i]<= {WEIGHTS_WIDTH{1'b0}};
end
`endif
end else begin
/*----------
Normal operation
----------*/
if(rstn_i == 1'b0 ) begin
/*----------
sync reset Quota
----------*/
for (i=0; i<N_CORES; i=i+1) begin : ResetQuota
quota_int[i] <={DATA_WIDTH{1'b0}};
end
/*----------
sync reset current cycle consumed quota
----------*/
for (i=0; i<N_CORES; i=i+1) begin : ResetCCCQuota
ccc_suma_int[i] <={OVERFLOW_PROT{1'b0}};
end
/*----------
sync reset debug registers
----------*/
`ifdef DEBUG
debug_ccc_suma_int <= {OVERFLOW_PROT{1'b0}};
debug_ccc_suma_loop_int <= {OVERFLOW_PROT{1'b0}};
for (i=0; i<N_CORES; i=i+1) begin : ResetDebugEvents
debug_events_weights_int [i]<= {WEIGHTS_WIDTH{1'b0}};
end
`endif
end else begin
/*----------
Substract to the core quota the weight of each active
event during this cycle. If the event is active the value
of the weight is substracted, if not 0 is substracted. Only
substract quota if enable is active. If the quota has been updated
this cycle quota_i is bypass
Normal operation
----------*/
//Cases to change the values of quota
`ifdef ASSERTIONS
//If unit was not in reset and has not been reseted this cycle
if($past(rstn_i)&& rstn_i) begin
for (i=0; i<N_CORES; i=i+1) begin : AssertionsQuotaNonReset
//!Enable && !update: hold values quota_int
if(!$past(enable_i) && !$past(update_quota_i[i])) begin
assert(quota_int[i] == $past(quota_int[i]));
/*----------
Substract to the core quota the weight of each active
event during this cycle. If the event is active the value
of the weight is substracted, if not 0 is substracted. Only
substract quota if enable is active. If the quota has been updated
this cycle quota_i is bypass
----------*/
//Cases to change the values of quota
`ifdef ASSERTIONS
//If unit was not in reset and has not been reseted this cycle
if($past(rstn_i)&& rstn_i) begin
for (i=0; i<N_CORES; i=i+1) begin : AssertionsQuotaNonReset
//!Enable && !update: hold values quota_int
if(!$past(enable_i) && !$past(update_quota_i[i])) begin
assert(quota_int[i] == $past(quota_int[i]));
end
//!Enable && update: Update values quota_int with quota_i,
// do NOT substract
if(!$past(enable_i) && $past(update_quota_i[i])) begin
assert(quota_int[i] == $past(quota_i[i]));
end
//Enable && !update:Replace quota_int with quota_int minus
// consumed quota (ccc_quota). If
// underflow the content of
// quota_int[i] can be 0.
if($past(enable_i) && !$past(update_quota_i[i])) begin
assert(quota_int[i] == ($past(quota_int[i])-$past(ccc_suma_int[i]))
|| (quota_int[i]==
{DATA_WIDTH{1'b0}}));
end
//Enable && update: Update values quota_int with quota_i and
// substract ccc_quota if
// underflow the content of
// quota_int[i] can be 0.
if($past(enable_i) && $past(update_quota_i[i])) begin
assert(quota_int[i] == ($past(quota_i[i])-$past(ccc_suma_int[i]))
|| (quota_int[i]==
{DATA_WIDTH{1'b0}}));
end
end
end else begin
//if the unit has been reseted in current or previous cycle
for (i=0; i<N_CORES; i=i+1) begin : AssertionsQuotaReset
assert(quota_int[i] == {DATA_WIDTH{1'b0}});
end
end
`endif
for (i=0; i<N_CORES; i=i+1) begin : SetQuota
//!Enable && !update: hold values quota_int
if(!enable_i && !update_quota_i[i]) begin
quota_int[i] <= quota_int[i];
//!Enable && update: Update values quota_int with quota_i,
// do NOT substract
if(!$past(enable_i) && $past(update_quota_i[i])) begin
assert(quota_int[i] == $past(quota_i[i]));
end
end else if (!enable_i && update_quota_i[i]) begin
quota_int[i] <= quota_i[i];
//Enable && !update:Replace quota_int with quota_int minus
// consumed quota (ccc_quota). If
// underflow the content of
// quota_int[i] can be 0.
if($past(enable_i) && !$past(update_quota_i[i])) begin
assert(quota_int[i] == ($past(quota_int[i])-$past(ccc_suma_int[i]))
|| (quota_int[i]==
{DATA_WIDTH{1'b0}}));
end
// consumed quota (ccc_quota)
end else if (enable_i && !update_quota_i[i]) begin
for (j=0; j<CORE_EVENTS; j=j+1) begin
//underflow detection. Padding needed for
// prevent width mismatch
if( ccc_suma_int[i] > {{O_D_0PAD{1'b0}},quota_int[i]} )
begin
quota_int[i] <={DATA_WIDTH{1'b0}};
end else begin
quota_int[i] <= quota_int[i] - ccc_suma_int[i][DATA_WIDTH-1:0];
end
end
//Enable && update: Update values quota_int with quota_i and
// substract ccc_quota if
// underflow the content of
// quota_int[i] can be 0.
if($past(enable_i) && $past(update_quota_i[i])) begin
assert(quota_int[i] == ($past(quota_i[i])-$past(ccc_suma_int[i]))
|| (quota_int[i]==
{DATA_WIDTH{1'b0}}));
// substract ccc_quota
end else if(enable_i && update_quota_i[i])begin
for (j=0; j<CORE_EVENTS; j=j+1) begin
//underflow detection. Padding needed for
// prevent width mismatch
if( ccc_suma_int[i] > {{O_D_0PAD{1'b0}},quota_i[i]} )
begin
quota_int[i] <={DATA_WIDTH{1'b0}};
end else begin
quota_int[i] <= quota_i[i] - ccc_suma_int[i][DATA_WIDTH-1:0];
end
end
end
end
end else begin
//if the unit has been reseted in current or previous cycle
for (i=0; i<N_CORES; i=i+1) begin : AssertionsQuotaReset
assert(quota_int[i] == {DATA_WIDTH{1'b0}});
end
end
`endif
for (i=0; i<N_CORES; i=i+1) begin : SetQuota
//!Enable && !update: hold values quota_int
if(!enable_i && !update_quota_i[i]) begin
quota_int[i] <= quota_int[i];
//!Enable && update: Update values quota_int with quota_i,
// do NOT substract
end else if (!enable_i && update_quota_i[i]) begin
quota_int[i] <= quota_i[i];
//Enable && !update:Replace quota_int with quota_int minus
// consumed quota (ccc_quota)
end else if (enable_i && !update_quota_i[i]) begin
/*----------
Add quotas of all active signals. The ones that are not
enabled are 0. The quotas in ccc_suma_int[i] are added at every
cycle independently of the enable signal, but ccc_suma_int will
only be substracted to the quota if MCCU is enabled
----------*/
for (i=0; i<N_CORES; i=i+1) begin : AddEventsWeights
tmp_ccc_suma_int=0;
for (j=0; j<CORE_EVENTS; j=j+1) begin
//underflow detection. Padding needed for
// prevent width mismatch
if( ccc_suma_int[i] > {{O_D_0PAD{1'b0}},quota_int[i]} )
begin
quota_int[i] <={DATA_WIDTH{1'b0}};
end else begin
quota_int[i] <= quota_int[i] - ccc_suma_int[i][DATA_WIDTH-1:0];
end
//Reguired to avoid warning. Blocking
//Assigment is legal when usign temporal
//variables.
/* verilator lint_off BLKSEQ */
tmp_ccc_suma_int ={{O_W_0PAD{1'b0}},events_weights_int[i][j]} + tmp_ccc_suma_int;
/* verilator lint_on BLKSEQ */
end
//Enable && update: Update values quota_int with quota_i and
// substract ccc_quota
end else if(enable_i && update_quota_i[i])begin
for (j=0; j<CORE_EVENTS; j=j+1) begin
//underflow detection. Padding needed for
// prevent width mismatch
if( ccc_suma_int[i] > {{O_D_0PAD{1'b0}},quota_i[i]} )
begin
quota_int[i] <={DATA_WIDTH{1'b0}};
end else begin
quota_int[i] <= quota_i[i] - ccc_suma_int[i][DATA_WIDTH-1:0];
ccc_suma_int[i]<=tmp_ccc_suma_int;
`ifdef DEBUG
/* verilator lint_off WIDTH */
/* verilator lint_off BLKSEQ */
//This only applies when 4 events are available
if(i==0 && CORE_EVENTS==4) begin
debug_events_weights_int <= events_weights_int [0];//assign to core 0
debug_ccc_suma_int <= debug_events_weights_int[0]+debug_events_weights_int[1]+debug_events_weights_int[2]+debug_events_weights_int[3];
debug_tmp=0;
for(k=0; k<CORE_EVENTS; k=k+1) begin
debug_tmp =debug_events_weights_int[k] + debug_tmp;
end
end
debug_ccc_suma_loop_int <= debug_tmp;
end
`ifdef ASSERTIONS
assert(debug_ccc_suma_int == debug_ccc_suma_loop_int);
`endif
//disable BLKSeK for the temporal assigment of debug_tmp
/* verilator lint_on BLKSEQ */
/* verilator lint_on WIDTH */
`endif
end
end
end
end
end else begin : Ft_suma
// Code for FT version
//Triplicate registers of interest
//Addition of current cycle consumed quota
reg [OVERFLOW_PROT-1:0] ccc_suma_int_0 [0:N_CORES-1];
reg [OVERFLOW_PROT-1:0] ccc_suma_int_1 [0:N_CORES-1];
reg [OVERFLOW_PROT-1:0] ccc_suma_int_2 [0:N_CORES-1];
//Voted ccc_suma_int
logic [OVERFLOW_PROT-1:0] ccc_suma_vint [0:N_CORES-1];
logic interruption_ccc_suma_fte1, interruption_ccc_suma_fte2;
//Quota set by external registers
reg [DATA_WIDTH-1:0] quota_int_0 [0:N_CORES-1];
reg [DATA_WIDTH-1:0] quota_int_1 [0:N_CORES-1];
reg [DATA_WIDTH-1:0] quota_int_2 [0:N_CORES-1];
//Voted quota int
logic [DATA_WIDTH-1:0] quota_vint [0:N_CORES-1];
logic interruption_quota_fte1, interruption_quota_fte2;
// generate loop vars
integer i;
integer j;
//Generate voted outputs
way3ua_voter #(
.W(OVERFLOW_PROT),
.U(N_CORES)
)ccc_sum_way3(
.in0(ccc_suma_int_0),
.in1(ccc_suma_int_1),
.in2(ccc_suma_int_2),
.out(ccc_suma_vint),
.error1_o(interruption_ccc_suma_fte1),
.error2_o(interruption_ccc_suma_fte2)
);
way3ua_voter #(
.W(DATA_WIDTH),
.U(N_CORES)
)quota_way3(
.in0(quota_int_0),
.in1(quota_int_1),
.in2(quota_int_2),
.out(quota_vint),
.error1_o(interruption_quota_fte1),
.error2_o(interruption_quota_fte2)
);
// generate begin : GeneratedQuotaMonitor
always @(posedge clk_i) begin: syncReset
/*----------
Auxiliar variables
----------*/
longint tmp_ccc_suma_int;//temporal addition of ccc_suma_int
/*----------
Add quotas of all active signals. The ones that are not
enabled are 0. The quotas in ccc_suma_int[i] are added at every
cycle independently of the enable signal, but ccc_suma_int will
only be substracted to the quota if MCCU is enabled
----------*/
for (i=0; i<N_CORES; i=i+1) begin : AddEventsWeights
tmp_ccc_suma_int=0;
for (j=0; j<CORE_EVENTS; j=j+1) begin
//Reguired to avoid warning. Blocking
//Assigment is legal when usign temporal
//variables.
/* verilator lint_off BLKSEQ */
tmp_ccc_suma_int ={{O_W_0PAD{1'b0}},events_weights_int[i][j]} + tmp_ccc_suma_int;
/* verilator lint_on BLKSEQ */
Reset
----------*/
if(rstn_i == 1'b0 ) begin
/*----------
sync reset Quota
----------*/
for (i=0; i<N_CORES; i=i+1) begin : ResetQuota
quota_int_0[i] <={DATA_WIDTH{1'b0}};
quota_int_1[i] <={DATA_WIDTH{1'b0}};
quota_int_2[i] <={DATA_WIDTH{1'b0}};
end
ccc_suma_int[i]<=tmp_ccc_suma_int;
`ifdef DEBUG
/* verilator lint_off WIDTH */
/* verilator lint_off BLKSEQ */
//This only applies when 4 events are available
if(i==0 && CORE_EVENTS==4) begin
debug_events_weights_int <= events_weights_int [0];//assign to core 0
debug_ccc_suma_int <= debug_events_weights_int[0]+debug_events_weights_int[1]+debug_events_weights_int[2]+debug_events_weights_int[3];
debug_tmp=0;
for(k=0; k<CORE_EVENTS; k=k+1) begin
debug_tmp =debug_events_weights_int[k] + debug_tmp;
/*----------
sync reset current cycle consumed quota
----------*/
for (i=0; i<N_CORES; i=i+1) begin : ResetCCCQuota
ccc_suma_int_0[i] <={OVERFLOW_PROT{1'b0}};
ccc_suma_int_1[i] <={OVERFLOW_PROT{1'b0}};
ccc_suma_int_2[i] <={OVERFLOW_PROT{1'b0}};
end
end else begin
/*----------
Normal operation
----------*/
/*----------
Substract to the core quota the weight of each active
event during this cycle. If the event is active the value
of the weight is substracted, if not 0 is substracted. Only
substract quota if enable is active. If the quota has been updated
this cycle quota_i is bypass
----------*/
for (i=0; i<N_CORES; i=i+1) begin : SetQuota
//!Enable && !update: hold values quota_int
if(!enable_i && !update_quota_i[i]) begin
quota_int_0[i] <= quota_vint[i];
quota_int_1[i] <= quota_vint[i];
quota_int_2[i] <= quota_vint[i];
//!Enable && update: Update values quota_int with quota_i,
// do NOT substract
end else if (!enable_i && update_quota_i[i]) begin
quota_int_0[i] <= quota_i[i];
quota_int_1[i] <= quota_i[i];
quota_int_2[i] <= quota_i[i];
//Enable && !update:Replace quota_int with quota_int minus
// consumed quota (ccc_quota)
end else if (enable_i && !update_quota_i[i]) begin
for (j=0; j<CORE_EVENTS; j=j+1) begin
//underflow detection. Padding needed for
// prevent width mismatch
if( ccc_suma_vint[i] > {{O_D_0PAD{1'b0}},quota_vint[i]} )
begin
quota_int_0[i] <={DATA_WIDTH{1'b0}};
quota_int_1[i] <={DATA_WIDTH{1'b0}};
quota_int_2[i] <={DATA_WIDTH{1'b0}};
end else begin
quota_int_0[i] <= quota_vint[i] - ccc_suma_vint[i][DATA_WIDTH-1:0];
quota_int_1[i] <= quota_vint[i] - ccc_suma_vint[i][DATA_WIDTH-1:0];
quota_int_2[i] <= quota_vint[i] - ccc_suma_vint[i][DATA_WIDTH-1:0];
end
end
//Enable && update: Update values quota_int with quota_i and
// substract ccc_quota
end else if(enable_i && update_quota_i[i])begin
for (j=0; j<CORE_EVENTS; j=j+1) begin
//underflow detection. Padding needed for
// prevent width mismatch
if( ccc_suma_vint[i] > {{O_D_0PAD{1'b0}},quota_i[i]} )
begin
quota_int_0[i] <={DATA_WIDTH{1'b0}};
quota_int_1[i] <={DATA_WIDTH{1'b0}};
quota_int_2[i] <={DATA_WIDTH{1'b0}};
end else begin
quota_int_0[i] <= quota_i[i] - ccc_suma_vint[i][DATA_WIDTH-1:0];
quota_int_1[i] <= quota_i[i] - ccc_suma_vint[i][DATA_WIDTH-1:0];
quota_int_2[i] <= quota_i[i] - ccc_suma_vint[i][DATA_WIDTH-1:0];
end
end
debug_ccc_suma_loop_int <= debug_tmp;
end
`ifdef ASSERTIONS
assert(debug_ccc_suma_int == debug_ccc_suma_loop_int);
end
/*----------
Add quotas of all active signals. The ones that are not
enabled are 0. The quotas in ccc_suma_int[i] are added at every
cycle independently of the enable signal, but ccc_suma_int will
only be substracted to the quota if MCCU is enabled
----------*/
for (i=0; i<N_CORES; i=i+1) begin : AddEventsWeights
tmp_ccc_suma_int=0;
for (j=0; j<CORE_EVENTS; j=j+1) begin
//Reguired to avoid warning. Blocking
//Assigment is legal when usign temporal
//variables.
/* verilator lint_off BLKSEQ */
tmp_ccc_suma_int ={{O_W_0PAD{1'b0}},events_weights_int[i][j]} + tmp_ccc_suma_int;
/* verilator lint_on BLKSEQ */
end
ccc_suma_int_0[i]<=tmp_ccc_suma_int;
ccc_suma_int_1[i]<=tmp_ccc_suma_int;
ccc_suma_int_2[i]<=tmp_ccc_suma_int;
`ifdef DEBUG
/* verilator lint_off WIDTH */
/* verilator lint_off BLKSEQ */
//This only applies when 4 events are available
if(i==0 && CORE_EVENTS==4) begin
debug_events_weights_int <= events_weights_int [0];//assign to core 0
debug_ccc_suma_int <= debug_events_weights_int[0]+debug_events_weights_int[1]+debug_events_weights_int[2]+debug_events_weights_int[3];
debug_tmp=0;
for(k=0; k<CORE_EVENTS; k=k+1) begin
debug_tmp =debug_events_weights_int[k] + debug_tmp;
end
debug_ccc_suma_loop_int <= debug_tmp;
end
`ifdef ASSERTIONS
assert(debug_ccc_suma_int == debug_ccc_suma_loop_int);
`endif
//disable BLKSeK for the temporal assigment of debug_tmp
/* verilator lint_on BLKSEQ */
/* verilator lint_on WIDTH */
`endif
//disable BLKSeK for the temporal assigment of debug_tmp
/* verilator lint_on BLKSEQ */
/* verilator lint_on WIDTH */
`endif
end
end</