|  | // Copyright lowRISC contributors. | 
|  | // Licensed under the Apache License, Version 2.0, see LICENSE for details. | 
|  | // SPDX-License-Identifier: Apache-2.0 | 
|  | // | 
|  |  | 
|  | package tlul_pkg; | 
|  |  | 
|  | // this can be either PPC or BINTREE | 
|  | // there is no functional difference, but timing and area behavior is different | 
|  | // between the two instances. PPC can result in smaller implementations when timing | 
|  | // is not critical, whereas BINTREE is favorable when timing pressure is high (but this | 
|  | // may also result in a larger implementation). on FPGA targets, BINTREE is favorable | 
|  | // both in terms of area and timing. | 
|  | parameter ArbiterImpl = "PPC"; | 
|  |  | 
|  | typedef enum logic [2:0] { | 
|  | PutFullData    = 3'h 0, | 
|  | PutPartialData = 3'h 1, | 
|  | Get            = 3'h 4 | 
|  | } tl_a_op_e; | 
|  |  | 
|  | typedef enum logic [2:0] { | 
|  | AccessAck     = 3'h 0, | 
|  | AccessAckData = 3'h 1 | 
|  | } tl_d_op_e; | 
|  |  | 
|  | typedef enum logic [2:0] { | 
|  | InstrEn       = 3'b101, | 
|  | InstrDis      = 3'b010 | 
|  | } tl_instr_en_e; | 
|  |  | 
|  | // used for intermodule connections | 
|  | typedef tl_instr_en_e tl_instr_en_t; | 
|  |  | 
|  | typedef enum logic [1:0] { | 
|  | InstrType     = 2'b01, | 
|  | DataType      = 2'b10 | 
|  | } tl_type_e; | 
|  |  | 
|  | parameter int H2DCmdMaxWidth  = 57; | 
|  | parameter int H2DCmdIntgWidth = 7; | 
|  | parameter int H2DCmdFullWidth = H2DCmdMaxWidth + H2DCmdIntgWidth; | 
|  | parameter int D2HRspMaxWidth  = 57; | 
|  | parameter int D2HRspIntgWidth = 7; | 
|  | parameter int D2HRspFullWidth = D2HRspMaxWidth + D2HRspIntgWidth; | 
|  | parameter int DataMaxWidth    = 32; | 
|  | parameter int DataIntgWidth   = 7; | 
|  | parameter int DataFullWidth   = DataMaxWidth + DataIntgWidth; | 
|  |  | 
|  | typedef struct packed { | 
|  | logic [4:0]                 rsvd; | 
|  | tl_type_e                   tl_type; | 
|  | logic [H2DCmdIntgWidth-1:0] cmd_intg; | 
|  | logic [DataIntgWidth-1:0]   data_intg; | 
|  | } tl_a_user_t; | 
|  |  | 
|  | parameter tl_a_user_t TL_A_USER_DEFAULT = '{ | 
|  | rsvd: '0, | 
|  | tl_type: DataType, | 
|  | cmd_intg:  '0, | 
|  | data_intg: '0 | 
|  | }; | 
|  |  | 
|  | typedef struct packed { | 
|  | tl_type_e                     tl_type; | 
|  | logic   [top_pkg::TL_AW-1:0]  addr; | 
|  | tl_a_op_e                     opcode; | 
|  | logic  [top_pkg::TL_DBW-1:0]  mask; | 
|  | } tl_h2d_cmd_intg_t; | 
|  |  | 
|  | typedef struct packed { | 
|  | logic                         a_valid; | 
|  | tl_a_op_e                     a_opcode; | 
|  | logic                  [2:0]  a_param; | 
|  | logic  [top_pkg::TL_SZW-1:0]  a_size; | 
|  | logic  [top_pkg::TL_AIW-1:0]  a_source; | 
|  | logic   [top_pkg::TL_AW-1:0]  a_address; | 
|  | logic  [top_pkg::TL_DBW-1:0]  a_mask; | 
|  | logic   [top_pkg::TL_DW-1:0]  a_data; | 
|  | tl_a_user_t                   a_user; | 
|  |  | 
|  | logic                         d_ready; | 
|  | } tl_h2d_t; | 
|  |  | 
|  | localparam tl_h2d_t TL_H2D_DEFAULT = '{ | 
|  | d_ready:  1'b1, | 
|  | a_opcode: tl_a_op_e'('0), | 
|  | a_user:   tl_a_user_t'('0), | 
|  | default:  '0 | 
|  | }; | 
|  |  | 
|  | typedef struct packed { | 
|  | logic [D2HRspIntgWidth-1:0]    rsp_intg; | 
|  | logic [DataIntgWidth-1:0]      data_intg; | 
|  | } tl_d_user_t; | 
|  |  | 
|  | parameter tl_d_user_t TL_D_USER_DEFAULT = '{ | 
|  | rsp_intg: '0, | 
|  | data_intg: '0 | 
|  | }; | 
|  |  | 
|  | typedef struct packed { | 
|  | logic                         d_valid; | 
|  | tl_d_op_e                     d_opcode; | 
|  | logic                  [2:0]  d_param; | 
|  | logic  [top_pkg::TL_SZW-1:0]  d_size;   // Bouncing back a_size | 
|  | logic  [top_pkg::TL_AIW-1:0]  d_source; | 
|  | logic  [top_pkg::TL_DIW-1:0]  d_sink; | 
|  | logic   [top_pkg::TL_DW-1:0]  d_data; | 
|  | tl_d_user_t                   d_user; | 
|  | logic                         d_error; | 
|  |  | 
|  | logic                         a_ready; | 
|  |  | 
|  | } tl_d2h_t; | 
|  |  | 
|  | typedef struct packed { | 
|  | tl_d_op_e                     opcode; | 
|  | logic  [top_pkg::TL_SZW-1:0]  size; | 
|  | // Temporarily removed because source changes throughout the fabric | 
|  | // and thus cannot be used for end-to-end checking. | 
|  | // A different PR will propose a work-around (a hoaky one) to see if | 
|  | // it gets the job done. | 
|  | //logic  [top_pkg::TL_AIW-1:0]  source; | 
|  | logic                         error; | 
|  | } tl_d2h_rsp_intg_t; | 
|  |  | 
|  | localparam tl_d2h_t TL_D2H_DEFAULT = '{ | 
|  | a_ready:  1'b1, | 
|  | d_opcode: tl_d_op_e'('0), | 
|  | d_user:   tl_d_user_t'(0), | 
|  | default:  '0 | 
|  | }; | 
|  |  | 
|  | // Check user for unsupported values | 
|  | function automatic logic tl_a_user_chk(tl_a_user_t user); | 
|  | logic malformed_err; | 
|  | logic unused_user; | 
|  | unused_user = |user; | 
|  | malformed_err = ~(user.tl_type inside {InstrType, DataType}); | 
|  | return malformed_err; | 
|  | endfunction // tl_a_user_chk | 
|  |  | 
|  | // extract variables used for command checking | 
|  | function automatic tl_h2d_cmd_intg_t extract_h2d_cmd_intg(tl_h2d_t tl); | 
|  | tl_h2d_cmd_intg_t payload; | 
|  | logic unused_tlul; | 
|  | unused_tlul = ^tl; | 
|  | payload.addr = tl.a_address; | 
|  | payload.opcode = tl.a_opcode; | 
|  | payload.mask = tl.a_mask; | 
|  | payload.tl_type = tl.a_user.tl_type; | 
|  | return payload; | 
|  | endfunction // extract_h2d_payload | 
|  |  | 
|  | // extract variables used for response checking | 
|  | function automatic tl_d2h_rsp_intg_t extract_d2h_rsp_intg(tl_d2h_t tl); | 
|  | tl_d2h_rsp_intg_t payload; | 
|  | logic unused_tlul; | 
|  | unused_tlul = ^tl; | 
|  | payload.opcode = tl.d_opcode; | 
|  | payload.size   = tl.d_size; | 
|  | //payload.source = tl.d_source; | 
|  | payload.error  = tl.d_error; | 
|  | return payload; | 
|  | endfunction // extract_d2h_rsp_intg | 
|  |  | 
|  | // calculate ecc for command checking | 
|  | function automatic logic [H2DCmdIntgWidth-1:0] get_cmd_intg(tl_h2d_t tl); | 
|  | logic [H2DCmdIntgWidth-1:0] cmd_intg; | 
|  | logic [H2DCmdMaxWidth-1:0] unused_cmd_payload; | 
|  | tl_h2d_cmd_intg_t cmd; | 
|  | cmd = extract_h2d_cmd_intg(tl); | 
|  | {cmd_intg, unused_cmd_payload} = prim_secded_pkg::prim_secded_64_57_enc(H2DCmdMaxWidth'(cmd)); | 
|  | return cmd_intg; | 
|  | endfunction  // get_cmd_intg | 
|  |  | 
|  | // calculate ecc for data checking | 
|  | function automatic logic [DataIntgWidth-1:0] get_data_intg(logic [top_pkg::TL_DW-1:0] data); | 
|  | logic [DataIntgWidth-1:0] data_intg; | 
|  | logic [top_pkg::TL_DW-1:0] unused_data; | 
|  | {data_intg, unused_data} = prim_secded_pkg::prim_secded_39_32_enc(data); | 
|  | return data_intg; | 
|  | endfunction  // get_data_intg | 
|  |  | 
|  | endpackage |