diff --git a/hardware/Makefile b/hardware/Makefile index 5963a0ffb..965d70779 100644 --- a/hardware/Makefile +++ b/hardware/Makefile @@ -190,6 +190,7 @@ $(veril_library)/V$(veril_top): $(config_file) Makefile ../Bender.yml $(shell fi -GNrLanes=$(nr_lanes) \ -GVLEN=$(vlen) \ -O3 \ + --hierarchical \ -Wno-fatal \ -Wno-PINCONNECTEMPTY \ -Wno-BLKANDNBLK \ diff --git a/hardware/include/ara/ara.svh b/hardware/include/ara/ara.svh index 612d72f07..a2c7c6cbc 100644 --- a/hardware/include/ara/ara.svh +++ b/hardware/include/ara/ara.svh @@ -16,6 +16,15 @@ logic[$bits(struct_t)-1:0] \ `endif + // Structs in ports of hierarchical modules are not supported in Verilator + // --> Flatten them for Verilator + `define STRUCT_PORT_BITS(bits) \ + `ifndef VERILATOR \ + struct_t \ + `else \ + logic[bits-1:0] \ + `endif + // Create a flattened vector of a struct. Make sure the first dimension is // the dimension into the vector of struct types and not the struct itself. `define STRUCT_VECT(struct_t, dim) \ diff --git a/hardware/include/ara/ara_typedef.svh b/hardware/include/ara/ara_typedef.svh new file mode 100644 index 000000000..47ea302c5 --- /dev/null +++ b/hardware/include/ara/ara_typedef.svh @@ -0,0 +1,86 @@ +// Copyright 2024 ETH Zurich and University of Bologna. +// Solderpad Hardware License, Version 0.51, see LICENSE for details. +// SPDX-License-Identifier: SHL-0.51 +// +// Author: Matteo Perotti +// Description: +// Hierarchical modules cannot have parametrized data types during Verilator's +// hierarchical verilation. + +typedef struct packed { + vid_t id; // ID of the vector instruction + + ara_op_e op; // Operation + + // Mask vector register operand + logic vm; + rvv_pkg::vew_e eew_vmask; + + vfu_e vfu; // VFU responsible for handling this instruction + + // Rescale vl taking into account the new and old EEW + logic scale_vl; + + // The lane that provides the first element of the computation + logic [$clog2(MaxNrLanes)-1:0] start_lane; + // The lane that provides the last element of the computation + logic [$clog2(MaxNrLanes)-1:0] end_lane; + + // 1st vector register operand + logic [4:0] vs1; + logic use_vs1; + opqueue_conversion_e conversion_vs1; + rvv_pkg::vew_e eew_vs1; + rvv_pkg::vew_e old_eew_vs1; + + // 2nd vector register operand + logic [4:0] vs2; + logic use_vs2; + opqueue_conversion_e conversion_vs2; + rvv_pkg::vew_e eew_vs2; + + // Use vd as an operand as well (e.g., vmacc) + logic use_vd_op; + rvv_pkg::vew_e eew_vd_op; + + // Scalar operand + elen_t scalar_op; + logic use_scalar_op; + + // If asserted: vs2 is kept in MulFPU opqueue C, and vd_op in MulFPU A + logic swap_vs2_vd_op; + + // 2nd scalar operand: stride for constant-strided vector load/stores + elen_t stride; + logic is_stride_np2; + + // Destination vector register + logic [4:0] vd; + logic use_vd; + + // Effective length multiplier + rvv_pkg::vlmul_e emul; + + // Rounding-Mode for FP operations + fpnew_pkg::roundmode_e fp_rm; + // Widen FP immediate (re-encoding) + logic wide_fp_imm; + // Resizing of FP conversions + resize_e cvt_resize; + + // Vector machine metadata + vlen_t vl; + vlen_t vstart; + rvv_pkg::vtype_t vtype; + + // Hazards + logic [NrVInsn-1:0] hazard_vs1; + logic [NrVInsn-1:0] hazard_vs2; + logic [NrVInsn-1:0] hazard_vm; + logic [NrVInsn-1:0] hazard_vd; +} pe_req_t; + +typedef struct packed { + // Each set bit indicates that the corresponding vector loop has finished execution + logic [NrVInsn-1:0] vinsn_done; +} pe_resp_t; diff --git a/hardware/src/ara.sv b/hardware/src/ara.sv index 20bc79be9..728042033 100644 --- a/hardware/src/ara.sv +++ b/hardware/src/ara.sv @@ -48,6 +48,7 @@ module ara import ara_pkg::*; #( input axi_resp_t axi_resp_i ); + `include "ara/ara_typedef.svh" import cf_math_pkg::idx_width; /////////////////// @@ -147,78 +148,6 @@ module ara import ara_pkg::*; #( vlen_t error_vl; } ara_resp_t; - typedef struct packed { - vid_t id; // ID of the vector instruction - - ara_op_e op; // Operation - - // Mask vector register operand - logic vm; - rvv_pkg::vew_e eew_vmask; - - vfu_e vfu; // VFU responsible for handling this instruction - - // Rescale vl taking into account the new and old EEW - logic scale_vl; - - // 1st vector register operand - logic [4:0] vs1; - logic use_vs1; - opqueue_conversion_e conversion_vs1; - rvv_pkg::vew_e eew_vs1; - - // 2nd vector register operand - logic [4:0] vs2; - logic use_vs2; - opqueue_conversion_e conversion_vs2; - rvv_pkg::vew_e eew_vs2; - - // Use vd as an operand as well (e.g., vmacc) - logic use_vd_op; - rvv_pkg::vew_e eew_vd_op; - - // Scalar operand - elen_t scalar_op; - logic use_scalar_op; - - // If asserted: vs2 is kept in MulFPU opqueue C, and vd_op in MulFPU A - logic swap_vs2_vd_op; - - // 2nd scalar operand: stride for constant-strided vector load/stores - elen_t stride; - logic is_stride_np2; - - // Destination vector register - logic [4:0] vd; - logic use_vd; - - // Effective length multiplier - rvv_pkg::vlmul_e emul; - - // Rounding-Mode for FP operations - fpnew_pkg::roundmode_e fp_rm; - // Widen FP immediate (re-encoding) - logic wide_fp_imm; - // Resizing of FP conversions - resize_e cvt_resize; - - // Vector machine metadata - vlen_t vl; - vlen_t vstart; - rvv_pkg::vtype_t vtype; - - // Hazards - logic [NrVInsn-1:0] hazard_vs1; - logic [NrVInsn-1:0] hazard_vs2; - logic [NrVInsn-1:0] hazard_vm; - logic [NrVInsn-1:0] hazard_vd; - } pe_req_t; - - typedef struct packed { - // Each set bit indicates that the corresponding vector loop has finished execution - logic [NrVInsn-1:0] vinsn_done; - } pe_resp_t; - ////////////////// // Dispatcher // ////////////////// @@ -400,8 +329,8 @@ module ara import ara_pkg::*; #( .FPUSupport (FPUSupport ), .FPExtSupport (FPExtSupport ), .FixPtSupport (FixPtSupport ), - .pe_req_t (pe_req_t ), - .pe_resp_t (pe_resp_t ) + .pe_req_t_bits ($bits(pe_req_t) ), + .pe_resp_t_bits ($bits(pe_resp_t) ) ) i_lane ( .clk_i (clk_i ), .rst_ni (rst_ni ), diff --git a/hardware/src/lane/lane.sv b/hardware/src/lane/lane.sv index 1dada9911..d3ac6c5f3 100644 --- a/hardware/src/lane/lane.sv +++ b/hardware/src/lane/lane.sv @@ -18,8 +18,9 @@ module lane import ara_pkg::*; import rvv_pkg::*; #( parameter fpext_support_e FPExtSupport = FPExtSupportEnable, // Support for fixed-point data types parameter fixpt_support_e FixPtSupport = FixedPointEnable, - parameter type pe_req_t = logic, - parameter type pe_resp_t = logic, + // To please Verilator + parameter int unsigned pe_req_t_bits = 0, + parameter int unsigned pe_resp_t_bits = 0, // Dependant parameters. DO NOT CHANGE! // VRF Parameters localparam int unsigned VLENB = VLEN / 8, @@ -48,11 +49,11 @@ module lane import ara_pkg::*; import rvv_pkg::*; #( output logic [4:0] fflags_ex_o, output logic fflags_ex_valid_o, // Interface with the sequencer - input `STRUCT_PORT(pe_req_t) pe_req_i, + input `STRUCT_PORT_BITS(pe_req_t_bits) pe_req_i, input logic pe_req_valid_i, input logic [NrVInsn-1:0] pe_vinsn_running_i, output logic pe_req_ready_o, - output `STRUCT_PORT(pe_resp_t) pe_resp_o, + output `STRUCT_PORT_BITS(pe_resp_t_bits) pe_resp_o, output logic alu_vinsn_done_o, output logic mfpu_vinsn_done_o, input logic [NrVInsn-1:0][NrVInsn-1:0] global_hazard_table_i, @@ -101,6 +102,9 @@ module lane import ara_pkg::*; import rvv_pkg::*; #( output logic mask_ready_o ); + `include "common_cells/registers.svh" + `include "ara/ara_typedef.svh" + /////////////////// // Definitions // ///////////////////