Skip to content

Commit 79844e3

Browse files
committed
hw: Fix FREP stalling logic
To track if all instructions in the current loop nest have been stored in the buffer we compare the write pointer to the end pointer of the loop nest. However, this must only be done when writing a loop nest instruction. Previously, we were using `loop_active_q` to check this, but it is incorrect, as `loop_active_q` tells us if we already started executing the loop. Instead, `loop_cnt_q > 0` tells us if we have just received an FREP, and thus should be counting the following instructions.
1 parent 2992f05 commit 79844e3

File tree

1 file changed

+19
-17
lines changed

1 file changed

+19
-17
lines changed

hw/snitch_cluster/src/snitch_sequencer.sv

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,9 @@ module snitch_sequencer import snitch_pkg::*; #(
401401
// is nested within the current loop nest. The latter means checking if the write
402402
// pointer is within the outermost loop bounds. But the write pointer can wrap to
403403
// the start of the loop, so we also need to track if we've already received all
404-
// instructions.
404+
// instructions. And this involves comparing the write pointer to the end pointer,
405+
// when writing a loop nest instruction. The first instructions following an FREP,
406+
// i.e. received while loop_cnt_q > 0, are guaranteed to be within the loop nest.
405407

406408
logic rb_wptr_within_bounds;
407409
logic [DepthBits-1:0] nest_start_pointer, nest_end_pointer;
@@ -411,7 +413,7 @@ module snitch_sequencer import snitch_pkg::*; #(
411413
nest_start_pointer = nest_cfg_q[0].base_pointer;
412414
nest_end_pointer = nest_cfg_q[0].base_pointer + nest_cfg_q[0].max_inst;
413415

414-
if (loop_active_q && (rb_wptr == nest_end_pointer) && (core_rb_valid && core_rb_ready)) begin
416+
if ((loop_cnt_q > 0) && (rb_wptr == nest_end_pointer) && (core_rb_valid && core_rb_ready)) begin
415417
received_all_nest_insns_d = 1'b1;
416418
end else if (nest_ends) begin
417419
received_all_nest_insns_d = 1'b0;
@@ -432,20 +434,20 @@ module snitch_sequencer import snitch_pkg::*; #(
432434
nest_cfg_d = nest_cfg_q;
433435
loop_cnt_d = loop_cnt_q;
434436

437+
if (nest_ends) begin
438+
loop_cnt_d = 0;
439+
end
440+
435441
if (core_frep_valid && core_frep_ready) begin
436-
nest_cfg_d[loop_cnt_q].is_streamctl = inp_qdata_op_i[31];
437-
nest_cfg_d[loop_cnt_q].max_inst = inp_qdata_op_i[20+:DepthBits];
438-
nest_cfg_d[loop_cnt_q].stagger_max = inp_qdata_op_i[14:12];
439-
nest_cfg_d[loop_cnt_q].stagger_mask = inp_qdata_op_i[11:8];
440-
nest_cfg_d[loop_cnt_q].max_iter = inp_qdata_arga_i[LoopIterBits-1:0];
441-
nest_cfg_d[loop_cnt_q].base_pointer = rb_wptr;
442+
nest_cfg_d[loop_cnt_d].is_streamctl = inp_qdata_op_i[31];
443+
nest_cfg_d[loop_cnt_d].max_inst = inp_qdata_op_i[20+:DepthBits];
444+
nest_cfg_d[loop_cnt_d].stagger_max = inp_qdata_op_i[14:12];
445+
nest_cfg_d[loop_cnt_d].stagger_mask = inp_qdata_op_i[11:8];
446+
nest_cfg_d[loop_cnt_d].max_iter = inp_qdata_arga_i[LoopIterBits-1:0];
447+
nest_cfg_d[loop_cnt_d].base_pointer = rb_wptr;
442448

443449
loop_cnt_d = loop_cnt_q + 1;
444450
end
445-
446-
if (nest_ends) begin
447-
loop_cnt_d = 0;
448-
end
449451
end
450452

451453
//--- Inner loops in last iteration detector ---
@@ -515,7 +517,7 @@ module snitch_sequencer import snitch_pkg::*; #(
515517
loop_idx_t outermost_ending_loop;
516518
logic [NestDepth-1:0] loop_ends;
517519
logic [NestDepth-1:0] loop_active;
518-
logic no_loop_ends, all_loops_end;
520+
logic no_loop_ends;
519521

520522
// Mask to select only loops which end on current instruction
521523
assign loop_ends = last_inst & last_iter & last_iter_inner_loops;
@@ -702,10 +704,10 @@ module snitch_sequencer import snitch_pkg::*; #(
702704
// pragma translate_off
703705
assign trace_port_o.source = snitch_pkg::SrcFpuSeq;
704706
assign trace_port_o.cbuf_push = core_frep_valid && core_frep_ready;
705-
assign trace_port_o.max_inst = nest_cfg_d[loop_cnt_q].max_inst;
706-
assign trace_port_o.max_iter = nest_cfg_d[loop_cnt_q].max_iter;
707-
assign trace_port_o.stg_max = nest_cfg_d[loop_cnt_q].stagger_max;
708-
assign trace_port_o.stg_mask = nest_cfg_d[loop_cnt_q].stagger_mask;
707+
assign trace_port_o.max_inst = inp_qdata_op_i[20+:DepthBits];
708+
assign trace_port_o.max_iter = inp_qdata_arga_i[LoopIterBits-1:0];
709+
assign trace_port_o.stg_max = inp_qdata_op_i[14:12];
710+
assign trace_port_o.stg_mask = inp_qdata_op_i[11:8];
709711
// pragma translate_on
710712

711713
////////////////

0 commit comments

Comments
 (0)