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 plb_interface PLB driver APIs
17 * @ingroup io_interfaces
18 * @{
19 */
20
21 #define PLB_SLICE_MASK (0xf)
22 #define PLB_SLICE_HIGH_BIT_MASK_SET(slice) (PLB_SLICE_MASK << ((slice - plb_type_b_slice_8) << 2))
23 #define PLB_SLICE_HIGH_BIT_SHIFT(slice) ((slice - plb_type_b_slice_8) << 2)
24 #define PLB_SLICE_LOW_BIT_MASK_SET(slice) (PLB_SLICE_MASK << (slice << 2))
25 #define PLB_SLICE_LOW_BIT_SHIFT(slice) (slice << 2)
26
27 /**
28 * @brief plb channels
29 *
30 */
31 typedef enum plb_chn {
32 #ifdef PLB_TYPE_B_0
33 plb_chn0 = PLB_TYPE_B_0,
34 #endif
35 #ifdef PLB_TYPE_B_1
36 plb_chn1 = PLB_TYPE_B_1,
37 #endif
38 #ifdef PLB_TYPE_B_2
39 plb_chn2 = PLB_TYPE_B_2,
40 #endif
41 #ifdef PLB_TYPE_B_3
42 plb_chn3 = PLB_TYPE_B_3,
43 #endif
44 #ifdef PLB_TYPE_B_4
45 plb_chn4 = PLB_TYPE_B_4,
46 #endif
47 #ifdef PLB_TYPE_B_5
48 plb_chn5 = PLB_TYPE_B_5,
49 #endif
50 #ifdef PLB_TYPE_B_6
51 plb_chn6 = PLB_TYPE_B_6,
52 #endif
53 #ifdef PLB_TYPE_B_7
54 plb_chn7 = PLB_TYPE_B_7,
55 #endif
56 } plb_chn_t;
57
58 /**
59 * @brief PLB look-up table unit
60 *
61 */
62 typedef enum plb_type_a_lut_num {
63 #ifdef PLB_TYPE_A_0
64 plb_type_a_table0 = PLB_TYPE_A_0,
65 #endif
66 #ifdef PLB_TYPE_A_1
67 plb_type_a_table1 = PLB_TYPE_A_1,
68 #endif
69 #ifdef PLB_TYPE_A_2
70 plb_type_a_table2 = PLB_TYPE_A_2,
71 #endif
72 #ifdef PLB_TYPE_A_3
73 plb_type_a_table3 = PLB_TYPE_A_3,
74 #endif
75 #ifdef PLB_TYPE_A_4
76 plb_type_a_table4 = PLB_TYPE_A_4,
77 #endif
78 #ifdef PLB_TYPE_A_5
79 plb_type_a_table5 = PLB_TYPE_A_5,
80 #endif
81 #ifdef PLB_TYPE_A_6
82 plb_type_a_table6 = PLB_TYPE_A_6,
83 #endif
84 #ifdef PLB_TYPE_A_7
85 plb_type_a_table7 = PLB_TYPE_A_7,
86 #endif
87 } plb_type_a_lut_num_t;
88
89 /**
90 * @brief PLB truth table configuration unit
91 *
92 */
93 typedef union {
94 struct {
95 uint16_t index0_1bit_out: 1;
96 uint16_t index1_1bit_out: 1;
97 uint16_t index2_1bit_out: 1;
98 uint16_t index3_1bit_out: 1;
99 uint16_t index4_1bit_out: 1;
100 uint16_t index5_1bit_out: 1;
101 uint16_t index6_1bit_out: 1;
102 uint16_t index7_1bit_out: 1;
103 uint16_t index8_1bit_out: 1;
104 uint16_t index9_1bit_out: 1;
105 uint16_t index10_1bit_out: 1;
106 uint16_t index11_1bit_out: 1;
107 uint16_t index12_1bit_out: 1;
108 uint16_t index13_1bit_out: 1;
109 uint16_t index14_1bit_out: 1;
110 uint16_t index15_1bit_out: 1;
111 };
112 uint16_t val;
113 } plb_type_a_truth_t;
114
115 /**
116 * @brief Index of slice
117 *
118 */
119 typedef enum plb_type_b_lut_slice {
120 plb_type_b_slice_0 = 0,
121 plb_type_b_slice_1 = 1,
122 plb_type_b_slice_2 = 2,
123 plb_type_b_slice_3 = 3,
124 plb_type_b_slice_4 = 4,
125 plb_type_b_slice_5 = 5,
126 plb_type_b_slice_6 = 6,
127 plb_type_b_slice_7 = 7,
128 plb_type_b_slice_8 = 8,
129 plb_type_b_slice_9 = 9,
130 plb_type_b_slice_10 = 10,
131 plb_type_b_slice_11 = 11,
132 plb_type_b_slice_12 = 12,
133 plb_type_b_slice_13 = 13,
134 plb_type_b_slice_14 = 14,
135 plb_type_b_slice_15 = 15,
136 } plb_type_b_lut_slice_t;
137
138 /**
139 * @brief Configuration of slice
140 *
141 */
142 typedef enum plb_type_b_slice_opt {
143 plb_slice_opt_keep = 0, /**< The data unit keeps the value of the previous cycle */
144 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 */
145 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 */
146 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 */
147 plb_slice_opt_add_one = 4, /**< The next cycle value of the data cell is the current value plus 1 */
148 plb_slice_opt_add_two = 5, /**< The next cycle value of the data cell is the current value plus 2 */
149 plb_slice_opt_sub_one = 6, /**< The next cycle value of the data cell is the current value minus 1 */
150 plb_slice_opt_sub_two = 7, /**< The next cycle value of the data cell is the current value minus 2 */
151 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 */
152 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 */
153 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 */
154 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 */
155 } plb_type_b_slice_opt_t;
156
157 /**
158 * @brief Comparator index
159 *
160 */
161 typedef enum plb_type_b_cmp {
162 plb_type_b_cmp0 = PLB_TYPE_B_CMP_0,
163 plb_type_b_cmp1 = PLB_TYPE_B_CMP_1,
164 plb_type_b_cmp2 = PLB_TYPE_B_CMP_2,
165 plb_type_b_cmp3 = PLB_TYPE_B_CMP_3,
166 } plb_type_b_cmp_t;
167
168 /**
169 * @brief Comparator operation
170 *
171 */
172 typedef enum plb_type_b_cmp_mode {
173 plb_cmp_mode_out_zero = 0, /**< output zero */
174 plb_cmp_mode_out_one = 1, /**< output one */
175 plb_cmp_mode_gt = 2, /**< Data unit greater than cmp output one, otherwise output zero */
176 plb_cmp_mode_lt = 3, /**< Data unit less than cmp output one, otherwise output zero */
177 plb_cmp_mode_eq = 4, /**< Data unit equal to cmp output one, otherwise output zero */
178 plb_cmp_mode_ne = 5, /**< Data unit not equal to cmp output one, otherwise output zero */
179 plb_cmp_mode_ge = 6, /**< Data unit greater than or equal to cmp output one, otherwise output zero */
180 plb_cmp_mode_le = 7, /**< Data unit less than or equal to cmp output one, otherwise output zero */
181 plb_cmp_mode_and_mask = 10, /**< The data cell corresponding to the bit set to one by cmp is and */
182 plb_cmp_mode_or_mask = 11, /**< The data cell corresponding to the bit set to one by cmp is or */
183 plb_cmp_mode_xor_mask = 12, /**< The data cell corresponding to the bit set to one by cmp is xor */
184 plb_cmp_mode_nand_mask = 13, /**< The data cell corresponding to the bit set to one by cmp is nand */
185 plb_cmp_mode_nor_mask = 14, /**< The data cell corresponding to the bit set to one by cmp is nor */
186 plb_cmp_mode_xnor_mask = 15, /**< The data cell corresponding to the bit set to one by cmp is xnor */
187 } plb_type_b_cmp_mode_t;
188
189
190 #ifdef __cplusplus
191 extern "C" {
192 #endif
193
194 /**
195 * @brief Configuring the truth table for lookup tables
196 *
197 * @param plb @ref PLB_Type plb base
198 * @param chn @ref plb_chn_t
199 * @param lut_num @ref plb_type_a_lut_num_t
200 * @param truth @ref plb_type_a_truth_t
201 */
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)202 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)
203 {
204 plb->TYPE_A[chn].LOOKUP_TABLE[lut_num] = PLB_TYPE_A_LOOKUP_TABLE_LOOKUP_TABLE_SET(truth->val);
205 }
206
207 /**
208 * @brief The software injects a cycle value into the TYPE A channel.
209 *
210 * @param plb @ref PLB_Type plb base
211 * @param chn @ref plb_chn_t
212 * @param inject_val Injected values
213 */
plb_type_a_inject_by_sw(PLB_Type * plb,plb_chn_t chn,uint8_t inject_val)214 static inline void plb_type_a_inject_by_sw(PLB_Type *plb, plb_chn_t chn, uint8_t inject_val)
215 {
216 plb->TYPE_A[chn].SW_INJECT = PLB_TYPE_A_SW_INJECT_SW_INJECT_SET(inject_val);
217 }
218
219 /**
220 * @brief Configure the value of the CMP
221 *
222 * @param plb @ref PLB_Type plb base
223 * @param chn @ref plb_chn_t
224 * @param cmp_index @ref plb_type_b_cmp_t
225 * @param val CMP value
226 */
plb_type_b_set_cmp_val(PLB_Type * plb,plb_chn_t chn,plb_type_b_cmp_t cmp_index,uint32_t val)227 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)
228 {
229 plb->TYPE_B[chn].CMP[cmp_index] = PLB_TYPE_B_CMP_CMP_VALUE_SET(val);
230 }
231
232 /**
233 * @brief Setting the mode of the CMP
234 *
235 * @param plb @ref PLB_Type plb base
236 * @param chn @ref plb_chn_t
237 * @param cmp_index @ref plb_type_b_cmp_t
238 * @param cmp_mode @ref plb_type_b_cmp_mode_t
239 */
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)240 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)
241 {
242 plb->TYPE_B[chn].MODE = (plb->TYPE_B[chn].MODE & (~(PLB_TYPE_B_MODE_OUT0_SEL_MASK << (cmp_index << 2)))) |
243 ((PLB_TYPE_B_MODE_OUT0_SEL_MASK & cmp_mode) << (cmp_index << 2));
244 }
245
246 /**
247 * @brief Software injection values
248 *
249 * @param plb @ref PLB_Type plb base
250 * @param chn @ref plb_chn_t
251 * @param val value
252 */
plb_type_b_inject_by_sw(PLB_Type * plb,plb_chn_t chn,uint32_t val)253 static inline void plb_type_b_inject_by_sw(PLB_Type *plb, plb_chn_t chn, uint32_t val)
254 {
255 plb->TYPE_B[chn].SW_INJECT = val;
256 }
257
258 /**
259 * @brief Configuring the PLB type_b's lookup table
260 *
261 * @param plb @ref PLB_Type plb base
262 * @param chn @ref plb_chn_t
263 * @param slice @ref plb_type_b_lut_slice_t
264 * @param opt @ref plb_type_b_slice_opt_t
265 */
266 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);
267
268 #ifdef __cplusplus
269 }
270 #endif
271
272 /**
273 * @}
274 */
275
276 #endif /* HPM_PLB_DRV_H */
277
278