Skip to content
Merged
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
10 changes: 7 additions & 3 deletions hw/src/spatz_controller.sv
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,8 @@ module spatz_controller
// Change vtype and vl if we have a config instruction
if (spatz_req.op == VCFG) begin
// Check if vtype is valid
if ((spatz_req.vtype.vsew > MAXEW) || (spatz_req.vtype.vlmul inside {LMUL_RES, LMUL_F8}) || (signed'(spatz_req.vtype.vlmul) + signed'($clog2(ELEN)) < signed'(spatz_req.vtype.vsew))) begin
// Illegal if SEW > MAXEW or LMUL is reserved or log2(LMUL) + log2(ELEN) < log2(SEW)
if (spatz_req.vtype.vill ||(spatz_req.vtype.vsew > MAXEW) || (spatz_req.vtype.vlmul inside {LMUL_RES}) || (signed'(spatz_req.vtype.vlmul) + signed'($clog2(ELEN)) < signed'(spatz_req.vtype.vsew) + 3)) begin
// Invalid
vtype_d = '{vill: 1'b1, vsew: EW_8, vlmul: LMUL_1, default: '0};
vl_d = '0;
Expand All @@ -194,6 +195,7 @@ module spatz_controller
unique case (spatz_req.vtype.vlmul)
LMUL_F2: vlmax >>= 1;
LMUL_F4: vlmax >>= 2;
LMUL_F8: vlmax >>= 3;
LMUL_1 : vlmax <<= 0;
LMUL_2 : vlmax <<= 1;
LMUL_4 : vlmax <<= 2;
Expand Down Expand Up @@ -882,7 +884,8 @@ module spatz_controller
end
VFU: begin
// Do not check vtype for scalar operations running on the spatz VFU
if (!decoder_rsp.spatz_req.op_arith.is_scalar) begin
// but check vtype for vfmv.f.s and vmv.x.s that have is_scalar=1 and use_vs2=1
if (!decoder_rsp.spatz_req.op_arith.is_scalar || decoder_rsp.spatz_req.use_vs2) begin
// vtype is illegal -> illegal instruction
if (vtype_q.vill) begin
issue_rsp_o.accept = 1'b0;
Expand Down Expand Up @@ -969,7 +972,8 @@ module spatz_controller
unique case (spatz_req.op_csr.addr)
riscv_instr::CSR_VSTART: rsp_d.data = elen_t'(vstart_q);
riscv_instr::CSR_VL : rsp_d.data = elen_t'(vl_q);
riscv_instr::CSR_VTYPE : rsp_d.data = elen_t'(vtype_q);
// vill must be held at XLEN-1 for RVV compliance. Snitch is a 32-bit core
riscv_instr::CSR_VTYPE : rsp_d.data = elen_t'({vtype_q.vill, 23'b0, vtype_q.vma, vtype_q.vta, vtype_q.vsew, vtype_q.vlmul});
riscv_instr::CSR_VLENB : rsp_d.data = elen_t'(VLENB);
riscv_instr::CSR_VXSAT : rsp_d.data = elen_t'(vxsat_q);
riscv_instr::CSR_VXRM : rsp_d.data = '0;
Expand Down
18 changes: 10 additions & 8 deletions hw/src/spatz_decoder.sv
Original file line number Diff line number Diff line change
Expand Up @@ -2136,30 +2136,32 @@ module spatz_decoder
riscv_instr::VSETIVLI: begin
automatic vreg_t setvl_rs1 = decoder_req_i.instr[19:15];
automatic vreg_t setvl_rd = decoder_req_i.instr[11:7];
automatic logic is_vsetivli = (decoder_req_i.instr[31:30] == 2'b11);

spatz_req.rd = setvl_rd;
spatz_req.use_rd = 1'b1;
spatz_req.op = VCFG;
spatz_req.ex_unit = CON;

// Extract vtype
if (decoder_req_i.instr[31] == 1'b0) begin
spatz_req.vtype = {1'b0, decoder_req_i.instr[27:20]};
if (decoder_req_i.instr[31] == 1'b0) begin // vsetvli
spatz_req.vtype = {decoder_req_i.instr[30:28] != '0, decoder_req_i.instr[27:20]};
spatz_req.rs1 = decoder_req_i.rs1;
end else if (decoder_req_i.instr[31:30] == 2'b11) begin
spatz_req.vtype = {1'b0, decoder_req_i.instr[27:20]};
end else if (decoder_req_i.instr[31:30] == 2'b11) begin // vsetivli
spatz_req.vtype = {decoder_req_i.instr[29:28] != '0, decoder_req_i.instr[27:20]};
spatz_req.rs1 = elen_t'(setvl_rs1);
end else if (decoder_req_i.instr[31:25] == 7'b1000000) begin
spatz_req.vtype = {1'b0, decoder_req_i.rs2[7:0]};
end else if (decoder_req_i.instr[31:25] == 7'b1000000) begin // vsetvl
spatz_req.vtype = {decoder_req_i.rs2[31:8] != '0, decoder_req_i.rs2[7:0]}; // reserved bits and vill
spatz_req.rs1 = decoder_req_i.rs1;
end else begin
illegal_instr = 1'b1;
end

// Note: For vsetivli instruction doesn't follow the rules of vsetvl and vsetvli instructions when rs1=0
// Set to maxvl or new desired value
spatz_req.rs1 = (setvl_rs1 == 0 && setvl_rd != 0) ? '1 : spatz_req.rs1;
spatz_req.rs1 = (!is_vsetivli && setvl_rs1 == 0 && setvl_rd != 0) ? '1 : spatz_req.rs1;
// Keep vl
spatz_req.op_cfg.keep_vl = setvl_rs1 == '0 && setvl_rd == '0;
spatz_req.op_cfg.keep_vl = !is_vsetivli && setvl_rs1 == '0 && setvl_rd == '0;
end

default: illegal_instr = 1'b1;
Expand Down