blob: 3317e87ded28b527ecf44e5a0de3a48e2a517e07 [file] [log] [blame]
`include "rvv_define.svh"
//
// IF stage, RVS to Command Queue
//
typedef struct packed {
logic [`VTYPE_VILL-1:0] vill, // 0:not illegal, 1:illegal
logic [`VTYPE_VMA-1:0] vma, // 0:inactive element undisturbed, 1:inactive element agnostic
logic [`VTYPE_VTA-1:0] vta, // 0:tail undisturbed, 1:tail agnostic
logic [`VTYPE_VSEW-1:0] vsew, // support: 000:SEW8, 001:SEW16, 010:SEW32
logic [`VTYPE_VLMUL-1:0] vlmul // support: 110:LMUL1/4, 111:LMUL1/2, 000:LMUL1, 001:LMUL2, 010:LMUL4, 011:LMUL8
} VTYPE_t;
typedef struct packed {
logic [`VCSR_VXRM-1:0] vxrm,
logic [`VCSR_VXSAT-1:0] vxsat
} VCSR_t;
typedef struct packed {
logic [`VSTART_WIDTH-1:0] vstart,
logic [`VL_WIDTH-1:0] vl,
VTYPE_t vtype,
VCSR_t vcsr
} VECTOR_CSR_t;
typedef struct packed {
logic [`PC_WIDTH-1:0] insts_pc,
logic [`INST_WIDTH-1:0] insts,
VECTOR_CSR_t vector_csr,
logic [`XLEN-1:0] rs1_data
} INST_t;
//
// ID stage, Uops Queue to Dispatch unit
//
// It is used to distinguish which execute units that VVV/VVX/VX uop is dispatch to, based on inst_encoding[6:0]
typedef enum logic [2:0] {
ALU,
PMT,
RDT,
MUL,
MAC,
LSU
} EXE_UNIT_e;
// when EXE_UNIT_e is not LSU, it is used to distinguish arithmetic instructions, based on inst_encoding[14:12]
typedef enum logic [2:0] {
OPIVV, // vs2, vs1, vd.
OPFVV, // vs2, vs1, vd/rd. float, not support
OPMVV, // vs2, vs1, vd/rd.
OPIVI, // vs2, imm[4:0], vd.
OPIVX, // vs2, rs1, vd.
OPFVF, // vs2, rs1, vd. float, not support
OPMVX, // vs2, rs1, vd/rd.
OPCFG // vset* instructions
} EXE_OPCODE_e;
// when EXE_UNIT_e is not LSU, it identifys what instruction, vadd or vmacc or ..? based on inst_encoding[31:26]
typedef enum logic [5:0] {
VADD = 6'b000_000,
VSUB = 6'b000_010,
VRSUB = 6'b000_011,
VMINU = 6'b000_100,
VMIN = 6'b000_101,
VMAXU = 6'b000_110,
VMAXU = 6'b000_111,
VAND = 6'b001_001,
VOR = 6'b001_010,
VXOR = 6'b001_011,
VRGATHER = 6'b001_100,
VSLIDEUP = 6'b001_110,
VRGATHEREI16 = 6'b001_110,
VSLIDEDOWN = 6'b001_111,
VADC = 6'b010_000,
VMADC = 6'b010_001,
VSBC = 6'b010_010,
VMSBC = 6'b010_011,
VMERGE_VMV = 6'b010_111, // it could be vmerge or vmv, based on vm field
VMSEQ = 6'b011_000,
VMSNE = 6'b011_001,
VMSLTU = 6'b011_010,
VMSLT = 6'b011_011,
VMSLEU = 6'b011_100,
VMSLE = 6'b011_101,
VMSGTU = 6'b011_110,
VMSGT = 6'b011_111,
VSADDU = 6'b100_000,
VSADD = 6'b100_001,
VSSUBU = 6'b100_010,
VSSUB = 6'b100_011,
VSLL = 6'b100_101,
VSMUL_VMVNRR = 6'b100_111, // it could be vsmul or vmv<nr>r, based on vm field
VSRL = 6'b101_000,
VSRA = 6'b101_001,
VSSRL = 6'b101_010,
VSSRA = 6'b101_011,
VNSRL = 6'b101_100,
VNSRA = 6'b101_101,
VNCLIPU = 6'b101_110,
VNCLIP = 6'b101_111,
VWREDSUMU = 6'b110_000,
VWREDSUM = 6'b110_001
} OPI_TYPE_e;
typedef enum logic [5:0] {
VREDSUM = 6'b000_000,
VREDAND = 6'b000_001,
VREDOR = 6'b000_010,
VREDXOR = 6'b000_011,
VREDMINU = 6'b000_100,
VREDMIN = 6'b000_101,
VREDMAXU = 6'b000_110,
VREDMAX = 6'b000_111,
VAADDU = 6'b001_000,
VAADD = 6'b001_001,
VASUBU = 6'b001_010,
VASUB = 6'b001_011,
VSLIDE1UP = 6'b001_110,
VSLIDE1DOWN = 6'b001_111,
VWXUNARY0 = 6'b010_000, // it could be vcpop.m, vfirst.m and vmv. They can be distinguished by vs1 field(inst_encoding[19:15]).
VXUNARY0 = 6'b010_010, // it could be vzext.vf2, vzext.vf4, vsext.vf2, vsext.vf4. They can be distinguished by vs1 field(inst_encoding[19:15]).
VMUNARY0 = 6'b010_100, // it could be vmsbf, vmsof, vmsif, viota, vid. They can be distinguished by vs1 field(inst_encoding[19:15]).
VCOMPRESS = 6'b010_111,
VMANDN = 6'b011_000,
VMAND = 6'b011_001,
VMOR = 6'b011_010,
VMXOR = 6'b011_011,
VMORN = 6'b011_100,
VMNAND = 6'b011_101,
VMNOR = 6'b011_110,
VMXNOR = 6'b011_111,
VDIVU = 6'b100_000,
VDIV = 6'b100_001,
VREMU = 6'b100_010,
VREM = 6'b100_011,
VMULHU = 6'b100_100,
VMUL = 6'b100_101,
VMULHSU = 6'b100_110,
VMULH = 6'b100_111,
VMADD = 6'b101_001,
VNMSUB = 6'b101_011,
VMACC = 6'b101_101,
VNMSAC = 6'b101_111,
VWADDU = 6'b110_000,
VWADD = 6'b110_001,
VWSUBU = 6'b110_010,
VWSUB = 6'b110_011,
VWADDU = 6'b110_100,
VWADD = 6'b110_101,
VWSUBU = 6'b110_110,
VWSUB = 6'b110_111,
VWMULU = 6'b111_000,
VWMULSU = 6'b111_010,
VWMUL = 6'b111_011,
VWMACCU = 6'b111_100,
VWMACC = 6'b111_101,
VWMACCUS = 6'b111_110,
VWMACCSU = 6'b111_111
} OPM_TYPE_e;
// when OPM_TYPE_e=vwxunary0, the uop could be vcpop.m, vfirst.m and vmv. They can be distinguished by vs1 field(inst_encoding[19:15]).
typedef enum logic [4:0] {
VMV_X_S = 5'b00000,
VCPOP = 5'b10000,
VFIRST = 5'b10001
} OPM_VWXUNARY0_e;
// when OPM_TYPE_e=vxunary0, the uop could be vzext.vf2, vzext.vf4, vsext.vf2, vsext.vf4. They can be distinguished by vs1 field(inst_encoding[19:15]).
typedef enum logic [4:0] {
VZEXT_VF4 = 5'b00100,
VSEXT_VF4 = 5'b00101,
VZEXT_VF2 = 5'b00110,
VSEXT_VF2 = 5'b00111
} OPM_VXUNARY0_e;
// when OPM_TYPE_e=vmxunary0, the uop could be vmsbf, vmsof, vmsif, viota, vid. They can be distinguished by vs1 field(inst_encoding[19:15]).
typedef enum logic [4:0] {
VMSBF = 5'b00001,
VMSOF = 5'b00010,
VMSIF = 5'b00011,
VIOTA = 5'b10000,
VID = 5'b10001
} OPM_VMXUNARY0_e;
// when EXE_UNIT_e is LSU, it identifys what LSU instruction, unit-stride load or indexed store or ..? based on inst_encoding[31:26]
typedef enum logic [1:0] {
US, // Unit-Stride
IU, // Indexed Unordered
CS, // Constant Stride
IO // Indexed Ordered
} LSU_MOP_e;
// It identifys what unit-stride instruction when LSU_MOP_e=US, based on inst_encoding[24:20]
typedef enum logic [1:0] {
US, // Unit-Stride load/store
WR, // Whole Register load/store
MK, // MasK load/store, EEW=8(inst_encoding[14:12]=3'b000)
FF // Faul-only-First load
} LSU_UMOP_e;
// It identifys what inst_encoding[11:7] is used for when LSU instruction, based on inst_encoding[5]
typedef enum logic [0] {
LOAD, // when load, inst_encoding[11:7] is seen as vs3
STORE // when load, inst_encoding[11:7] is seen as vd
} LSU_IS_STORE_e;
// combine those signals to LSU_TYPE
typedef struct packed {
logic rsv, // reserved
LSU_MOP_e lsu_mop,
LSU_UMOP_e lsu_umop,
LSU_IS_STORE_e lsu_is_store
} LSU_TYPE_t;
// function opcode
typedef union packed {
OPI_TYPE_e opi_funct,
OPM_TYPE_e opm_funct,
LSU_TYPE_t lsu_funct
} FUNCT_u;
// vs1 field
typedef union packed {
OPM_VWXUNARY0_e vwxunary0_funct,
OPM_VXUNARY0_e vxunary0_funct,
OPM_VMXUNARY0_e vmxunary0_funct,
logic [`REGFILE_INDEX_WIDTH-1:0] vs1_index,
} VS1_u;
// uop classification used for dispatch rule
typedef enum logic [1:0] {
VVV, // this uop will use 2 read ports of VRF
VVX, // this uop will use 1 read ports of VRF
VX, // this uop will use 0 read ports of VRF
MACV // this uop will use 3 read ports of VRF
} UOP_CLASS_e;
// Effective Element Width
typedef enum logic [1:0] {
EEW1,
EEW8,
EEW16,
EEW32
} EEW_e;
// the uop struct stored in Uops Queue
typedef struct packed {
logic [`PC_WIDTH-1:0] uop_pc,
EXE_UNIT_e uop_exe_unit,
EXE_OPCODE_e uop_opcode,
FUNCT_u uop_funct,
UOP_CLASS_e uop_class,
VECTOR_CSR_t vector_csr,
logic vm, // Original 32bit instruction encoding: insts[25]
logic [`REGFILE_INDEX_WIDTH-1:0] vd_index, // Original 32bit instruction encoding: insts[11:7].this index is also used as vs3 in some uops
EEW_e vd_eew,
logic vd_valid,
VS1_u vs1, // when vs1_valid=1, vs1 field is used as vs1_index to address VRF
EEW_e vs1_eew, // when vs1_valid=0, vs1 field is used to decode some OPMVV uops
logic vs1_valid,
logic [`REGFILE_INDEX_WIDTH-1:0] vs2_index, // Original 32bit instruction encoding: insts[24:20]
EEW_e vs2_eew,
logic vs2_valid,
logic [`REGFILE_INDEX_WIDTH-1:0] rd_index, // Original 32bit instruction encoding: insts[11:7].
logic rd_index_valid,
logic [`XLEN-1:0] rs1_data, // rs1_data could be from X[rs1] and imm(insts[19:15]). If it is imm, the 5-bit imm(insts[19:15]) will be sign-extend or zero-extend(shift instructions...) to XLEN-bit.
logic rs1_data_valid,
logic [`UOP_INDEX_WIDTH-1:0] uop_index, // used for calculate v0_start in DP stage
logic last_uop_valid // one instruction may be split to many uops, this signal is used to specify the last uop in those uops of one instruction.
} UOP_QUEUE_t;
//
// DP stage,
//
// specify whether the current byte belongs to 'prestart' or 'body-inactive' or 'body-active' or 'tail'
typedef enum logic [1:0] {
NOT_CHANGE, // the byte is not changed, which may belong to 'prestart' or superfluous element in widening/narrowing uop
BODY_INACTIVE, // body-inactive byte
BODY_ACTIVE, // body-active byte
TAIL // tail byte
} ELE_TYPE_e;
// the max number of byte in a vector register is VLENB
typedef ELE_TYPE_e [`VLENB-1:0] ELE_TYPE_t;
// ALU reservation station struct
typedef union packed {
logic [`VLEN-1:0] v0_data,
logic [`VLEN-1:0] vd_data
}VS3_u;
typedef struct packed {
logic [`ROB_DEPTH_WIDTH-1:0] rob_entry,
FUNCT_e uop_funct,
EXE_OPCODE_e uop_opcode,
logic [`VSTART_WIDTH-1:0] vstart,
// vm field can be used to identify vmadc.v?m/vmadc.v? uop in the same uop_funct(6'b010000).
// vm field can be used to identify vmsbc.v?m/vmsbc.v? uop in the same uop_funct(6'b010011).
logic vm,
// rounding mode
logic [`VCSR_VXRM-1:0] vxrm,
// when the uop is vmadc.v?m/vmsbc.v?m, the uop will use v0_data as the third vector operand.
// when the uop is mask uop(vmandn,vmand,...), the uop will use vd_data as the third vector operand.
VS3_u vs3_data,
// when vs1_data_valid=0, vs1_data is used to decode some OPMVV uops
// when vs1_data_valid=1, vs1_data is valid as a vector operand
VS1_u vs1,
logic [`VLEN-1:0] vs1_data,
EEW_e vs1_eew,
logic vs1_data_valid,
ELE_TYPE_t vs1_type,
logic [`VLEN-1:0] vs2_data,
EEW_e vs2_eew,
logic vs2_data_valid,
ELE_TYPE_t vs2_type,
// rs1_data could be from X[rs1] and imm(insts[19:15]). If it is imm, the 5-bit imm(insts[19:15]) will be sign-extend to XLEN-bit.
logic [`XLEN-1:0] rs1_data,
logic rs1_data_valid
} ALU_RS_t;
// DIV reservation station struct
typedef struct packed {
logic [`ROB_DEPTH_WIDTH-1:0] rob_entry,
FUNCT_e uop_funct,
EXE_OPCODE_e uop_opcode,
// when vs1_data_valid=1, vs1_data is valid as a vector operand
logic [`VLEN-1:0] vs1_data,
EEW_e vs1_eew,
logic vs1_data_valid,
ELE_TYPE_t vs1_type,
logic [`VLEN-1:0] vs2_data,
EEW_e vs2_eew,
logic vs2_data_valid,
ELE_TYPE_t vs2_type,
// rs1_data could be from X[rs1] and imm(insts[19:15]). If it is imm, the 5-bit imm(insts[19:15]) will be sign-extend to XLEN-bit.
logic [`XLEN-1:0] rs1_data,
logic rs1_data_valid
} DIV_RS_t;
// MUL and MAC reservation station struct
typedef struct packed {
logic [`ROB_DEPTH_WIDTH-1:0] rob_entry,
FUNCT_e uop_func,
EXE_OPCODE_e uop_opcode,
logic [`VCSR_VXRM-1:0] vxrm, // rounding mode
logic [`VLEN-1:0] vs1_data,
EEW_e vs1_eew,
logic vs1_data_valid,
ELE_TYPE_t vs1_type,
logic [`VLEN-1:0] vs2_data,
EEW_e vs2_eew,
logic vs2_data_valid,
ELE_TYPE_t vs2_type,
logic [`VLEN-1:0] vs3_data,
EEW_e vs3_eew,
logic vs3_data_valid,
ELE_TYPE_t vs3_type,
// rs1_data could be from X[rs1] and imm(insts[19:15]). If it is imm, the 5-bit imm(insts[19:15]) will be sign-extend to XLEN-bit.
logic [`XLEN-1:0] rs1_data,
logic rs1_data_valid
} MUL_RS_t;
// PMT and RDT reservation station struct
typedef struct packed {
logic [`ROB_DEPTH_WIDTH-1:0] rob_entry,
FUNCT_e uop_func,
EXE_OPCODE_e uop_opcode,
// Identify vmerge and vmv in the same uop_funct(6'b010111).
logic vm,
// when vs1_data_valid=0, vs1 field is valid and used to decode some OPMVV uops
// when vs1_data_valid=1, vs1_data is valid as a vector operand
VS1_u vs1,
logic [`VLEN-1:0] vs1_data,
EEW_e vs1_eew,
logic vs1_data_valid,
ELE_TYPE_t vs1_type,
logic [`VLEN-1:0] vs2_data,
EEW_e vs2_eew,
logic vs2_data_valid,
ELE_TYPE_t vs2_type,
// rs1_data could be from X[rs1] and imm(insts[19:15]). If it is imm, the 5-bit imm(insts[19:15]) will be sign-extend to XLEN-bit.
logic [`XLEN-1:0] rs1_data,
logic rs1_data_valid,
logic last_uop_valid
} PMT_RDT_RS_t;
// LSU reservation station struct
typedef struct packed {
logic [`PC_WIDTH-1:0] uop_pc,
logic [`ROB_DEPTH_WIDTH-1:0] uop_id,
LSU_TYPE_t uop_funct,
logic vidx_valid,
logic [`REGFILE_INDEX_WIDTH-1:0] vidx_addr,
logic [`VLEN-1:0] vidx_data, // vs2
ELE_TYPE_t vs2_type,
logic vregfile_read_valid,
logic [`REGFILE_INDEX_WIDTH-1:0] vregfile_read_addr,
logic [`VLEN-1:0] vregfile_read_data // vs3
ELE_TYPE_t vs3_type,
} LSU_RS_t;
//
// EX stage,
//
// send ALU's result to ROB
typedef struct packed {
logic [`ROB_DEPTH_WIDTH-1:0] rob_entry,
logic [`VLEN-1:0] w_data, // when w_type=XRF, w_data[`XLEN-1:0] will store the scalar result
W_DATA_TYPE_t w_type,
logic w_valid,
logic [`VCSR_VXSAT-1:0] vxsat,
logic ignore_vta_vma
} ALU2ROB_t;
// send uop to LSU
typedef struct packed {
// RVV send to uop_pc to help LSU match the vld/vst uop
logic [`PC_WIDTH-1:0] uop_pc,
// When LSU submit the result to RVV, LSU need to attend uop_id to help RVV retire the uop in ROB
logic [`ROB_DEPTH_WIDTH-1:0] uop_id,
// Vector regfile index interface for indexed vld/vst
logic vidx_valid,
logic [`REGFILE_INDEX_WIDTH-1:0] vidx_addr,
logic [`VLEN-1:0] vidx_data, // vs2
ELE_TYPE_t vs2_type, // mask for vs2
// Vector regfile read interface for vst
logic vregfile_read_valid,
logic [`REGFILE_INDEX_WIDTH-1:0] vregfile_read_addr,
logic [`VLEN-1:0] vregfile_read_data, // vs3
ELE_TYPE_t vs3_type // mask for vs3
} UOP_LSU_RVV2RVS_t;
// LSU feedback to RVV
typedef struct packed {
// When LSU submit the result to RVV, LSU need to attend uop_id to help RVV retire the uop in ROB
logic [`ROB_DEPTH_WIDTH-1:0] uop_id,
// LSU uop type
// When LSU complete the vstore uop, it need to tell RVV done signal and attend uop_id to help RVV retire the uops
// when load, it means the uop is vld. It enables vregfile_write_addr and vregfile_write_data, and submit the vector data to ROB
// when store, it means this store uop is done in LSU, ROB can retire this uop.
LSU_IS_STORE_e uop_type,
// Vector regfile write interface for vld
logic [`REGFILE_INDEX_WIDTH-1:0] vregfile_write_addr,
logic [`VLEN-1:0] vregfile_write_data, // vd
ELE_TYPE_t vs1_type // mask for vd
} UOP_LSU_RVS2RVV_t;
// ReOrder Buffer data struct
typedef enum logic [0] {
VRF,
XRF
} W_DATA_TYPE_t;
typedef struct packed {
logic valid, // Total valid
logic [`REGFILE_INDEX_WIDTH-1:0] w_index,
logic [`VLEN-1:0] w_data, // when w_type=XRF, w_data[`XLEN-1:0] will store the scalar result
W_DATA_TYPE_t w_type,
logic w_valid,
ELE_TYPE_t vd_type,
VECTOR_CSR_t vector_csr,
logic ignore_vta_vma
} ROB_t;
//
// WB stage, bypass and write back to VRF/XRF, trap handler
//
// write back to XRF
typedef struct packed {
logic [`REGFILE_INDEX_WIDTH-1:0] w_index,
logic [`XLEN-1:0] w_data
} WB_XRF_t;
// write back to VRF
typedef struct packed {
logic [`REGFILE_INDEX_WIDTH-1:0] w_index,
logic [`VLEN-1:0] w_data,
logic [`VLENB-1:0] w_strobe
} WB_VRF_t;
// trap handle
typedef enum logic [0] {
DECODE, // RVS find some illegal instructions when decoding,
// which means a trap occurs to the instruction that is NOT executing in RVV.
// So RVV will stop receiving new instructions from RVS, and complete all instructions in RVV.
LSU, // RVS find some illegal instructions when complete LSU transaction, like bus error,
// which means a trap occurs to the instruction that is executing in RVV.
// So RVV will top CQ to receive new instructions and flush Command Queue and Uops Queue,
// and complete the instructions in EX, ME and WB stage. And RVS need to send rob_entry of that exception instruction.
// After RVV retire all uops before that exception instruction, RVV response a ready signal for trap application.
LSU_FF // fault only first load, need to confirm whether has TLB or not.
} TRAP_INFO_e;
typedef struct packed {
logic trap_apply,
TRAP_INFO_e trap_info,
logic [`ROB_DEPTH_WIDTH-1:0] trap_uop_rob_entry
} TRAP_t;