1 /*
2 * Copyright (c) 2023 HPMicro
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #ifndef HPM_PLB_DRV_H
9 #define HPM_PLB_DRV_H
10
11 #include "hpm_common.h"
12 #include "hpm_plb_regs.h"
13
14 /**
15 * @brief PLB driver APIs
16 * @defgroup pla_interface PLB driver APIs
17 * @ingroup io_interfaces
18 * @{
19 */
20
21 /**
22 * @brief plb channels
23 *
24 */
25 typedef enum plb_chn {
26 plb_chn0 = 0,
27 plb_chn1 = 1,
28 plb_chn2 = 2,
29 plb_chn3 = 3,
30 } plb_chn_t;
31
32 /**
33 * @brief PLB look-up table unit
34 *
35 */
36 typedef enum plb_type_a_lut_num {
37 plb_type_a_table0 = PLB_TYPE_A_0,
38 plb_type_a_table1 = PLB_TYPE_A_1,
39 plb_type_a_table2 = PLB_TYPE_A_2,
40 plb_type_a_table3 = PLB_TYPE_A_3,
41 } plb_type_a_lut_num_t;
42
43 /**
44 * @brief PLB truth table configuration unit
45 *
46 */
47 typedef union {
48 struct {
49 uint16_t index0_1bit_out: 1;
50 uint16_t index1_1bit_out: 1;
51 uint16_t index2_1bit_out: 1;
52 uint16_t index3_1bit_out: 1;
53 uint16_t index4_1bit_out: 1;
54 uint16_t index5_1bit_out: 1;
55 uint16_t index6_1bit_out: 1;
56 uint16_t index7_1bit_out: 1;
57 uint16_t index8_1bit_out: 1;
58 uint16_t index9_1bit_out: 1;
59 uint16_t index10_1bit_out: 1;
60 uint16_t index11_1bit_out: 1;
61 uint16_t index12_1bit_out: 1;
62 uint16_t index13_1bit_out: 1;
63 uint16_t index14_1bit_out: 1;
64 uint16_t index15_1bit_out: 1;
65 };
66 uint16_t val;
67 } plb_type_a_truth_t;
68
69 /**
70 * @brief Index of slice
71 *
72 */
73 typedef enum plb_type_b_lut_slice {
74 plb_type_b_slice_0 = 0,
75 plb_type_b_slice_1 = 1,
76 plb_type_b_slice_2 = 2,
77 plb_type_b_slice_3 = 3,
78 plb_type_b_slice_4 = 4,
79 plb_type_b_slice_5 = 5,
80 plb_type_b_slice_6 = 6,
81 plb_type_b_slice_7 = 7,
82 plb_type_b_slice_8 = 8,
83 plb_type_b_slice_9 = 9,
84 plb_type_b_slice_10 = 10,
85 plb_type_b_slice_11 = 11,
86 plb_type_b_slice_12 = 12,
87 plb_type_b_slice_13 = 13,
88 plb_type_b_slice_14 = 14,
89 plb_type_b_slice_15 = 15,
90 } plb_type_b_lut_slice_t;
91
92 /**
93 * @brief Configuration of slice
94 *
95 */
96 typedef enum plb_type_b_slice_opt {
97 plb_slice_opt_keep = 0, /**< The data unit keeps the value of the previous cycle */
98 plb_slice_opt_get_cmp0_val = 1, /**< The data unit will take the value of the cmp0 register as the value for the next cycle */
99 plb_slice_opt_get_cmp1_val = 2, /**< The data unit will take the value of the cmp1 register as the value for the next cycle */
100 plb_slice_opt_get_cmp2_val = 3, /**< The data unit will take the value of the cmp2 register as the value for the next cycle */
101 plb_slice_opt_add_one = 4, /**< The next cycle value of the data cell is the current value plus 1 */
102 plb_slice_opt_add_two = 5, /**< The next cycle value of the data cell is the current value plus 2 */
103 plb_slice_opt_sub_one = 6, /**< The next cycle value of the data cell is the current value minus 1 */
104 plb_slice_opt_sub_two = 7, /**< The next cycle value of the data cell is the current value minus 2 */
105 plb_slice_opt_shift_left = 4 << 8, /**< The value of the next cycle of the data cell is shifted one place to the left of the current value */
106 plb_slice_opt_shift_left_add_one = 5 << 8, /**< The next cycle value of the data cell is the current value shifted one place to the left, with the lower bit complemented by one */
107 plb_slice_opt_shift_right = 6 << 8, /**< The value of the next cycle of the data cell is shifted one place to the right of the current value */
108 plb_slice_opt_shift_right_add_one = 7 << 8, /**< The next cycle value of the data cell is the current value shifted one place to the right, with the lower bit complemented by one */
109 } plb_type_b_slice_opt_t;
110
111 /**
112 * @brief Comparator index
113 *
114 */
115 typedef enum plb_type_b_cmp {
116 plb_type_b_cmp0 = PLB_TYPE_B_CMP_0,
117 plb_type_b_cmp1 = PLB_TYPE_B_CMP_1,
118 plb_type_b_cmp2 = PLB_TYPE_B_CMP_2,
119 plb_type_b_cmp3 = PLB_TYPE_B_CMP_3,
120 } plb_type_b_cmp_t;
121
122 /**
123 * @brief Comparator operation
124 *
125 */
126 typedef enum plb_type_b_cmp_mode {
127 plb_cmp_mode_out_zero = 0, /**< output zero */
128 plb_cmp_mode_out_one = 1, /**< output one */
129 plb_cmp_mode_gt = 2, /**< Data unit greater than cmp output one, otherwise output zero */
130 plb_cmp_mode_lt = 3, /**< Data unit less than cmp output one, otherwise output zero */
131 plb_cmp_mode_eq = 4, /**< Data unit equal to cmp output one, otherwise output zero */
132 plb_cmp_mode_ne = 5, /**< Data unit not equal to cmp output one, otherwise output zero */
133 plb_cmp_mode_ge = 6, /**< Data unit greater than or equal to cmp output one, otherwise output zero */
134 plb_cmp_mode_le = 7, /**< Data unit less than or equal to cmp output one, otherwise output zero */
135 plb_cmp_mode_and_mask = 10, /**< The data cell corresponding to the bit set to one by cmp is and */
136 plb_cmp_mode_or_mask = 11, /**< The data cell corresponding to the bit set to one by cmp is or */
137 plb_cmp_mode_xor_mask = 12, /**< The data cell corresponding to the bit set to one by cmp is xor */
138 plb_cmp_mode_nand_mask = 13, /**< The data cell corresponding to the bit set to one by cmp is nand */
139 plb_cmp_mode_nor_mask = 14, /**< The data cell corresponding to the bit set to one by cmp is nor */
140 plb_cmp_mode_xnor_mask = 15, /**< The data cell corresponding to the bit set to one by cmp is xnor */
141 } plb_type_b_cmp_mode_t;
142
143
144 #ifdef __cplusplus
145 extern "C" {
146 #endif
147
148 /**
149 * @brief Configuring the truth table for lookup tables
150 *
151 * @param plb @ref PLB_Type plb base
152 * @param chn @ref plb_chn_t
153 * @param lut_num @ref plb_type_a_lut_num_t
154 * @param truth @ref plb_type_a_truth_t
155 */
plb_type_a_set_lut(PLB_Type * plb,plb_chn_t chn,plb_type_a_lut_num_t lut_num,plb_type_a_truth_t * truth)156 static inline void plb_type_a_set_lut(PLB_Type *plb, plb_chn_t chn, plb_type_a_lut_num_t lut_num, plb_type_a_truth_t *truth)
157 {
158 plb->TYPE_A[chn].LOOKUP_TABLE[lut_num] = PLB_TYPE_A_LOOKUP_TABLE_LOOKUP_TABLE_SET(truth->val);
159 }
160
161 /**
162 * @brief The software injects a cycle value into the TYPE A channel.
163 *
164 * @param plb @ref PLB_Type plb base
165 * @param chn @ref plb_chn_t
166 * @param inject_val Injected values
167 */
plb_type_a_inject_by_sw(PLB_Type * plb,plb_chn_t chn,uint8_t inject_val)168 static inline void plb_type_a_inject_by_sw(PLB_Type *plb, plb_chn_t chn, uint8_t inject_val)
169 {
170 plb->TYPE_A[chn].SW_INJECT = PLB_TYPE_A_SW_INJECT_SW_INJECT_SET(inject_val);
171 }
172
173 /**
174 * @brief Configure the value of the CMP
175 *
176 * @param plb @ref PLB_Type plb base
177 * @param chn @ref plb_chn_t
178 * @param cmp_index @ref plb_type_b_cmp_t
179 * @param val CMP value
180 */
plb_type_b_set_cmp_val(PLB_Type * plb,plb_chn_t chn,plb_type_b_cmp_t cmp_index,uint32_t val)181 static inline void plb_type_b_set_cmp_val(PLB_Type *plb, plb_chn_t chn, plb_type_b_cmp_t cmp_index, uint32_t val)
182 {
183 plb->TYPE_B[chn].CMP[cmp_index] = PLB_TYPE_B_CMP_CMP_VALUE_SET(val);
184 }
185
186 /**
187 * @brief Setting the mode of the CMP
188 *
189 * @param plb @ref PLB_Type plb base
190 * @param chn @ref plb_chn_t
191 * @param cmp_index @ref plb_type_b_cmp_t
192 * @param cmp_mode @ref plb_type_b_cmp_mode_t
193 */
plb_type_b_set_cmp_mode(PLB_Type * plb,plb_chn_t chn,plb_type_b_cmp_t cmp_index,plb_type_b_cmp_mode_t cmp_mode)194 static inline void plb_type_b_set_cmp_mode(PLB_Type *plb, plb_chn_t chn, plb_type_b_cmp_t cmp_index, plb_type_b_cmp_mode_t cmp_mode)
195 {
196 plb->TYPE_B[chn].MODE = (plb->TYPE_B[chn].MODE & (~(PLB_TYPE_B_MODE_OUT0_SEL_MASK << (cmp_index << 2)))) |
197 ((PLB_TYPE_B_MODE_OUT0_SEL_MASK & cmp_mode) << (cmp_index << 2));
198 }
199
200 /**
201 * @brief Software injection values
202 *
203 * @param plb @ref PLB_Type plb base
204 * @param chn @ref plb_chn_t
205 * @param val value
206 */
plb_type_b_inject_by_sw(PLB_Type * plb,plb_chn_t chn,uint32_t val)207 static inline void plb_type_b_inject_by_sw(PLB_Type *plb, plb_chn_t chn, uint32_t val)
208 {
209 plb->TYPE_B[chn].SW_INJECT = val;
210 }
211
212 /**
213 * @brief Configuring the PLB type_b's lookup table
214 *
215 * @param plb @ref PLB_Type plb base
216 * @param chn @ref plb_chn_t
217 * @param slice @ref plb_type_b_lut_slice_t
218 * @param opt @ref plb_type_b_slice_opt_t
219 */
220 void plb_type_b_set_lut(PLB_Type *plb, plb_chn_t chn, plb_type_b_lut_slice_t slice, plb_type_b_slice_opt_t opt);
221
222 #ifdef __cplusplus
223 }
224 #endif
225
226 /**
227 * @}
228 */
229
230 #endif /* HPM_PLB_DRV_H */
231
232