Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions rtl/vproc_pending_wr.sv
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ module vproc_pending_wr #(
end else begin
unique case ({emul_i, widenarrow_i == OP_NARROWING})
{EMUL_1, 1'b0},
{EMUL_1, 1'b1},
{EMUL_2, 1'b1}: begin
pend_vd = rd_i.vreg ? (32'h00000001 << rd_i.addr ) : 32'b0;
end
Expand Down
10 changes: 9 additions & 1 deletion rtl/vproc_pipeline.sv
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ module vproc_pipeline import vproc_pkg::*; #(
logic alt_last_cycle;
logic init_addr; // initialize address (used by LSU)
logic requires_flush;
logic red_op;
logic [XIF_ID_W -1:0] id;
op_unit unit;
op_mode mode;
Expand Down Expand Up @@ -241,6 +242,7 @@ module vproc_pipeline import vproc_pkg::*; #(
state_next.first_cycle = 1'b1;
state_next.init_addr = 1'b1;
state_next.requires_flush = pipe_in_state_i.requires_flush;
state_next.red_op = pipe_in_state_i.red_op;
state_next.id = pipe_in_state_i.id;
state_next.unit = pipe_in_state_i.unit;
state_next.mode = pipe_in_state_i.mode;
Expand Down Expand Up @@ -466,7 +468,8 @@ module vproc_pipeline import vproc_pkg::*; #(
if ((count_next_inc.part.low == '0) & ((OP_ALT_COUNTER == '0) | ~state_q.count.part.sign) &
((RES_ALWAYS_VREG | state_q.res_vreg) != '0) // at least one valid vreg
) begin
res_store = ((RES_NARROW & state_q.res_narrow) == '0) | ~count_next_inc.part.mul[0];
// state_q.last_cycle is necessary for narrowing instructions with EMUL < 1
res_store = ((RES_NARROW & state_q.res_narrow) == '0) | ~count_next_inc.part.mul[0] | state_q.last_cycle;
end
// Shifting is delayed by one cycle compared to the store and hence uses the current counter
if ((state_q.count.val & ~({COUNTER_W{1'b1}} << $clog2(RES_W[0] / COUNTER_OP_W))) == '0) begin
Expand Down Expand Up @@ -679,6 +682,7 @@ module vproc_pipeline import vproc_pkg::*; #(
logic last_cycle;
logic init_addr; // initialize address (used by LSU)
logic requires_flush;
logic red_op;
logic alt_count_valid; // alternative counter value is valid
logic [AUX_COUNTER_W-1:0] aux_count;
logic [XIF_ID_W-1:0] id;
Expand Down Expand Up @@ -711,6 +715,7 @@ module vproc_pipeline import vproc_pkg::*; #(
(~FIELD_COUNT_USED | (state_q.field_count == '0));
unpack_ctrl.init_addr = state_q.init_addr;
unpack_ctrl.requires_flush = state_q.requires_flush;
unpack_ctrl.red_op = state_q.red_op;
unpack_ctrl.alt_count_valid = DONT_CARE_ZERO ? '0 : 'x;
unique case (state_q.emul)
EMUL_1: unpack_ctrl.alt_count_valid = state_q.alt_count.val[COUNTER_W-1 -: 4] == '0;
Expand Down Expand Up @@ -858,6 +863,7 @@ module vproc_pipeline import vproc_pkg::*; #(
logic unit_out_ready;
logic [XIF_ID_W -1:0] unit_out_instr_id;
vproc_pkg::cfg_vsew unit_out_eew;
vproc_pkg::cfg_emul unit_out_emul;
logic [4:0] unit_out_vaddr;
logic unit_out_res_vaddr;
logic [RES_CNT-1:0] unit_out_res_store;
Expand Down Expand Up @@ -896,6 +902,7 @@ module vproc_pipeline import vproc_pkg::*; #(
.pipe_out_ready_i ( unit_out_ready ),
.pipe_out_instr_id_o ( unit_out_instr_id ),
.pipe_out_eew_o ( unit_out_eew ),
.pipe_out_emul_o ( unit_out_emul ),
.pipe_out_vaddr_o ( unit_out_vaddr ),
.pipe_out_res_store_o ( unit_out_res_store ),
.pipe_out_res_valid_o ( unit_out_res_valid ),
Expand Down Expand Up @@ -948,6 +955,7 @@ module vproc_pipeline import vproc_pkg::*; #(
.pipe_in_ready_o ( unit_out_ready ),
.pipe_in_instr_id_i ( unit_out_instr_id ),
.pipe_in_eew_i ( unit_out_eew ),
.pipe_in_emul_i ( unit_out_emul ),
.pipe_in_vaddr_i ( unit_out_vaddr ),
.pipe_in_res_store_i ( unit_out_res_store ),
.pipe_in_res_valid_i ( unit_out_res_valid ),
Expand Down
36 changes: 27 additions & 9 deletions rtl/vproc_pipeline_wrapper.sv
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ module vproc_pipeline_wrapper import vproc_pkg::*; #(
count_inc_e count_inc; // counter increment policy
logic [2:0] field_count_init; // field counter initial value
logic requires_flush; // whether the instr requires flushing
logic red_op; // whether the instr is a reduction
logic [XIF_ID_W -1:0] id;
op_unit unit;
op_mode mode;
Expand All @@ -224,99 +225,115 @@ module vproc_pipeline_wrapper import vproc_pkg::*; #(
assign unit_elem = UNITS[UNIT_ELEM] & (pipe_in_data_i.unit == UNIT_ELEM);

// identify the type of data that vs2 supplies for ELEM instructions
logic elem_flush, elem_vs2_data, elem_vs2_mask, elem_vs2_dyn_addr;
logic elem_flush, red_op, elem_vs2_data, elem_vs2_mask, elem_vs2_dyn_addr;
always_comb begin
elem_flush = DONT_CARE_ZERO ? 1'b0 : 1'bx;
red_op = DONT_CARE_ZERO ? 1'b0 : 1'bx;
elem_vs2_data = DONT_CARE_ZERO ? 1'b0 : 1'bx;
elem_vs2_mask = DONT_CARE_ZERO ? 1'b0 : 1'bx;
elem_vs2_dyn_addr = DONT_CARE_ZERO ? 1'b0 : 1'bx;
unique case (pipe_in_data_i.mode.elem.op)
ELEM_XMV: begin
elem_flush = 1'b0;
red_op = 1'b0;
elem_vs2_data = 1'b1;
elem_vs2_mask = 1'b0;
elem_vs2_dyn_addr = 1'b0;
end
ELEM_VPOPC: begin
elem_flush = 1'b0;
red_op = 1'b0;
elem_vs2_data = 1'b0;
elem_vs2_mask = 1'b1;
elem_vs2_dyn_addr = 1'b0;
end
ELEM_VFIRST: begin
elem_flush = 1'b0;
red_op = 1'b0;
elem_vs2_data = 1'b0;
elem_vs2_mask = 1'b1;
elem_vs2_dyn_addr = 1'b0;
end
ELEM_VID: begin
elem_flush = 1'b0;
red_op = 1'b0;
elem_vs2_data = 1'b0;
elem_vs2_mask = 1'b0;
elem_vs2_dyn_addr = 1'b0;
end
ELEM_VIOTA: begin
elem_flush = 1'b0;
red_op = 1'b0;
elem_vs2_data = 1'b0;
elem_vs2_mask = 1'b1;
elem_vs2_dyn_addr = 1'b0;
end
ELEM_VRGATHER: begin
elem_flush = 1'b0;
red_op = 1'b0;
elem_vs2_data = 1'b0;
elem_vs2_mask = 1'b0;
elem_vs2_dyn_addr = 1'b1;
end
ELEM_VCOMPRESS: begin
elem_flush = 1'b1;
red_op = 1'b0;
elem_vs2_data = 1'b0;
elem_vs2_mask = 1'b1;
elem_vs2_dyn_addr = 1'b0;
end
ELEM_VREDSUM: begin
elem_flush = 1'b1;
elem_flush = 1'b0;
red_op = 1'b1;
elem_vs2_data = 1'b1;
elem_vs2_mask = 1'b0;
elem_vs2_dyn_addr = 1'b0;
end
ELEM_VREDAND: begin
elem_flush = 1'b1;
elem_flush = 1'b0;
red_op = 1'b1;
elem_vs2_data = 1'b1;
elem_vs2_mask = 1'b0;
elem_vs2_dyn_addr = 1'b0;
end
ELEM_VREDOR: begin
elem_flush = 1'b1;
elem_flush = 1'b0;
red_op = 1'b1;
elem_vs2_data = 1'b1;
elem_vs2_mask = 1'b0;
elem_vs2_dyn_addr = 1'b0;
end
ELEM_VREDXOR: begin
elem_flush = 1'b1;
elem_flush = 1'b0;
red_op = 1'b1;
elem_vs2_data = 1'b1;
elem_vs2_mask = 1'b0;
elem_vs2_dyn_addr = 1'b0;
end
ELEM_VREDMINU: begin
elem_flush = 1'b1;
elem_flush = 1'b0;
red_op = 1'b1;
elem_vs2_data = 1'b1;
elem_vs2_mask = 1'b0;
elem_vs2_dyn_addr = 1'b0;
end
ELEM_VREDMIN: begin
elem_flush = 1'b1;
elem_flush = 1'b0;
red_op = 1'b1;
elem_vs2_data = 1'b1;
elem_vs2_mask = 1'b0;
elem_vs2_dyn_addr = 1'b0;
end
ELEM_VREDMAXU: begin
elem_flush = 1'b1;
elem_flush = 1'b0;
red_op = 1'b1;
elem_vs2_data = 1'b1;
elem_vs2_mask = 1'b0;
elem_vs2_dyn_addr = 1'b0;
end
ELEM_VREDMAX: begin
elem_flush = 1'b1;
elem_flush = 1'b0;
red_op = 1'b1;
elem_vs2_data = 1'b1;
elem_vs2_mask = 1'b0;
elem_vs2_dyn_addr = 1'b0;
Expand Down Expand Up @@ -403,6 +420,7 @@ module vproc_pipeline_wrapper import vproc_pkg::*; #(

state_init.field_count_init = unit_lsu ? pipe_in_data_i.mode.lsu.nfields : '0;
state_init.requires_flush = unit_elem & elem_flush;
state_init.red_op = red_op;
state_init.id = pipe_in_data_i.id;
state_init.unit = pipe_in_data_i.unit;
state_init.mode = pipe_in_data_i.mode;
Expand Down
1 change: 1 addition & 0 deletions rtl/vproc_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@ typedef struct packed {
logic narrow;
logic saturate;
logic sig;
logic red_op;
logic [2:0] mul_idx;
} pack_flags;

Expand Down
5 changes: 5 additions & 0 deletions rtl/vproc_unit_mux.sv
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ module vproc_unit_mux import vproc_pkg::*; #(
input logic pipe_out_ready_i,
output logic [XIF_ID_W -1:0] pipe_out_instr_id_o,
output cfg_vsew pipe_out_eew_o,
output cfg_emul pipe_out_emul_o,
output logic [4:0] pipe_out_vaddr_o,
output logic [RES_CNT-1:0] pipe_out_res_store_o,
output logic [RES_CNT-1:0] pipe_out_res_valid_o,
Expand Down Expand Up @@ -87,6 +88,7 @@ module vproc_unit_mux import vproc_pkg::*; #(
logic [UNIT_CNT-1:0] unit_out_ready;
logic [UNIT_CNT-1:0][XIF_ID_W -1:0] unit_out_instr_id;
cfg_vsew [UNIT_CNT-1:0] unit_out_eew;
cfg_emul [UNIT_CNT-1:0] unit_out_emul;
logic [UNIT_CNT-1:0][4:0] unit_out_vaddr;
logic [UNIT_CNT-1:0][RES_CNT-1:0] unit_out_res_store;
logic [UNIT_CNT-1:0][RES_CNT-1:0] unit_out_res_valid;
Expand Down Expand Up @@ -148,6 +150,7 @@ module vproc_unit_mux import vproc_pkg::*; #(
.pipe_out_ready_i ( unit_out_ready [i] ),
.pipe_out_instr_id_o ( unit_out_instr_id [i] ),
.pipe_out_eew_o ( unit_out_eew [i] ),
.pipe_out_emul_o ( unit_out_emul [i] ),
.pipe_out_vaddr_o ( unit_out_vaddr [i] ),
.pipe_out_res_store_o ( unit_out_res_store [i] ),
.pipe_out_res_valid_o ( unit_out_res_valid [i] ),
Expand Down Expand Up @@ -247,6 +250,7 @@ module vproc_unit_mux import vproc_pkg::*; #(
pipe_out_valid_o = '0;
pipe_out_instr_id_o = DONT_CARE_ZERO ? '0 : 'x ;
pipe_out_eew_o = DONT_CARE_ZERO ? cfg_vsew' ('0) : cfg_vsew' ('x) ;
pipe_out_emul_o = DONT_CARE_ZERO ? cfg_emul' ('0) : cfg_emul' ('x) ;
pipe_out_vaddr_o = DONT_CARE_ZERO ? '0 : 'x ;
pipe_out_res_store_o = DONT_CARE_ZERO ? '0 : 'x ;
pipe_out_res_valid_o = DONT_CARE_ZERO ? '0 : 'x ;
Expand All @@ -261,6 +265,7 @@ module vproc_unit_mux import vproc_pkg::*; #(
pipe_out_valid_o = unit_out_valid [i];
pipe_out_instr_id_o = unit_out_instr_id [i];
pipe_out_eew_o = unit_out_eew [i];
pipe_out_emul_o = unit_out_emul [i];
pipe_out_vaddr_o = unit_out_vaddr [i];
pipe_out_res_store_o = unit_out_res_store [i];
pipe_out_res_valid_o = unit_out_res_valid [i];
Expand Down
9 changes: 8 additions & 1 deletion rtl/vproc_unit_wrapper.sv
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ module vproc_unit_wrapper import vproc_pkg::*; #(
input logic pipe_out_ready_i,
output logic [XIF_ID_W -1:0] pipe_out_instr_id_o,
output cfg_vsew pipe_out_eew_o,
output cfg_emul pipe_out_emul_o,
output logic [4:0] pipe_out_vaddr_o,
output logic [RES_CNT-1:0] pipe_out_res_store_o,
output logic [RES_CNT-1:0] pipe_out_res_valid_o,
Expand Down Expand Up @@ -111,6 +112,7 @@ module vproc_unit_wrapper import vproc_pkg::*; #(
always_comb begin
pipe_out_instr_id_o = unit_out_ctrl.id;
pipe_out_eew_o = unit_out_ctrl.eew;
pipe_out_emul_o = unit_out_ctrl.emul;
pipe_out_vaddr_o = unit_out_ctrl.res_vaddr;
pipe_out_res_store_o = '0;
pipe_out_res_valid_o = '0;
Expand Down Expand Up @@ -156,6 +158,7 @@ module vproc_unit_wrapper import vproc_pkg::*; #(
always_comb begin
pipe_out_instr_id_o = unit_out_ctrl.id;
pipe_out_eew_o = unit_out_ctrl.eew;
pipe_out_emul_o = unit_out_ctrl.emul;
pipe_out_vaddr_o = unit_out_ctrl.res_vaddr;
pipe_out_res_store_o = '0;
pipe_out_res_valid_o = '0;
Expand Down Expand Up @@ -211,6 +214,7 @@ module vproc_unit_wrapper import vproc_pkg::*; #(
always_comb begin
pipe_out_instr_id_o = unit_out_ctrl.id;
pipe_out_eew_o = unit_out_ctrl.eew;
pipe_out_emul_o = unit_out_ctrl.emul;
pipe_out_vaddr_o = unit_out_ctrl.res_vaddr;
pipe_out_res_store_o = '0;
pipe_out_res_valid_o = '0;
Expand Down Expand Up @@ -253,6 +257,7 @@ module vproc_unit_wrapper import vproc_pkg::*; #(
always_comb begin
pipe_out_instr_id_o = unit_out_ctrl.id;
pipe_out_eew_o = unit_out_ctrl.eew;
pipe_out_emul_o = unit_out_ctrl.emul;
pipe_out_vaddr_o = unit_out_ctrl.res_vaddr;
pipe_out_res_store_o = '0;
pipe_out_res_valid_o = '0;
Expand Down Expand Up @@ -428,6 +433,7 @@ module vproc_unit_wrapper import vproc_pkg::*; #(
always_comb begin
pipe_out_instr_id_o = flushing_q ? flushing_id_q : unit_out_ctrl.id;
pipe_out_eew_o = flushing_q ? flushing_eew_q : unit_out_ctrl.eew;
pipe_out_emul_o = flushing_q ? flushing_emul_q : unit_out_ctrl.emul;
pipe_out_vaddr_o = DONT_CARE_ZERO ? '0 : 'x;
unique case (flushing_q ? flushing_emul_q : unit_out_ctrl.emul)
EMUL_1: pipe_out_vaddr_o = base_vaddr;
Expand All @@ -449,7 +455,8 @@ module vproc_unit_wrapper import vproc_pkg::*; #(
default: ;
endcase
pipe_out_res_flags_o[0].elemwise = 1'b1;
pipe_out_res_store_o[0] = ((~unit_out_ctrl.mode.elem.xreg & unit_out_res_valid) | flushing_q) & (vd_count_d.part.low == '1);
pipe_out_res_flags_o[0].red_op = unit_out_ctrl.red_op;
pipe_out_res_store_o[0] = ((~unit_out_ctrl.mode.elem.xreg & unit_out_res_valid) | flushing_q) & (vd_count_d.part.low == '1 | unit_out_ctrl.red_op);
pipe_out_res_valid_o[0] = flushing_q | unit_out_res_valid;
pipe_out_res_data_o [0] = unit_out_res;
pipe_out_res_mask_o [0][3:0] = flushing_q ? '0 : unit_out_mask;
Expand Down
Loading