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