add cvikernel
commit 9f1f57a19c3c281a931dfc71b318494487193d56 Author: sophgo-forum-service <forum_service@sophgo.com> Date: Mon May 13 13:58:23 2024 +0800 [feat] cvikernel opensource for cv18xx soc. - 79b6a7, set lookup_interp_table layer_id.
This commit is contained in:
334
cvikernel/include/bmkernel/bm1822/1822_fp_convert.h
Normal file
334
cvikernel/include/bmkernel/bm1822/1822_fp_convert.h
Normal file
@ -0,0 +1,334 @@
|
||||
#ifndef ATOMIC_FP_H_
|
||||
#define ATOMIC_FP_H_
|
||||
|
||||
#if __arm__
|
||||
#define __DISABLE_FENV__
|
||||
#endif
|
||||
|
||||
#ifndef __DISABLE_FENV__
|
||||
#include <fenv.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static inline uint8_t convert_bf16_u8(uint16_t data);
|
||||
static inline uint8_t _convert_bf16_u8(uint16_t data, int int8_rnd_md);
|
||||
static inline int8_t _convert_bf16_s8(uint16_t data, int int8_rnd_md);
|
||||
static inline int8_t convert_bf16_s8(uint16_t data);
|
||||
static inline uint16_t convert_int8_bf16(uint8_t data, uint8_t sign);
|
||||
static inline uint32_t convert_fp32_u32(float fp32);
|
||||
static inline uint32_t convert_fp32_hex(float val);
|
||||
static inline float convert_hex_fp32(uint32_t hval);
|
||||
|
||||
static inline float convert_bf16_fp32(uint16_t bf16);
|
||||
static inline uint16_t convert_fp32_bf16(float fp32);
|
||||
|
||||
static inline void f32_integer(void *if32, void *o_integer, int integer_size, int accumulate, int int8_signed, int int8_rnd_md);
|
||||
//static inline void f32_integer(void *if32, void *o_integer,
|
||||
// 0 for 32 bit , 1 for 16 bit , 2 for 8 bit
|
||||
// int integer_size, int accumulate = 0, int int8_signed = 1, int int8_rnd_md = 0);
|
||||
|
||||
union convert_type_float {
|
||||
float fval;
|
||||
uint16_t bf16[2];
|
||||
uint32_t ival;
|
||||
};
|
||||
|
||||
typedef union convert_type_float convert_int_float;
|
||||
static const uint16_t NAN_VALUE = 0x7FC0;
|
||||
|
||||
//static int round_mode = 0;
|
||||
static uint8_t float_isnan(const float x) {
|
||||
//return isnan(x);
|
||||
return x != x;
|
||||
}
|
||||
|
||||
static inline int set_store_feround()
|
||||
{
|
||||
#ifndef __DISABLE_FENV__
|
||||
int round_mode = fegetround();
|
||||
fesetround(FE_TOWARDZERO);
|
||||
return round_mode;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void restore_feround(int round_mode)
|
||||
{
|
||||
#ifndef __DISABLE_FENV__
|
||||
fesetround(round_mode);
|
||||
#else
|
||||
(void)round_mode;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline uint8_t _convert_bf16_u8(uint16_t data, int int8_rnd_md)
|
||||
{
|
||||
/* convert bf16 to float32*/
|
||||
float fp32;
|
||||
convert_int_float convert_val;
|
||||
fp32 = convert_bf16_fp32(data);
|
||||
/* convert float32 to uint8_t*/
|
||||
f32_integer((void*)&fp32, &convert_val.ival, 2, 0, 0, int8_rnd_md);
|
||||
return (uint8_t) convert_val.ival;
|
||||
}
|
||||
|
||||
static inline uint8_t convert_bf16_u8(uint16_t data)
|
||||
{
|
||||
return (uint8_t) _convert_bf16_u8(data, 0);
|
||||
}
|
||||
|
||||
static inline int8_t _convert_bf16_s8(uint16_t data, int int8_rnd_md)
|
||||
{
|
||||
/* convert bf16 to float32*/
|
||||
float fp32;
|
||||
convert_int_float convert_val;
|
||||
fp32 = convert_bf16_fp32(data);
|
||||
/* convert float32 to uint8_t*/
|
||||
f32_integer((void*)&fp32, &convert_val.ival, 2, 0, 1, int8_rnd_md);
|
||||
return (int8_t) convert_val.ival;
|
||||
}
|
||||
|
||||
static inline int8_t convert_bf16_s8(uint16_t data)
|
||||
{
|
||||
return (int8_t) _convert_bf16_s8(data, 0);
|
||||
}
|
||||
|
||||
static inline uint16_t convert_int8_bf16(uint8_t data, uint8_t sign)
|
||||
{
|
||||
int32_t val = sign ? (int8_t) data : (uint8_t) data;
|
||||
/* need to round to bf16 mode */
|
||||
return convert_fp32_bf16((float) val);
|
||||
}
|
||||
|
||||
static inline uint16_t convert_fp32_bf16(float fp32)
|
||||
{
|
||||
if (float_isnan(fp32))
|
||||
return NAN_VALUE;
|
||||
convert_int_float convert_val;
|
||||
convert_val.fval = fp32;
|
||||
uint32_t input = convert_val.ival;
|
||||
uint32_t lsb = (input >> 16) & 1;
|
||||
uint32_t rounding_bias = 0x7fff + lsb;
|
||||
input += rounding_bias;
|
||||
convert_val.bf16[1] = (uint16_t) (input >> 16);
|
||||
|
||||
/* HW behavior */
|
||||
if ((convert_val.bf16[1] & 0x7f80) == 0x7f80) {
|
||||
convert_val.bf16[1] = 0x7f7f;
|
||||
}
|
||||
return convert_val.bf16[1];
|
||||
}
|
||||
|
||||
static inline uint8_t convert_fp32_u8(float fp32)
|
||||
{
|
||||
convert_int_float convert_val;
|
||||
f32_integer((void*)&fp32, &convert_val.ival, 2, 0, 0, 0);
|
||||
return (uint8_t) convert_val.ival;
|
||||
}
|
||||
|
||||
static inline int8_t convert_fp32_s8(float fp32)
|
||||
{
|
||||
convert_int_float convert_val;
|
||||
f32_integer((void*)&fp32, &convert_val.ival, 2, 0, 1, 0);
|
||||
return (int8_t) convert_val.ival;
|
||||
}
|
||||
|
||||
static inline uint32_t convert_fp32_u32(float fp32)
|
||||
{
|
||||
convert_int_float convert_val;
|
||||
f32_integer((void*)&fp32, &convert_val.ival, 0, 0, 0, 0);
|
||||
return (uint32_t) convert_val.ival;
|
||||
}
|
||||
|
||||
static inline int32_t convert_fp32_s32(float fp32)
|
||||
{
|
||||
convert_int_float convert_val;
|
||||
f32_integer((void*)&fp32, &convert_val.ival, 0, 0, 1, 0);
|
||||
return (int32_t) convert_val.ival;
|
||||
}
|
||||
|
||||
/* convert hex to float directly */
|
||||
static inline float convert_hex_fp32(uint32_t hval)
|
||||
{
|
||||
convert_int_float convert_val;
|
||||
convert_val.ival = hval;
|
||||
return convert_val.fval;
|
||||
}
|
||||
/* convert float to hex directly */
|
||||
static inline uint32_t convert_fp32_hex(float val)
|
||||
{
|
||||
convert_int_float convert_val;
|
||||
convert_val.fval = val;
|
||||
return convert_val.ival;
|
||||
}
|
||||
static inline float convert_bf16_fp32(uint16_t bf16)
|
||||
{
|
||||
convert_int_float convert_val;
|
||||
convert_val.bf16[1] = bf16;
|
||||
convert_val.bf16[0] = 0;
|
||||
return convert_val.fval;
|
||||
}
|
||||
|
||||
static inline void flt2int_flt(float x, unsigned long long* integer_part, float * sub_part, uint8_t sign)
|
||||
{
|
||||
convert_int_float work_x;
|
||||
int level_code;
|
||||
unsigned long tail_code;
|
||||
work_x.fval = x;
|
||||
level_code = ((work_x.ival >> 23) & 0xff) - 127;
|
||||
|
||||
//if the level code is negaive, the integer part of the float is zero
|
||||
if ( level_code < 0 ){
|
||||
*integer_part = 0;
|
||||
*sub_part = x;
|
||||
}
|
||||
else {
|
||||
tail_code = (work_x.ival) & 0x7fffff;
|
||||
tail_code = tail_code | 0x800000;
|
||||
|
||||
if (level_code < 23){
|
||||
tail_code >>= (23 - level_code);
|
||||
*integer_part = tail_code;
|
||||
work_x.ival &= 0xffffffff << (23 - level_code);
|
||||
*sub_part = x - work_x.fval;
|
||||
}
|
||||
else {
|
||||
tail_code <<= (level_code - 23);
|
||||
*integer_part = tail_code;
|
||||
if(level_code>30){
|
||||
*integer_part = 0x7fffffff;
|
||||
if(sign)*integer_part = 0x800000000;
|
||||
}
|
||||
*sub_part = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline static int flt2int(float ifval, int int8_rnd_md)
|
||||
{
|
||||
union {
|
||||
float floatNum;
|
||||
unsigned long intNum;
|
||||
} tempIfval;
|
||||
tempIfval.floatNum = ifval;
|
||||
uint8_t isPositive = ((tempIfval.intNum & 0x80000000UL) == 0x80000000UL) ? false : true ;
|
||||
float abs_fval = (!isPositive) ? -ifval : ifval;
|
||||
float sub_part;
|
||||
unsigned long long integer_part;
|
||||
uint8_t sign = !isPositive;
|
||||
flt2int_flt(abs_fval, &integer_part, &sub_part, sign);
|
||||
if (!isPositive)
|
||||
{
|
||||
unsigned long long result;
|
||||
if(int8_rnd_md == 0) { // round to nearest even
|
||||
if ( sub_part > 0.5f )
|
||||
{
|
||||
result = integer_part + 1;
|
||||
}
|
||||
else if (sub_part == 0.5f)
|
||||
{
|
||||
if ( integer_part & 0x1 )
|
||||
{
|
||||
result = integer_part + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = integer_part;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = integer_part;
|
||||
}
|
||||
} else { //round to zero
|
||||
result = integer_part;
|
||||
}
|
||||
if ( result > 0x80000000UL )
|
||||
{
|
||||
result = 0x80000000UL;
|
||||
}
|
||||
return -result;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned long long result;
|
||||
if(int8_rnd_md == 0) { // round to nearest even
|
||||
if ( sub_part > 0.5f )
|
||||
{
|
||||
result = integer_part + 1;
|
||||
}
|
||||
else if ( sub_part == 0.5f )
|
||||
{
|
||||
if ( integer_part & 0x1 )
|
||||
{
|
||||
result = integer_part + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = integer_part;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = integer_part;
|
||||
}
|
||||
} else {
|
||||
result = integer_part;
|
||||
}
|
||||
if ( result > 0x7fffffff )
|
||||
{
|
||||
result = 0x7fffffff;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void f32_integer(void *if32, void *o_integer, int integer_size, int accumulate, int int8_signed, int int8_rnd_md)
|
||||
{
|
||||
int i_tmp;
|
||||
float *f_tmp;
|
||||
f_tmp = (float *)if32;
|
||||
i_tmp = flt2int(*f_tmp, int8_rnd_md);
|
||||
int *o32 = (int *)o_integer;
|
||||
int dst_f32 = *o32;
|
||||
short *o16 = (short *)o_integer;
|
||||
short dst_o16 = *o32;
|
||||
char *o8 = (char *)o_integer;
|
||||
char dst_o8 = *o8;
|
||||
|
||||
if (integer_size == 0) {
|
||||
*o32 = i_tmp;
|
||||
} else if (integer_size == 1) {
|
||||
*o16 = i_tmp;
|
||||
} else{
|
||||
*o8 = i_tmp;
|
||||
int min = (int8_signed) ? -128 : 0;
|
||||
int max = (int8_signed) ? 127 : 255;
|
||||
if (i_tmp < min ){
|
||||
*o8 = min;
|
||||
}
|
||||
else if (i_tmp > max){
|
||||
*o8 = max;
|
||||
}
|
||||
//*o8 = i_tmp;
|
||||
}
|
||||
if (accumulate) {
|
||||
if (integer_size == 0) {
|
||||
*o32 += dst_f32;
|
||||
} else if (integer_size == 1) {
|
||||
*o16 += dst_o16;
|
||||
} else
|
||||
*o8 += dst_o8;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ATOMIC_FP_H_ */
|
||||
|
||||
306
cvikernel/include/bmkernel/bm1822/bm1822_tdma_reg.h
Normal file
306
cvikernel/include/bmkernel/bm1822/bm1822_tdma_reg.h
Normal file
@ -0,0 +1,306 @@
|
||||
#ifndef BM1822_TDMA_REG_H
|
||||
#define BM1822_TDMA_REG_H
|
||||
|
||||
/*
|
||||
* This file is generated by tools. Do not edit it manually.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef unsigned long long ullong;
|
||||
|
||||
typedef struct {
|
||||
uint32_t vld;
|
||||
uint32_t compress_en;
|
||||
uint32_t eod;
|
||||
uint32_t intp_en;
|
||||
uint32_t bar_en;
|
||||
uint32_t check_bf16_value;
|
||||
uint32_t trans_dir;
|
||||
uint32_t rsv00;
|
||||
uint32_t trans_fmt;
|
||||
uint32_t transpose_md;
|
||||
uint32_t rsv01;
|
||||
uint32_t intra_cmd_paral;
|
||||
uint32_t outstanding_en;
|
||||
uint32_t cmd_id;
|
||||
uint32_t spec_func;
|
||||
uint32_t dst_fmt;
|
||||
uint32_t src_fmt;
|
||||
uint32_t cmprs_fmt;
|
||||
uint32_t sys_dtype;
|
||||
uint32_t rsv2_1;
|
||||
uint32_t int8_sign;
|
||||
uint32_t compress_zero_guard;
|
||||
uint32_t int8_rnd_mode;
|
||||
uint32_t wait_id_tpu;
|
||||
uint32_t wait_id_other_tdma;
|
||||
uint32_t wait_id_sdma;
|
||||
uint32_t const_val;
|
||||
uint32_t src_base_reg_sel;
|
||||
uint32_t mv_lut_idx;
|
||||
uint32_t dst_base_reg_sel;
|
||||
uint32_t mv_lut_base;
|
||||
uint32_t rsv4_5;
|
||||
uint32_t dst_h_stride;
|
||||
uint32_t dst_c_stride_low;
|
||||
uint32_t dst_n_stride;
|
||||
uint32_t src_h_stride;
|
||||
uint32_t src_c_stride_low;
|
||||
uint32_t src_n_stride;
|
||||
uint32_t dst_c;
|
||||
uint32_t src_c;
|
||||
uint32_t dst_w;
|
||||
uint32_t dst_h;
|
||||
uint32_t src_w;
|
||||
uint32_t src_h;
|
||||
uint32_t dst_base_addr_low;
|
||||
uint32_t src_base_addr_low;
|
||||
uint32_t src_n;
|
||||
uint32_t dst_base_addr_high;
|
||||
uint32_t src_base_addr_high;
|
||||
uint32_t src_c_stride_high;
|
||||
uint32_t dst_c_stride_high;
|
||||
uint32_t compress_bias0;
|
||||
uint32_t compress_bias1;
|
||||
uint32_t layer_ID;
|
||||
} tdma_reg_t;
|
||||
|
||||
static inline void parse_tdma_reg(tdma_reg_t *r, const uint32_t *p)
|
||||
{
|
||||
r->vld = p[0] & 1;
|
||||
r->compress_en = (p[0] >> 1) & 1;
|
||||
r->eod = (p[0] >> 2) & 1;
|
||||
r->intp_en = (p[0] >> 3) & 1;
|
||||
r->bar_en = (p[0] >> 4) & 1;
|
||||
r->check_bf16_value = (p[0] >> 5) & 1;
|
||||
r->trans_dir = (p[0] >> 6) & ((1u << 2) - 1);
|
||||
r->rsv00 = (p[0] >> 8) & ((1u << 2) - 1);
|
||||
r->trans_fmt = (p[0] >> 10) & 1;
|
||||
r->transpose_md = (p[0] >> 11) & ((1u << 2) - 1);
|
||||
r->rsv01 = (p[0] >> 13) & 1;
|
||||
r->intra_cmd_paral = (p[0] >> 14) & 1;
|
||||
r->outstanding_en = (p[0] >> 15) & 1;
|
||||
r->cmd_id = (p[0] >> 16) & ((1u << 16) - 1);
|
||||
r->spec_func = p[1] & ((1u << 3) - 1);
|
||||
r->dst_fmt = (p[1] >> 3) & ((1u << 2) - 1);
|
||||
r->src_fmt = (p[1] >> 5) & ((1u << 2) - 1);
|
||||
r->cmprs_fmt = (p[1] >> 7) & 1;
|
||||
r->sys_dtype = (p[1] >> 8) & 1;
|
||||
r->rsv2_1 = (p[1] >> 9) & ((1u << 4) - 1);
|
||||
r->int8_sign = (p[1] >> 13) & 1;
|
||||
r->compress_zero_guard = (p[1] >> 14) & 1;
|
||||
r->int8_rnd_mode = (p[1] >> 15) & 1;
|
||||
r->wait_id_tpu = (p[1] >> 16) & ((1u << 16) - 1);
|
||||
r->wait_id_other_tdma = p[2] & ((1u << 16) - 1);
|
||||
r->wait_id_sdma = (p[2] >> 16) & ((1u << 16) - 1);
|
||||
r->const_val = p[3] & ((1u << 16) - 1);
|
||||
r->src_base_reg_sel = (p[3] >> 16) & ((1u << 3) - 1);
|
||||
r->mv_lut_idx = (p[3] >> 19) & 1;
|
||||
r->dst_base_reg_sel = (p[3] >> 20) & ((1u << 3) - 1);
|
||||
r->mv_lut_base = (p[3] >> 23) & 1;
|
||||
r->rsv4_5 = (p[3] >> 24) & ((1u << 8) - 1);
|
||||
r->dst_h_stride = p[4] & ((1u << 16) - 1);
|
||||
r->dst_c_stride_low = (p[4] >> 16) & ((1u << 16) - 1);
|
||||
r->dst_n_stride = p[5];
|
||||
r->src_h_stride = p[6] & ((1u << 16) - 1);
|
||||
r->src_c_stride_low = (p[6] >> 16) & ((1u << 16) - 1);
|
||||
r->src_n_stride = p[7];
|
||||
r->dst_c = p[8] & ((1u << 16) - 1);
|
||||
r->src_c = (p[8] >> 16) & ((1u << 16) - 1);
|
||||
r->dst_w = p[9] & ((1u << 16) - 1);
|
||||
r->dst_h = (p[9] >> 16) & ((1u << 16) - 1);
|
||||
r->src_w = p[10] & ((1u << 16) - 1);
|
||||
r->src_h = (p[10] >> 16) & ((1u << 16) - 1);
|
||||
r->dst_base_addr_low = p[11];
|
||||
r->src_base_addr_low = p[12];
|
||||
r->src_n = p[13] & ((1u << 16) - 1);
|
||||
r->dst_base_addr_high = (p[13] >> 16) & ((1u << 8) - 1);
|
||||
r->src_base_addr_high = (p[13] >> 24) & ((1u << 8) - 1);
|
||||
r->src_c_stride_high = p[14] & ((1u << 16) - 1);
|
||||
r->dst_c_stride_high = (p[14] >> 16) & ((1u << 16) - 1);
|
||||
r->compress_bias0 = p[15] & ((1u << 8) - 1);
|
||||
r->compress_bias1 = (p[15] >> 8) & ((1u << 8) - 1);
|
||||
r->layer_ID = (p[15] >> 16) & ((1u << 16) - 1);
|
||||
}
|
||||
|
||||
static inline void emit_tdma_reg(const tdma_reg_t *r, uint32_t *_p)
|
||||
{
|
||||
volatile uint32_t *p = (typeof(p))_p;
|
||||
p[15] = (r->compress_bias0 & ((1u << 8) - 1)) |
|
||||
((r->compress_bias1 & ((1u << 8) - 1)) << 8) |
|
||||
((r->layer_ID & ((1u << 16) - 1)) << 16);
|
||||
p[14] = (r->src_c_stride_high & ((1u << 16) - 1)) |
|
||||
((r->dst_c_stride_high & ((1u << 16) - 1)) << 16);
|
||||
p[13] = (r->src_n & ((1u << 16) - 1)) |
|
||||
((r->dst_base_addr_high & ((1u << 8) - 1)) << 16) |
|
||||
((r->src_base_addr_high & ((1u << 8) - 1)) << 24);
|
||||
p[12] = (r->src_base_addr_low & (((uint64_t)1 << 32) - 1));
|
||||
p[11] = (r->dst_base_addr_low & (((uint64_t)1 << 32) - 1));
|
||||
p[10] = (r->src_w & ((1u << 16) - 1)) |
|
||||
((r->src_h & ((1u << 16) - 1)) << 16);
|
||||
p[9] = (r->dst_w & ((1u << 16) - 1)) |
|
||||
((r->dst_h & ((1u << 16) - 1)) << 16);
|
||||
p[8] = (r->dst_c & ((1u << 16) - 1)) |
|
||||
((r->src_c & ((1u << 16) - 1)) << 16);
|
||||
p[7] = (r->src_n_stride & (((uint64_t)1 << 32) - 1));
|
||||
p[6] = (r->src_h_stride & ((1u << 16) - 1)) |
|
||||
((r->src_c_stride_low & ((1u << 16) - 1)) << 16);
|
||||
p[5] = (r->dst_n_stride & (((uint64_t)1 << 32) - 1));
|
||||
p[4] = (r->dst_h_stride & ((1u << 16) - 1)) |
|
||||
((r->dst_c_stride_low & ((1u << 16) - 1)) << 16);
|
||||
p[3] = (r->const_val & ((1u << 16) - 1)) |
|
||||
((r->src_base_reg_sel & ((1u << 3) - 1)) << 16) |
|
||||
((r->mv_lut_idx & 1) << 19) |
|
||||
((r->dst_base_reg_sel & ((1u << 3) - 1)) << 20) |
|
||||
((r->mv_lut_base & 1) << 23) |
|
||||
((r->rsv4_5 & ((1u << 8) - 1)) << 24);
|
||||
p[2] = (r->wait_id_other_tdma & ((1u << 16) - 1)) |
|
||||
((r->wait_id_sdma & ((1u << 16) - 1)) << 16);
|
||||
p[1] = (r->spec_func & ((1u << 3) - 1)) |
|
||||
((r->dst_fmt & ((1u << 2) - 1)) << 3) |
|
||||
((r->src_fmt & ((1u << 2) - 1)) << 5) |
|
||||
((r->cmprs_fmt & 1) << 7) |
|
||||
((r->sys_dtype & 1) << 8) |
|
||||
((r->rsv2_1 & ((1u << 4) - 1)) << 9) |
|
||||
((r->int8_sign & 1) << 13) |
|
||||
((r->compress_zero_guard & 1) << 14) |
|
||||
((r->int8_rnd_mode & 1) << 15) |
|
||||
((r->wait_id_tpu & ((1u << 16) - 1)) << 16);
|
||||
p[0] = (r->vld & 1) |
|
||||
((r->compress_en & 1) << 1) |
|
||||
((r->eod & 1) << 2) |
|
||||
((r->intp_en & 1) << 3) |
|
||||
((r->bar_en & 1) << 4) |
|
||||
((r->check_bf16_value & 1) << 5) |
|
||||
((r->trans_dir & ((1u << 2) - 1)) << 6) |
|
||||
((r->rsv00 & ((1u << 2) - 1)) << 8) |
|
||||
((r->trans_fmt & 1) << 10) |
|
||||
((r->transpose_md & ((1u << 2) - 1)) << 11) |
|
||||
((r->rsv01 & 1) << 13) |
|
||||
((r->intra_cmd_paral & 1) << 14) |
|
||||
((r->outstanding_en & 1) << 15) |
|
||||
((r->cmd_id & ((1u << 16) - 1)) << 16);
|
||||
}
|
||||
|
||||
static inline void reset_tdma_reg(tdma_reg_t *r)
|
||||
{
|
||||
r->vld = 0x0;
|
||||
r->compress_en = 0x0;
|
||||
r->eod = 0x0;
|
||||
r->intp_en = 0x0;
|
||||
r->bar_en = 0x0;
|
||||
r->check_bf16_value = 0x0;
|
||||
r->trans_dir = 0x0;
|
||||
r->rsv00 = 0x0;
|
||||
r->trans_fmt = 0x0;
|
||||
r->transpose_md = 0x0;
|
||||
r->rsv01 = 0x0;
|
||||
r->intra_cmd_paral = 0x0;
|
||||
r->outstanding_en = 0x0;
|
||||
r->cmd_id = 0x0;
|
||||
r->spec_func = 0x0;
|
||||
r->dst_fmt = 0x1;
|
||||
r->src_fmt = 0x1;
|
||||
r->cmprs_fmt = 0x0;
|
||||
r->sys_dtype = 0x0;
|
||||
r->rsv2_1 = 0x0;
|
||||
r->int8_sign = 0x0;
|
||||
r->compress_zero_guard = 0x0;
|
||||
r->int8_rnd_mode = 0x0;
|
||||
r->wait_id_tpu = 0x0;
|
||||
r->wait_id_other_tdma = 0x0;
|
||||
r->wait_id_sdma = 0x0;
|
||||
r->const_val = 0x0;
|
||||
r->src_base_reg_sel = 0x0;
|
||||
r->mv_lut_idx = 0x0;
|
||||
r->dst_base_reg_sel = 0x0;
|
||||
r->mv_lut_base = 0x0;
|
||||
r->rsv4_5 = 0x0;
|
||||
r->dst_h_stride = 0x1;
|
||||
r->dst_c_stride_low = 0x1;
|
||||
r->dst_n_stride = 0x1;
|
||||
r->src_h_stride = 0x1;
|
||||
r->src_c_stride_low = 0x1;
|
||||
r->src_n_stride = 0x1;
|
||||
r->dst_c = 0x1;
|
||||
r->src_c = 0x1;
|
||||
r->dst_w = 0x1;
|
||||
r->dst_h = 0x1;
|
||||
r->src_w = 0x1;
|
||||
r->src_h = 0x1;
|
||||
r->dst_base_addr_low = 0x0;
|
||||
r->src_base_addr_low = 0x0;
|
||||
r->src_n = 0x1;
|
||||
r->dst_base_addr_high = 0x0;
|
||||
r->src_base_addr_high = 0x0;
|
||||
r->src_c_stride_high = 0x0;
|
||||
r->dst_c_stride_high = 0x0;
|
||||
r->compress_bias0 = 0x0;
|
||||
r->compress_bias1 = 0x0;
|
||||
r->layer_ID = 0x0;
|
||||
}
|
||||
|
||||
static inline void trace_tdma_reg(tdma_reg_t *r, const char *tag)
|
||||
{
|
||||
#define trace_one_reg(name) \
|
||||
printf(" %s: 0x%llx\n", #name, (ullong)r->name)
|
||||
|
||||
printf("--- %s ---\n", tag);
|
||||
trace_one_reg(vld);
|
||||
trace_one_reg(compress_en);
|
||||
trace_one_reg(eod);
|
||||
trace_one_reg(intp_en);
|
||||
trace_one_reg(bar_en);
|
||||
trace_one_reg(check_bf16_value);
|
||||
trace_one_reg(trans_dir);
|
||||
trace_one_reg(rsv00);
|
||||
trace_one_reg(trans_fmt);
|
||||
trace_one_reg(transpose_md);
|
||||
trace_one_reg(rsv01);
|
||||
trace_one_reg(intra_cmd_paral);
|
||||
trace_one_reg(outstanding_en);
|
||||
trace_one_reg(cmd_id);
|
||||
trace_one_reg(spec_func);
|
||||
trace_one_reg(dst_fmt);
|
||||
trace_one_reg(src_fmt);
|
||||
trace_one_reg(cmprs_fmt);
|
||||
trace_one_reg(sys_dtype);
|
||||
trace_one_reg(rsv2_1);
|
||||
trace_one_reg(int8_sign);
|
||||
trace_one_reg(compress_zero_guard);
|
||||
trace_one_reg(int8_rnd_mode);
|
||||
trace_one_reg(wait_id_tpu);
|
||||
trace_one_reg(wait_id_other_tdma);
|
||||
trace_one_reg(wait_id_sdma);
|
||||
trace_one_reg(const_val);
|
||||
trace_one_reg(src_base_reg_sel);
|
||||
trace_one_reg(mv_lut_idx);
|
||||
trace_one_reg(dst_base_reg_sel);
|
||||
trace_one_reg(mv_lut_base);
|
||||
trace_one_reg(rsv4_5);
|
||||
trace_one_reg(dst_h_stride);
|
||||
trace_one_reg(dst_c_stride_low);
|
||||
trace_one_reg(dst_n_stride);
|
||||
trace_one_reg(src_h_stride);
|
||||
trace_one_reg(src_c_stride_low);
|
||||
trace_one_reg(src_n_stride);
|
||||
trace_one_reg(dst_c);
|
||||
trace_one_reg(src_c);
|
||||
trace_one_reg(dst_w);
|
||||
trace_one_reg(dst_h);
|
||||
trace_one_reg(src_w);
|
||||
trace_one_reg(src_h);
|
||||
trace_one_reg(dst_base_addr_low);
|
||||
trace_one_reg(src_base_addr_low);
|
||||
trace_one_reg(src_n);
|
||||
trace_one_reg(dst_base_addr_high);
|
||||
trace_one_reg(src_base_addr_high);
|
||||
trace_one_reg(src_c_stride_high);
|
||||
trace_one_reg(dst_c_stride_high);
|
||||
trace_one_reg(compress_bias0);
|
||||
trace_one_reg(compress_bias1);
|
||||
trace_one_reg(layer_ID);
|
||||
}
|
||||
#endif /* BM1822_TDMA_REG_H */
|
||||
599
cvikernel/include/bmkernel/bm1822/bm1822_tiu_reg.h
Normal file
599
cvikernel/include/bmkernel/bm1822/bm1822_tiu_reg.h
Normal file
@ -0,0 +1,599 @@
|
||||
#ifndef BM1822_TIU_REG_H
|
||||
#define BM1822_TIU_REG_H
|
||||
|
||||
/*
|
||||
* This file is generated by tools. Do not edit it manually.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef unsigned long long ullong;
|
||||
|
||||
typedef struct {
|
||||
uint32_t cmd_en;
|
||||
uint32_t cmd_end;
|
||||
uint32_t cmd_id_en;
|
||||
uint32_t cmd_keep;
|
||||
uint32_t cmd_intr_en;
|
||||
uint32_t tsk_typ;
|
||||
uint32_t tsk_eu_typ;
|
||||
uint32_t tsk_opd_num;
|
||||
uint32_t opt_res_shift;
|
||||
uint32_t opt_left_shift;
|
||||
uint32_t opt_shift_typ;
|
||||
uint32_t opt_rshift_typ;
|
||||
uint32_t dummy1;
|
||||
uint32_t opd_typ;
|
||||
uint32_t opt_chl_quan;
|
||||
uint32_t cmd_id_tpu;
|
||||
uint32_t cmd_id_gdma;
|
||||
uint32_t quan_m;
|
||||
uint32_t opt_res0_sign;
|
||||
uint32_t opt_opd0_sign;
|
||||
uint32_t opt_opd1_sign;
|
||||
uint32_t opt_opd2_sign;
|
||||
uint32_t opt_res0_seg;
|
||||
uint32_t opt_opd0_seg;
|
||||
uint32_t opt_opd1_seg;
|
||||
uint32_t opt_opd2_seg;
|
||||
uint32_t ps32_md;
|
||||
uint32_t double_conv;
|
||||
uint32_t opt_left_tran;
|
||||
uint32_t fp_round_typ;
|
||||
uint32_t opt_relu_typ;
|
||||
uint32_t opt_relu_value;
|
||||
uint32_t cmd_pre_exe_typ;
|
||||
uint32_t opt_res_add;
|
||||
uint32_t rsvd0;
|
||||
uint32_t conv_opd0_x_ins0;
|
||||
uint32_t conv_opd0_y_ins0;
|
||||
uint32_t conv_opd0_x_ins0_last;
|
||||
uint32_t conv_opd0_y_ins0_last;
|
||||
uint32_t conv_opd1_x_ins0;
|
||||
uint32_t conv_opd1_y_ins0;
|
||||
uint32_t dummy0;
|
||||
uint32_t opd0_ins_val;
|
||||
uint32_t conv_opd0_up_pad;
|
||||
uint32_t conv_opd0_dn_pad;
|
||||
uint32_t conv_opd0_lf_pad;
|
||||
uint32_t conv_opd0_rt_pad;
|
||||
uint32_t res0_n;
|
||||
uint32_t res0_c;
|
||||
uint32_t res0_h;
|
||||
uint32_t res0_w;
|
||||
uint32_t conv_op_x_str;
|
||||
uint32_t conv_op_y_str;
|
||||
uint32_t cmd_pre_exe;
|
||||
uint32_t rsvd1;
|
||||
uint32_t res0_addr;
|
||||
uint32_t opd0_addr;
|
||||
uint32_t opd1_addr;
|
||||
uint32_t opd2_addr;
|
||||
uint32_t opt_opd0_const;
|
||||
uint32_t opt_opd1_const;
|
||||
uint32_t opt_opd2_const;
|
||||
uint32_t short_nchwstr_same;
|
||||
uint32_t short_res0_str;
|
||||
uint32_t short_opd0_str;
|
||||
uint32_t short_opd1_str;
|
||||
uint32_t short_opd2_str;
|
||||
uint32_t dummy2;
|
||||
uint32_t opd0_n;
|
||||
uint32_t opd0_c;
|
||||
uint32_t dummy3;
|
||||
uint32_t rsvd2;
|
||||
uint32_t opd0_h;
|
||||
uint32_t opd0_w;
|
||||
uint32_t opd1_n;
|
||||
uint32_t opd1_c;
|
||||
uint32_t opd1_h;
|
||||
uint32_t opd1_w;
|
||||
uint32_t opd2_n;
|
||||
uint32_t opd2_c;
|
||||
uint32_t opd2_h;
|
||||
uint32_t opd2_w;
|
||||
uint32_t dummy4;
|
||||
uint32_t rsvd3;
|
||||
uint32_t layer_info;
|
||||
uint32_t res0_n_str;
|
||||
uint32_t res0_c_str;
|
||||
uint32_t res0_h_str;
|
||||
uint32_t res0_w_str;
|
||||
uint32_t res0_b_str;
|
||||
uint32_t opd0_n_str;
|
||||
uint32_t dummy5;
|
||||
uint32_t rsvd4;
|
||||
uint32_t opd0_c_str;
|
||||
uint32_t opd0_h_str;
|
||||
uint32_t opd0_w_str;
|
||||
uint32_t opd0_b_str;
|
||||
uint32_t opd1_n_str;
|
||||
uint32_t opd1_c_str;
|
||||
uint32_t opd1_h_str;
|
||||
uint32_t dummy6;
|
||||
uint32_t rsvd5;
|
||||
uint32_t opd1_w_str;
|
||||
uint32_t opd1_b_str;
|
||||
uint32_t opd2_n_str;
|
||||
uint32_t opd2_c_str;
|
||||
uint32_t opd2_h_str;
|
||||
uint32_t opd2_w_str;
|
||||
uint32_t opd2_b_str;
|
||||
uint32_t dummy7;
|
||||
uint32_t rsvd6;
|
||||
} tiu_reg_t;
|
||||
|
||||
static inline void parse_tiu_reg(tiu_reg_t *r, const uint32_t *p)
|
||||
{
|
||||
r->cmd_en = p[0] & 1;
|
||||
r->cmd_end = (p[0] >> 1) & 1;
|
||||
r->cmd_id_en = (p[0] >> 2) & 1;
|
||||
r->cmd_keep = (p[0] >> 3) & 1;
|
||||
r->cmd_intr_en = (p[0] >> 4) & 1;
|
||||
r->tsk_typ = (p[0] >> 5) & ((1u << 4) - 1);
|
||||
r->tsk_eu_typ = (p[0] >> 9) & ((1u << 5) - 1);
|
||||
r->tsk_opd_num = (p[0] >> 14) & ((1u << 2) - 1);
|
||||
r->opt_res_shift = (p[0] >> 16) & ((1u << 6) - 1);
|
||||
r->opt_left_shift = (p[0] >> 22) & ((1u << 5) - 1);
|
||||
r->opt_shift_typ = (p[0] >> 27) & 1;
|
||||
r->opt_rshift_typ = (p[0] >> 28) & 1;
|
||||
r->dummy1 = (p[0] >> 29) & 1;
|
||||
r->opd_typ = (p[0] >> 30) & 1;
|
||||
r->opt_chl_quan = (p[0] >> 31) & 1;
|
||||
r->cmd_id_tpu = p[1] & ((1u << 16) - 1);
|
||||
r->cmd_id_gdma = (p[1] >> 16) & ((1u << 16) - 1);
|
||||
r->quan_m = p[2];
|
||||
r->opt_res0_sign = p[3] & 1;
|
||||
r->opt_opd0_sign = (p[3] >> 1) & 1;
|
||||
r->opt_opd1_sign = (p[3] >> 2) & 1;
|
||||
r->opt_opd2_sign = (p[3] >> 3) & 1;
|
||||
r->opt_res0_seg = (p[3] >> 4) & ((1u << 2) - 1);
|
||||
r->opt_opd0_seg = (p[3] >> 6) & ((1u << 2) - 1);
|
||||
r->opt_opd1_seg = (p[3] >> 8) & ((1u << 2) - 1);
|
||||
r->opt_opd2_seg = (p[3] >> 10) & 1;
|
||||
r->ps32_md = (p[3] >> 11) & ((1u << 2) - 1);
|
||||
r->double_conv = (p[3] >> 13) & 1;
|
||||
r->opt_left_tran = (p[3] >> 14) & 1;
|
||||
r->fp_round_typ = (p[3] >> 15) & 1;
|
||||
r->opt_relu_typ = (p[3] >> 16) & ((1u << 2) - 1);
|
||||
r->opt_relu_value = (p[3] >> 18) & ((1u << 8) - 1);
|
||||
r->cmd_pre_exe_typ = (p[3] >> 26) & 1;
|
||||
r->opt_res_add = (p[3] >> 27) & 1;
|
||||
r->rsvd0 = (p[3] >> 28) & ((1u << 4) - 1);
|
||||
r->conv_opd0_x_ins0 = p[4] & ((1u << 4) - 1);
|
||||
r->conv_opd0_y_ins0 = (p[4] >> 4) & ((1u << 4) - 1);
|
||||
r->conv_opd0_x_ins0_last = (p[4] >> 8) & ((1u << 4) - 1);
|
||||
r->conv_opd0_y_ins0_last = (p[4] >> 12) & ((1u << 4) - 1);
|
||||
r->conv_opd1_x_ins0 = (p[4] >> 16) & ((1u << 4) - 1);
|
||||
r->conv_opd1_y_ins0 = (p[4] >> 20) & ((1u << 4) - 1);
|
||||
r->dummy0 = (p[4] >> 24) & ((1u << 8) - 1);
|
||||
r->opd0_ins_val = p[5] & ((1u << 16) - 1);
|
||||
r->conv_opd0_up_pad = (p[5] >> 16) & ((1u << 4) - 1);
|
||||
r->conv_opd0_dn_pad = (p[5] >> 20) & ((1u << 4) - 1);
|
||||
r->conv_opd0_lf_pad = (p[5] >> 24) & ((1u << 4) - 1);
|
||||
r->conv_opd0_rt_pad = (p[5] >> 28) & ((1u << 4) - 1);
|
||||
r->res0_n = p[6] & ((1u << 12) - 1);
|
||||
r->res0_c = (p[6] >> 12) & ((1u << 12) - 1);
|
||||
r->res0_h = (p[6] >> 24) & ((1u << 8) - 1);
|
||||
r->res0_h |= (uint64_t)(p[7] & ((1u << 4) - 1)) << 8;
|
||||
r->res0_w = (p[7] >> 4) & ((1u << 12) - 1);
|
||||
r->conv_op_x_str = (p[7] >> 16) & ((1u << 5) - 1);
|
||||
r->conv_op_y_str = (p[7] >> 21) & ((1u << 5) - 1);
|
||||
r->cmd_pre_exe = (p[7] >> 26) & ((1u << 2) - 1);
|
||||
r->rsvd1 = (p[7] >> 28) & ((1u << 4) - 1);
|
||||
r->res0_addr = p[8] & ((1u << 24) - 1);
|
||||
r->opd0_addr = (p[8] >> 24) & ((1u << 8) - 1);
|
||||
r->opd0_addr |= (uint64_t)(p[9] & ((1u << 16) - 1)) << 8;
|
||||
r->opd1_addr = (p[9] >> 16) & ((1u << 16) - 1);
|
||||
r->opd2_addr = p[10] & ((1u << 16) - 1);
|
||||
r->opt_opd0_const = (p[10] >> 16) & 1;
|
||||
r->opt_opd1_const = (p[10] >> 17) & 1;
|
||||
r->opt_opd2_const = (p[10] >> 18) & 1;
|
||||
r->short_nchwstr_same = (p[10] >> 19) & 1;
|
||||
r->short_res0_str = (p[10] >> 20) & ((1u << 2) - 1);
|
||||
r->short_opd0_str = (p[10] >> 22) & ((1u << 2) - 1);
|
||||
r->short_opd1_str = (p[10] >> 24) & ((1u << 2) - 1);
|
||||
r->short_opd2_str = (p[10] >> 26) & ((1u << 2) - 1);
|
||||
r->dummy2 = (p[10] >> 28) & ((1u << 4) - 1);
|
||||
r->opd0_n = p[11] & ((1u << 12) - 1);
|
||||
r->opd0_c = (p[11] >> 12) & ((1u << 12) - 1);
|
||||
r->dummy3 = (p[11] >> 24) & ((1u << 4) - 1);
|
||||
r->rsvd2 = (p[11] >> 28) & ((1u << 4) - 1);
|
||||
r->opd0_h = p[12] & ((1u << 12) - 1);
|
||||
r->opd0_w = (p[12] >> 12) & ((1u << 12) - 1);
|
||||
r->opd1_n = (p[12] >> 24) & ((1u << 8) - 1);
|
||||
r->opd1_n |= (uint64_t)(p[13] & ((1u << 4) - 1)) << 8;
|
||||
r->opd1_c = (p[13] >> 4) & ((1u << 12) - 1);
|
||||
r->opd1_h = (p[13] >> 16) & ((1u << 12) - 1);
|
||||
r->opd1_w = (p[13] >> 28) & ((1u << 4) - 1);
|
||||
r->opd1_w |= (uint64_t)(p[14] & ((1u << 8) - 1)) << 4;
|
||||
r->opd2_n = (p[14] >> 8) & ((1u << 12) - 1);
|
||||
r->opd2_c = (p[14] >> 20) & ((1u << 12) - 1);
|
||||
r->opd2_h = p[15] & ((1u << 12) - 1);
|
||||
r->opd2_w = (p[15] >> 12) & ((1u << 12) - 1);
|
||||
r->dummy4 = (p[15] >> 24) & ((1u << 4) - 1);
|
||||
r->rsvd3 = (p[15] >> 28) & ((1u << 4) - 1);
|
||||
r->layer_info = p[16] & ((1u << 16) - 1);
|
||||
r->res0_n_str = (p[16] >> 16) & ((1u << 16) - 1);
|
||||
r->res0_c_str = p[17] & ((1u << 16) - 1);
|
||||
r->res0_h_str = (p[17] >> 16) & ((1u << 16) - 1);
|
||||
r->res0_w_str = p[18] & ((1u << 16) - 1);
|
||||
r->res0_b_str = (p[18] >> 16) & ((1u << 16) - 1);
|
||||
r->opd0_n_str = p[19] & ((1u << 16) - 1);
|
||||
r->dummy5 = (p[19] >> 16) & ((1u << 12) - 1);
|
||||
r->rsvd4 = (p[19] >> 28) & ((1u << 4) - 1);
|
||||
r->opd0_c_str = p[20] & ((1u << 16) - 1);
|
||||
r->opd0_h_str = (p[20] >> 16) & ((1u << 16) - 1);
|
||||
r->opd0_w_str = p[21] & ((1u << 16) - 1);
|
||||
r->opd0_b_str = (p[21] >> 16) & ((1u << 16) - 1);
|
||||
r->opd1_n_str = p[22] & ((1u << 16) - 1);
|
||||
r->opd1_c_str = (p[22] >> 16) & ((1u << 16) - 1);
|
||||
r->opd1_h_str = p[23] & ((1u << 16) - 1);
|
||||
r->dummy6 = (p[23] >> 16) & ((1u << 12) - 1);
|
||||
r->rsvd5 = (p[23] >> 28) & ((1u << 4) - 1);
|
||||
r->opd1_w_str = p[24] & ((1u << 16) - 1);
|
||||
r->opd1_b_str = (p[24] >> 16) & ((1u << 16) - 1);
|
||||
r->opd2_n_str = p[25] & ((1u << 16) - 1);
|
||||
r->opd2_c_str = (p[25] >> 16) & ((1u << 16) - 1);
|
||||
r->opd2_h_str = p[26] & ((1u << 16) - 1);
|
||||
r->opd2_w_str = (p[26] >> 16) & ((1u << 16) - 1);
|
||||
r->opd2_b_str = p[27] & ((1u << 16) - 1);
|
||||
r->dummy7 = (p[27] >> 16) & ((1u << 12) - 1);
|
||||
r->rsvd6 = (p[27] >> 28) & ((1u << 4) - 1);
|
||||
}
|
||||
|
||||
static inline void emit_tiu_reg(const tiu_reg_t *r, uint32_t *_p)
|
||||
{
|
||||
volatile uint32_t *p = (typeof(p))_p;
|
||||
p[27] = (r->opd2_b_str & ((1u << 16) - 1)) |
|
||||
((r->dummy7 & ((1u << 12) - 1)) << 16) |
|
||||
((r->rsvd6 & ((1u << 4) - 1)) << 28);
|
||||
p[26] = (r->opd2_h_str & ((1u << 16) - 1)) |
|
||||
((r->opd2_w_str & ((1u << 16) - 1)) << 16);
|
||||
p[25] = (r->opd2_n_str & ((1u << 16) - 1)) |
|
||||
((r->opd2_c_str & ((1u << 16) - 1)) << 16);
|
||||
p[24] = (r->opd1_w_str & ((1u << 16) - 1)) |
|
||||
((r->opd1_b_str & ((1u << 16) - 1)) << 16);
|
||||
p[23] = (r->opd1_h_str & ((1u << 16) - 1)) |
|
||||
((r->dummy6 & ((1u << 12) - 1)) << 16) |
|
||||
((r->rsvd5 & ((1u << 4) - 1)) << 28);
|
||||
p[22] = (r->opd1_n_str & ((1u << 16) - 1)) |
|
||||
((r->opd1_c_str & ((1u << 16) - 1)) << 16);
|
||||
p[21] = (r->opd0_w_str & ((1u << 16) - 1)) |
|
||||
((r->opd0_b_str & ((1u << 16) - 1)) << 16);
|
||||
p[20] = (r->opd0_c_str & ((1u << 16) - 1)) |
|
||||
((r->opd0_h_str & ((1u << 16) - 1)) << 16);
|
||||
p[19] = (r->opd0_n_str & ((1u << 16) - 1)) |
|
||||
((r->dummy5 & ((1u << 12) - 1)) << 16) |
|
||||
((r->rsvd4 & ((1u << 4) - 1)) << 28);
|
||||
p[18] = (r->res0_w_str & ((1u << 16) - 1)) |
|
||||
((r->res0_b_str & ((1u << 16) - 1)) << 16);
|
||||
p[17] = (r->res0_c_str & ((1u << 16) - 1)) |
|
||||
((r->res0_h_str & ((1u << 16) - 1)) << 16);
|
||||
p[16] = (r->layer_info & ((1u << 16) - 1)) |
|
||||
((r->res0_n_str & ((1u << 16) - 1)) << 16);
|
||||
p[15] = (r->opd2_h & ((1u << 12) - 1)) |
|
||||
((r->opd2_w & ((1u << 12) - 1)) << 12) |
|
||||
((r->dummy4 & ((1u << 4) - 1)) << 24) |
|
||||
((r->rsvd3 & ((1u << 4) - 1)) << 28);
|
||||
p[14] = ((r->opd1_w >> 4) & ((1u << 8) - 1)) |
|
||||
((r->opd2_n & ((1u << 12) - 1)) << 8) |
|
||||
((r->opd2_c & ((1u << 12) - 1)) << 20);
|
||||
p[13] = ((r->opd1_n >> 8) & ((1u << 4) - 1)) |
|
||||
((r->opd1_c & ((1u << 12) - 1)) << 4) |
|
||||
((r->opd1_h & ((1u << 12) - 1)) << 16) |
|
||||
((r->opd1_w & ((1u << 4) - 1)) << 28);
|
||||
p[12] = (r->opd0_h & ((1u << 12) - 1)) |
|
||||
((r->opd0_w & ((1u << 12) - 1)) << 12) |
|
||||
((r->opd1_n & ((1u << 8) - 1)) << 24);
|
||||
p[11] = (r->opd0_n & ((1u << 12) - 1)) |
|
||||
((r->opd0_c & ((1u << 12) - 1)) << 12) |
|
||||
((r->dummy3 & ((1u << 4) - 1)) << 24) |
|
||||
((r->rsvd2 & ((1u << 4) - 1)) << 28);
|
||||
p[10] = (r->opd2_addr & ((1u << 16) - 1)) |
|
||||
((r->opt_opd0_const & 1) << 16) |
|
||||
((r->opt_opd1_const & 1) << 17) |
|
||||
((r->opt_opd2_const & 1) << 18) |
|
||||
((r->short_nchwstr_same & 1) << 19) |
|
||||
((r->short_res0_str & ((1u << 2) - 1)) << 20) |
|
||||
((r->short_opd0_str & ((1u << 2) - 1)) << 22) |
|
||||
((r->short_opd1_str & ((1u << 2) - 1)) << 24) |
|
||||
((r->short_opd2_str & ((1u << 2) - 1)) << 26) |
|
||||
((r->dummy2 & ((1u << 4) - 1)) << 28);
|
||||
p[9] = ((r->opd0_addr >> 8) & ((1u << 16) - 1)) |
|
||||
((r->opd1_addr & ((1u << 16) - 1)) << 16);
|
||||
p[8] = (r->res0_addr & ((1u << 24) - 1)) |
|
||||
((r->opd0_addr & ((1u << 8) - 1)) << 24);
|
||||
p[7] = ((r->res0_h >> 8) & ((1u << 4) - 1)) |
|
||||
((r->res0_w & ((1u << 12) - 1)) << 4) |
|
||||
((r->conv_op_x_str & ((1u << 5) - 1)) << 16) |
|
||||
((r->conv_op_y_str & ((1u << 5) - 1)) << 21) |
|
||||
((r->cmd_pre_exe & ((1u << 2) - 1)) << 26) |
|
||||
((r->rsvd1 & ((1u << 4) - 1)) << 28);
|
||||
p[6] = (r->res0_n & ((1u << 12) - 1)) |
|
||||
((r->res0_c & ((1u << 12) - 1)) << 12) |
|
||||
((r->res0_h & ((1u << 8) - 1)) << 24);
|
||||
p[5] = (r->opd0_ins_val & ((1u << 16) - 1)) |
|
||||
((r->conv_opd0_up_pad & ((1u << 4) - 1)) << 16) |
|
||||
((r->conv_opd0_dn_pad & ((1u << 4) - 1)) << 20) |
|
||||
((r->conv_opd0_lf_pad & ((1u << 4) - 1)) << 24) |
|
||||
((r->conv_opd0_rt_pad & ((1u << 4) - 1)) << 28);
|
||||
p[4] = (r->conv_opd0_x_ins0 & ((1u << 4) - 1)) |
|
||||
((r->conv_opd0_y_ins0 & ((1u << 4) - 1)) << 4) |
|
||||
((r->conv_opd0_x_ins0_last & ((1u << 4) - 1)) << 8) |
|
||||
((r->conv_opd0_y_ins0_last & ((1u << 4) - 1)) << 12) |
|
||||
((r->conv_opd1_x_ins0 & ((1u << 4) - 1)) << 16) |
|
||||
((r->conv_opd1_y_ins0 & ((1u << 4) - 1)) << 20) |
|
||||
((r->dummy0 & ((1u << 8) - 1)) << 24);
|
||||
p[3] = (r->opt_res0_sign & 1) |
|
||||
((r->opt_opd0_sign & 1) << 1) |
|
||||
((r->opt_opd1_sign & 1) << 2) |
|
||||
((r->opt_opd2_sign & 1) << 3) |
|
||||
((r->opt_res0_seg & ((1u << 2) - 1)) << 4) |
|
||||
((r->opt_opd0_seg & ((1u << 2) - 1)) << 6) |
|
||||
((r->opt_opd1_seg & ((1u << 2) - 1)) << 8) |
|
||||
((r->opt_opd2_seg & 1) << 10) |
|
||||
((r->ps32_md & ((1u << 2) - 1)) << 11) |
|
||||
((r->double_conv & 1) << 13) |
|
||||
((r->opt_left_tran & 1) << 14) |
|
||||
((r->fp_round_typ & 1) << 15) |
|
||||
((r->opt_relu_typ & ((1u << 2) - 1)) << 16) |
|
||||
((r->opt_relu_value & ((1u << 8) - 1)) << 18) |
|
||||
((r->cmd_pre_exe_typ & 1) << 26) |
|
||||
((r->opt_res_add & 1) << 27) |
|
||||
((r->rsvd0 & ((1u << 4) - 1)) << 28);
|
||||
p[2] = (r->quan_m & (((uint64_t)1 << 32) - 1));
|
||||
p[1] = (r->cmd_id_tpu & ((1u << 16) - 1)) |
|
||||
((r->cmd_id_gdma & ((1u << 16) - 1)) << 16);
|
||||
p[0] = (r->cmd_en & 1) |
|
||||
((r->cmd_end & 1) << 1) |
|
||||
((r->cmd_id_en & 1) << 2) |
|
||||
((r->cmd_keep & 1) << 3) |
|
||||
((r->cmd_intr_en & 1) << 4) |
|
||||
((r->tsk_typ & ((1u << 4) - 1)) << 5) |
|
||||
((r->tsk_eu_typ & ((1u << 5) - 1)) << 9) |
|
||||
((r->tsk_opd_num & ((1u << 2) - 1)) << 14) |
|
||||
((r->opt_res_shift & ((1u << 6) - 1)) << 16) |
|
||||
((r->opt_left_shift & ((1u << 5) - 1)) << 22) |
|
||||
((r->opt_shift_typ & 1) << 27) |
|
||||
((r->opt_rshift_typ & 1) << 28) |
|
||||
((r->dummy1 & 1) << 29) |
|
||||
((r->opd_typ & 1) << 30) |
|
||||
((r->opt_chl_quan & 1) << 31);
|
||||
}
|
||||
|
||||
static inline void reset_tiu_reg(tiu_reg_t *r)
|
||||
{
|
||||
r->cmd_en = 0x0;
|
||||
r->cmd_end = 0x0;
|
||||
r->cmd_id_en = 0x0;
|
||||
r->cmd_keep = 0x0;
|
||||
r->cmd_intr_en = 0x0;
|
||||
r->tsk_typ = 0x0;
|
||||
r->tsk_eu_typ = 0x0;
|
||||
r->tsk_opd_num = 0x3;
|
||||
r->opt_res_shift = 0xa;
|
||||
r->opt_left_shift = 0x2;
|
||||
r->opt_shift_typ = 0x1;
|
||||
r->opt_rshift_typ = 0x1;
|
||||
r->dummy1 = 0x0;
|
||||
r->opd_typ = 0x0;
|
||||
r->opt_chl_quan = 0x0;
|
||||
r->cmd_id_tpu = 0x0;
|
||||
r->cmd_id_gdma = 0x0;
|
||||
r->quan_m = 0x0;
|
||||
r->opt_res0_sign = 0x0;
|
||||
r->opt_opd0_sign = 0x0;
|
||||
r->opt_opd1_sign = 0x1;
|
||||
r->opt_opd2_sign = 0x1;
|
||||
r->opt_res0_seg = 0x1;
|
||||
r->opt_opd0_seg = 0x1;
|
||||
r->opt_opd1_seg = 0x1;
|
||||
r->opt_opd2_seg = 0x0;
|
||||
r->ps32_md = 0x0;
|
||||
r->double_conv = 0x0;
|
||||
r->opt_left_tran = 0x0;
|
||||
r->fp_round_typ = 0x0;
|
||||
r->opt_relu_typ = 0x0;
|
||||
r->opt_relu_value = 0x0;
|
||||
r->cmd_pre_exe_typ = 0x0;
|
||||
r->opt_res_add = 0x0;
|
||||
r->rsvd0 = 0x0;
|
||||
r->conv_opd0_x_ins0 = 0x0;
|
||||
r->conv_opd0_y_ins0 = 0x0;
|
||||
r->conv_opd0_x_ins0_last = 0x0;
|
||||
r->conv_opd0_y_ins0_last = 0x0;
|
||||
r->conv_opd1_x_ins0 = 0x0;
|
||||
r->conv_opd1_y_ins0 = 0x0;
|
||||
r->dummy0 = 0x0;
|
||||
r->opd0_ins_val = 0x0;
|
||||
r->conv_opd0_up_pad = 0x0;
|
||||
r->conv_opd0_dn_pad = 0x0;
|
||||
r->conv_opd0_lf_pad = 0x0;
|
||||
r->conv_opd0_rt_pad = 0x0;
|
||||
r->res0_n = 0x1;
|
||||
r->res0_c = 0x1;
|
||||
r->res0_h = 0x1;
|
||||
r->res0_w = 0x10;
|
||||
r->conv_op_x_str = 0x1;
|
||||
r->conv_op_y_str = 0x1;
|
||||
r->cmd_pre_exe = 0x0;
|
||||
r->rsvd1 = 0x1;
|
||||
r->res0_addr = 0x0;
|
||||
r->opd0_addr = 0x0;
|
||||
r->opd1_addr = 0x0;
|
||||
r->opd2_addr = 0x0;
|
||||
r->opt_opd0_const = 0x0;
|
||||
r->opt_opd1_const = 0x0;
|
||||
r->opt_opd2_const = 0x0;
|
||||
r->short_nchwstr_same = 0x0;
|
||||
r->short_res0_str = 0x0;
|
||||
r->short_opd0_str = 0x0;
|
||||
r->short_opd1_str = 0x0;
|
||||
r->short_opd2_str = 0x0;
|
||||
r->dummy2 = 0x0;
|
||||
r->opd0_n = 0x1;
|
||||
r->opd0_c = 0x1;
|
||||
r->dummy3 = 0x0;
|
||||
r->rsvd2 = 0x2;
|
||||
r->opd0_h = 0x1;
|
||||
r->opd0_w = 0x10;
|
||||
r->opd1_n = 0x1;
|
||||
r->opd1_c = 0x1;
|
||||
r->opd1_h = 0x1;
|
||||
r->opd1_w = 0x10;
|
||||
r->opd2_n = 0x1;
|
||||
r->opd2_c = 0x1;
|
||||
r->opd2_h = 0x1;
|
||||
r->opd2_w = 0x10;
|
||||
r->dummy4 = 0x0;
|
||||
r->rsvd3 = 0x3;
|
||||
r->layer_info = 0x0;
|
||||
r->res0_n_str = 0x10;
|
||||
r->res0_c_str = 0x10;
|
||||
r->res0_h_str = 0x0;
|
||||
r->res0_w_str = 0x1;
|
||||
r->res0_b_str = 0x10;
|
||||
r->opd0_n_str = 0x10;
|
||||
r->dummy5 = 0x0;
|
||||
r->rsvd4 = 0x4;
|
||||
r->opd0_c_str = 0x10;
|
||||
r->opd0_h_str = 0x0;
|
||||
r->opd0_w_str = 0x1;
|
||||
r->opd0_b_str = 0x10;
|
||||
r->opd1_n_str = 0x10;
|
||||
r->opd1_c_str = 0x10;
|
||||
r->opd1_h_str = 0x0;
|
||||
r->dummy6 = 0x0;
|
||||
r->rsvd5 = 0x5;
|
||||
r->opd1_w_str = 0x1;
|
||||
r->opd1_b_str = 0x10;
|
||||
r->opd2_n_str = 0x10;
|
||||
r->opd2_c_str = 0x10;
|
||||
r->opd2_h_str = 0x0;
|
||||
r->opd2_w_str = 0x1;
|
||||
r->opd2_b_str = 0x10;
|
||||
r->dummy7 = 0x0;
|
||||
r->rsvd6 = 0x6;
|
||||
}
|
||||
|
||||
static inline void trace_tiu_reg(tiu_reg_t *r, const char *tag)
|
||||
{
|
||||
#define trace_one_reg(name) \
|
||||
printf(" %s: 0x%llx\n", #name, (ullong)r->name)
|
||||
|
||||
printf("--- %s ---\n", tag);
|
||||
trace_one_reg(cmd_en);
|
||||
trace_one_reg(cmd_end);
|
||||
trace_one_reg(cmd_id_en);
|
||||
trace_one_reg(cmd_keep);
|
||||
trace_one_reg(cmd_intr_en);
|
||||
trace_one_reg(tsk_typ);
|
||||
trace_one_reg(tsk_eu_typ);
|
||||
trace_one_reg(tsk_opd_num);
|
||||
trace_one_reg(opt_res_shift);
|
||||
trace_one_reg(opt_left_shift);
|
||||
trace_one_reg(opt_shift_typ);
|
||||
trace_one_reg(opt_rshift_typ);
|
||||
trace_one_reg(dummy1);
|
||||
trace_one_reg(opd_typ);
|
||||
trace_one_reg(opt_chl_quan);
|
||||
trace_one_reg(cmd_id_tpu);
|
||||
trace_one_reg(cmd_id_gdma);
|
||||
trace_one_reg(quan_m);
|
||||
trace_one_reg(opt_res0_sign);
|
||||
trace_one_reg(opt_opd0_sign);
|
||||
trace_one_reg(opt_opd1_sign);
|
||||
trace_one_reg(opt_opd2_sign);
|
||||
trace_one_reg(opt_res0_seg);
|
||||
trace_one_reg(opt_opd0_seg);
|
||||
trace_one_reg(opt_opd1_seg);
|
||||
trace_one_reg(opt_opd2_seg);
|
||||
trace_one_reg(ps32_md);
|
||||
trace_one_reg(double_conv);
|
||||
trace_one_reg(opt_left_tran);
|
||||
trace_one_reg(fp_round_typ);
|
||||
trace_one_reg(opt_relu_typ);
|
||||
trace_one_reg(opt_relu_value);
|
||||
trace_one_reg(cmd_pre_exe_typ);
|
||||
trace_one_reg(opt_res_add);
|
||||
trace_one_reg(rsvd0);
|
||||
trace_one_reg(conv_opd0_x_ins0);
|
||||
trace_one_reg(conv_opd0_y_ins0);
|
||||
trace_one_reg(conv_opd0_x_ins0_last);
|
||||
trace_one_reg(conv_opd0_y_ins0_last);
|
||||
trace_one_reg(conv_opd1_x_ins0);
|
||||
trace_one_reg(conv_opd1_y_ins0);
|
||||
trace_one_reg(dummy0);
|
||||
trace_one_reg(opd0_ins_val);
|
||||
trace_one_reg(conv_opd0_up_pad);
|
||||
trace_one_reg(conv_opd0_dn_pad);
|
||||
trace_one_reg(conv_opd0_lf_pad);
|
||||
trace_one_reg(conv_opd0_rt_pad);
|
||||
trace_one_reg(res0_n);
|
||||
trace_one_reg(res0_c);
|
||||
trace_one_reg(res0_h);
|
||||
trace_one_reg(res0_w);
|
||||
trace_one_reg(conv_op_x_str);
|
||||
trace_one_reg(conv_op_y_str);
|
||||
trace_one_reg(cmd_pre_exe);
|
||||
trace_one_reg(rsvd1);
|
||||
trace_one_reg(res0_addr);
|
||||
trace_one_reg(opd0_addr);
|
||||
trace_one_reg(opd1_addr);
|
||||
trace_one_reg(opd2_addr);
|
||||
trace_one_reg(opt_opd0_const);
|
||||
trace_one_reg(opt_opd1_const);
|
||||
trace_one_reg(opt_opd2_const);
|
||||
trace_one_reg(short_nchwstr_same);
|
||||
trace_one_reg(short_res0_str);
|
||||
trace_one_reg(short_opd0_str);
|
||||
trace_one_reg(short_opd1_str);
|
||||
trace_one_reg(short_opd2_str);
|
||||
trace_one_reg(dummy2);
|
||||
trace_one_reg(opd0_n);
|
||||
trace_one_reg(opd0_c);
|
||||
trace_one_reg(dummy3);
|
||||
trace_one_reg(rsvd2);
|
||||
trace_one_reg(opd0_h);
|
||||
trace_one_reg(opd0_w);
|
||||
trace_one_reg(opd1_n);
|
||||
trace_one_reg(opd1_c);
|
||||
trace_one_reg(opd1_h);
|
||||
trace_one_reg(opd1_w);
|
||||
trace_one_reg(opd2_n);
|
||||
trace_one_reg(opd2_c);
|
||||
trace_one_reg(opd2_h);
|
||||
trace_one_reg(opd2_w);
|
||||
trace_one_reg(dummy4);
|
||||
trace_one_reg(rsvd3);
|
||||
trace_one_reg(layer_info);
|
||||
trace_one_reg(res0_n_str);
|
||||
trace_one_reg(res0_c_str);
|
||||
trace_one_reg(res0_h_str);
|
||||
trace_one_reg(res0_w_str);
|
||||
trace_one_reg(res0_b_str);
|
||||
trace_one_reg(opd0_n_str);
|
||||
trace_one_reg(dummy5);
|
||||
trace_one_reg(rsvd4);
|
||||
trace_one_reg(opd0_c_str);
|
||||
trace_one_reg(opd0_h_str);
|
||||
trace_one_reg(opd0_w_str);
|
||||
trace_one_reg(opd0_b_str);
|
||||
trace_one_reg(opd1_n_str);
|
||||
trace_one_reg(opd1_c_str);
|
||||
trace_one_reg(opd1_h_str);
|
||||
trace_one_reg(dummy6);
|
||||
trace_one_reg(rsvd5);
|
||||
trace_one_reg(opd1_w_str);
|
||||
trace_one_reg(opd1_b_str);
|
||||
trace_one_reg(opd2_n_str);
|
||||
trace_one_reg(opd2_c_str);
|
||||
trace_one_reg(opd2_h_str);
|
||||
trace_one_reg(opd2_w_str);
|
||||
trace_one_reg(opd2_b_str);
|
||||
trace_one_reg(dummy7);
|
||||
trace_one_reg(rsvd6);
|
||||
}
|
||||
#endif /* BM1822_TIU_REG_H */
|
||||
38
cvikernel/include/bmkernel/bm1822/bm1822_tpu_cfg.h
Normal file
38
cvikernel/include/bmkernel/bm1822/bm1822_tpu_cfg.h
Normal file
@ -0,0 +1,38 @@
|
||||
#ifndef __BM1822_TPU_CFG__
|
||||
#define __BM1822_TPU_CFG__
|
||||
|
||||
#define BM1822_VER 1822
|
||||
#define BM1822_HW_NPU_SHIFT 3
|
||||
#define BM1822_HW_EU_SHIFT 4
|
||||
#define BM1822_HW_LMEM_SHIFT 15
|
||||
#define BM1822_HW_LMEM_BANKS 8
|
||||
#define BM1822_HW_LMEM_BANK_SIZE 0x1000
|
||||
#define BM1822_HW_NODE_CHIP_SHIFT 0
|
||||
#define BM1822_HW_NPU_NUM (1 << BM1822_HW_NPU_SHIFT)
|
||||
#define BM1822_HW_EU_NUM (1 << BM1822_HW_EU_SHIFT)
|
||||
#define BM1822_HW_LMEM_SIZE (1 << BM1822_HW_LMEM_SHIFT)
|
||||
#define BM1822_HW_LMEM_START_ADDR 0x0C000000
|
||||
#define BM1822_HW_NODE_CHIP_NUM (1 << BM1822_HW_NODE_CHIP_SHIFT)
|
||||
|
||||
#if (BM1822_HW_LMEM_SIZE != (BM1822_HW_LMEM_BANK_SIZE * BM1822_HW_LMEM_BANKS))
|
||||
#error "Set wrong TPU configuraiton."
|
||||
#endif
|
||||
|
||||
#define BM1822_GLOBAL_MEM_START_ADDR 0x0
|
||||
#define BM1822_GLOBAL_MEM_SIZE 0x100000000
|
||||
|
||||
#define BM1822_GLOBAL_TIU_CMDBUF_ADDR 0x00000000
|
||||
#define BM1822_GLOBAL_TDMA_CMDBUF_ADDR 0x10000000
|
||||
#define BM1822_GLOBAL_TIU_CMDBUF_RESERVED_SIZE 0x10000000
|
||||
#define BM1822_GLOBAL_TDMA_CMDBUF_RESERVED_SIZE 0x10000000
|
||||
#define BM1822_GLOBAL_POOL_RESERVED_SIZE (BM1822_GLOBAL_MEM_SIZE - BM1822_GLOBAL_TIU_CMDBUF_RESERVED_SIZE - BM1822_GLOBAL_TDMA_CMDBUF_RESERVED_SIZE)
|
||||
|
||||
#define BM1822_UART_CTLR_BASE_ADDR 0x04140000
|
||||
|
||||
#define BM1822_TDMA_ENGINE_BASE_ADDR 0x0C100000
|
||||
#define BM1822_TDMA_ENGINE_END_ADDR (BM1822_TDMA_ENGINE_BASE_ADDR + 0x1000)
|
||||
|
||||
#define BM1822_TIU_ENGINE_BASE_ADDR 0x0C101000 //"NPS Register" in memory map?
|
||||
#define BM1822_TIU_ENGINE_END_ADDR (BM1822_TIU_ENGINE_BASE_ADDR + 0x1000)
|
||||
|
||||
#endif
|
||||
703
cvikernel/include/bmkernel/bm1822/bm_vlc_compress.h
Normal file
703
cvikernel/include/bmkernel/bm1822/bm_vlc_compress.h
Normal file
@ -0,0 +1,703 @@
|
||||
#ifndef __BM_VLC_COMPRESS_H__
|
||||
#define __BM_VLC_COMPRESS_H__
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define MAX_UNARY_FIELD_SIZE 47
|
||||
#define MAX_ORDER_K 5
|
||||
|
||||
/**
|
||||
* \data_type 0 means 8bit, 1 means 16bit
|
||||
*/
|
||||
static inline size_t get_out_bs_buf_size(uint64_t in_size, uint8_t data_type) {
|
||||
size_t blk_num = (data_type) ? ((in_size + 31) >> 5) : ((in_size + 15) >> 4);
|
||||
size_t in_size_pad = blk_num << (4 + data_type);
|
||||
size_t bs_buf_size = in_size_pad + (ceiling_func(blk_num, 16) << 4) + 16;
|
||||
return bs_buf_size;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t signedness;
|
||||
uint8_t is_bfloat16;
|
||||
uint8_t bias0;
|
||||
uint8_t bias1;
|
||||
uint8_t zero_guard_en;
|
||||
} CommandInfo;
|
||||
typedef struct
|
||||
{
|
||||
uint8_t *stream; // stream buffer pointer
|
||||
int bit_pos; // current pointer (in bit)
|
||||
int buf_size; // in byte
|
||||
} StreamBuffer;
|
||||
|
||||
static inline int8_t two_side_circular_shift(int8_t val, uint8_t bias0, uint8_t bias1);
|
||||
static inline int8_t inv_two_side_circular_shift(int8_t val, uint8_t bias0, uint8_t bias1);
|
||||
static inline uint8_t center_shift(uint8_t val, uint8_t bias, uint8_t zero_guard);
|
||||
static inline uint8_t inv_center_shift(uint8_t val, uint8_t bias, uint8_t zero_guard);
|
||||
|
||||
static inline void init_stream(StreamBuffer *bs, const uint8_t *buf, int buf_size, uint8_t read_only);
|
||||
|
||||
static inline void bm_vlc_est_weight_bias(const uint8_t *ibuf, size_t isz, uint8_t signedness, uint8_t isBfloat16, CommandInfo *cmd_info);
|
||||
static inline void bm_vlc_enc_int8(const uint8_t *ibuf, size_t isz, uint8_t *obuf, size_t *osz, CommandInfo *cmd_info);
|
||||
static inline void bm_vlc_dec_int8_ext(const uint8_t *ibuf, size_t isz, uint8_t *obuf, size_t *bs_size);
|
||||
static inline void bm_vlc_dec_int8(const uint8_t *ibuf, size_t isz, uint8_t *obuf);
|
||||
static inline void bm_vlc_enc_bf16(const uint16_t *ibuf, size_t isz, uint8_t *obuf, size_t *osz, CommandInfo *cmd_info);
|
||||
static inline void bm_vlc_dec_bf16_ext(const uint8_t *ibuf, size_t isz, uint16_t *obuf, size_t *bs_size);
|
||||
static inline void bm_vlc_dec_bf16(const uint8_t *ibuf, size_t isz, uint16_t *obuf);
|
||||
|
||||
static inline uint8_t get_bit_val(uint8_t *buf, int byte_idx, int bit_idx)
|
||||
{
|
||||
return (buf[byte_idx] >> bit_idx) & 0x1;
|
||||
}
|
||||
|
||||
static inline uint8_t sign_to_unsign(uint8_t val)
|
||||
{
|
||||
uint8_t sign_i = (val >> 7) & 0x1;
|
||||
int abs_data_i = abs(((int8_t)val));
|
||||
return ((abs_data_i << 1) - sign_i);
|
||||
}
|
||||
|
||||
static inline int8_t unsign_to_sign(uint8_t val)
|
||||
{
|
||||
uint8_t sign_i = val & 0x1;
|
||||
int abs_data_i = (((int)val) + 1) >> 1;
|
||||
return (uint8_t)((sign_i == 1) ? (-abs_data_i) : abs_data_i);
|
||||
}
|
||||
|
||||
static inline void dispatch_bf16_data(const uint16_t *bf16_in, uint8_t *exp, uint8_t *frac, size_t isz)
|
||||
{
|
||||
for (size_t i = 0; i < isz; i++)
|
||||
{
|
||||
exp[i] = (uint8_t)((bf16_in[i] >> 7) & 0xFF);
|
||||
frac[i] = (uint8_t)(((bf16_in[i] >> 15) << 7) | (bf16_in[i] & 0x7F));
|
||||
}
|
||||
}
|
||||
|
||||
static inline void merge_bf16_data(const uint8_t *exp_in, const uint8_t *frac_in, uint16_t *bf16_out, size_t isz)
|
||||
{
|
||||
memset(bf16_out, 0, sizeof(uint16_t));
|
||||
for (size_t i = 0; i < isz; i++)
|
||||
{
|
||||
bf16_out[i] = ((frac_in[i] >> 7) << 15) | (exp_in[i] << 7) | (frac_in[i] & 0x7F);
|
||||
}
|
||||
}
|
||||
|
||||
// -- streaming operation handler --
|
||||
static inline void init_stream(StreamBuffer *bs, const uint8_t *buf, int buf_size, uint8_t read_only)
|
||||
{
|
||||
bs->bit_pos = 0;
|
||||
bs->stream = (uint8_t *)buf;
|
||||
bs->buf_size = buf_size;
|
||||
if (!read_only)
|
||||
memset((uint8_t *)buf, 0, sizeof(uint8_t) * buf_size);
|
||||
}
|
||||
|
||||
static inline void write_stream(StreamBuffer *bs, uint8_t *src, int bit_len)
|
||||
{
|
||||
for (int bit = 0; bit < bit_len; bit++)
|
||||
{
|
||||
int src_byte_i = bit / 8;
|
||||
int src_bit_i = bit % 8;
|
||||
int dest_byte_i = (bs->bit_pos + bit) / 8;
|
||||
int dest_bit_i = (bs->bit_pos + bit) % 8;
|
||||
bs->stream[dest_byte_i] |= (get_bit_val(src, src_byte_i, src_bit_i) << dest_bit_i);
|
||||
}
|
||||
bs->bit_pos += bit_len;
|
||||
}
|
||||
|
||||
static inline void move_stream_ptr(StreamBuffer *bs, int bit_len)
|
||||
{
|
||||
bs->bit_pos += bit_len;
|
||||
}
|
||||
|
||||
static inline void parse_stream(StreamBuffer *bs, uint8_t *dest, int bit_len)
|
||||
{
|
||||
memset(dest, 0, sizeof(uint8_t) * (bit_len + 7) >> 3);
|
||||
for (int bit = 0; bit < bit_len; bit++)
|
||||
{
|
||||
int dest_byte_i = bit / 8;
|
||||
int dest_bit_i = bit % 8;
|
||||
int bs_byte_i = (bs->bit_pos + bit) / 8;
|
||||
int bs_bit_i = (bs->bit_pos + bit) % 8;
|
||||
dest[dest_byte_i] |= (get_bit_val(bs->stream, bs_byte_i, bs_bit_i) << dest_bit_i);
|
||||
}
|
||||
bs->bit_pos += bit_len;
|
||||
}
|
||||
|
||||
// -- header read/write operation handler --
|
||||
static inline void vlc_enc_header(StreamBuffer *bs_header, CommandInfo *cmd_info, size_t blk_bs_size)
|
||||
{
|
||||
write_stream(bs_header, (uint8_t *)&blk_bs_size, 24); // bit[23:0] compressed block stream size
|
||||
move_stream_ptr(bs_header, 4); // bit[27:24] reserved
|
||||
write_stream(bs_header, (uint8_t *)&cmd_info->signedness, 1); // bit[28] signedness
|
||||
write_stream(bs_header, (uint8_t *)&cmd_info->is_bfloat16, 1); // bit[29] data type
|
||||
move_stream_ptr(bs_header, 2); // bit[31:30] bit depth
|
||||
write_stream(bs_header, (uint8_t *)&cmd_info->bias0, 8); // bit[39:32] bias0 for symbol remapping
|
||||
write_stream(bs_header, (uint8_t *)&cmd_info->bias1, 7); // bit[46:40] bias1 for symbol remapping
|
||||
write_stream(bs_header, (uint8_t *)&cmd_info->zero_guard_en, 1); // bit[47] zero guard
|
||||
}
|
||||
|
||||
static inline void vlc_dec_header_ext(StreamBuffer *bs_header, CommandInfo *cmd_info, size_t *blk_bs_size)
|
||||
{
|
||||
parse_stream(bs_header, (uint8_t *)blk_bs_size, 24); // bit[23:0] compressed block stream size
|
||||
move_stream_ptr(bs_header, 4); // bit[27:24] reserved
|
||||
parse_stream(bs_header, (uint8_t *)&cmd_info->signedness, 1); // bit[28] signedness
|
||||
parse_stream(bs_header, (uint8_t *)&cmd_info->is_bfloat16, 1); // bit[29] data type
|
||||
move_stream_ptr(bs_header, 2);
|
||||
parse_stream(bs_header, (uint8_t *)&cmd_info->bias0, 8); // bit[39:32] bias0 for symbol remapping
|
||||
parse_stream(bs_header, (uint8_t *)&cmd_info->bias1, 7); // bit[46:40] bias1 for symbol remapping
|
||||
parse_stream(bs_header, (uint8_t *)&cmd_info->zero_guard_en, 1); // bit[47] zero guard
|
||||
}
|
||||
|
||||
static inline void vlc_dec_header(StreamBuffer *bs_header, CommandInfo *cmd_info)
|
||||
{
|
||||
size_t blk_bs_size;
|
||||
vlc_dec_header_ext(bs_header, cmd_info, &blk_bs_size);
|
||||
}
|
||||
|
||||
// -- symbol remmaping handler --
|
||||
static inline uint8_t center_shift(uint8_t val, uint8_t bias, uint8_t zero_guard)
|
||||
{
|
||||
if (val == 0 && zero_guard)
|
||||
return 0;
|
||||
|
||||
int16_t shift_data_i = val - bias;
|
||||
uint8_t range = (bias <= 128) ? bias : 255 - bias;
|
||||
if (bias <= 128)
|
||||
{
|
||||
return (val >= (range << 1)) ? val : sign_to_unsign(shift_data_i) + zero_guard;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (val < (bias - range)) ? (range + bias - val + zero_guard) : (sign_to_unsign(shift_data_i) + zero_guard);
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint8_t inv_center_shift(uint8_t val, uint8_t bias, uint8_t zero_guard)
|
||||
{
|
||||
if (val == 0 && zero_guard)
|
||||
return 0;
|
||||
|
||||
uint8_t unsign_data_i = val - zero_guard;
|
||||
uint8_t range = (bias <= 128) ? bias : 255 - bias;
|
||||
if (bias <= 128)
|
||||
{
|
||||
return (val >= (range << 1)) ? val : unsign_to_sign(unsign_data_i) + bias;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (unsign_data_i > (range << 1)) ? (range + bias - val + zero_guard) : unsign_to_sign(unsign_data_i) + bias;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int8_t two_side_circular_shift(int8_t val, uint8_t bias0, uint8_t bias1)
|
||||
{
|
||||
if (val == 0)
|
||||
return 0;
|
||||
|
||||
uint8_t sign = (val < 0) ? true : false;
|
||||
int32_t abs_val = abs(val);
|
||||
abs_val -= (sign) ? bias1 : bias0;
|
||||
abs_val += (abs_val <= 0) ? (127 + sign) : 0;
|
||||
return (sign) ? -abs_val : abs_val;
|
||||
}
|
||||
|
||||
static inline int8_t inv_two_side_circular_shift(int8_t val, uint8_t bias0, uint8_t bias1)
|
||||
{
|
||||
if (val == 0)
|
||||
return 0;
|
||||
|
||||
uint8_t sign = (val < 0) ? true : false;
|
||||
uint32_t abs_val = abs(val);
|
||||
abs_val += (sign) ? bias1 : bias0;
|
||||
int32_t abs_val_minus = abs_val - (127 + sign);
|
||||
uint8_t abs_val_lsb = ((abs_val_minus <= 0)
|
||||
? abs_val
|
||||
: abs_val_minus) &
|
||||
0xFF;
|
||||
return (sign) ? -abs_val_lsb : abs_val_lsb;
|
||||
}
|
||||
|
||||
static inline void symbol_remapping(uint8_t *blk_in, uint8_t *blk_out, uint8_t bias0, uint8_t bias1, uint8_t signedness, uint8_t is_bf16_exp, uint8_t zero_guard)
|
||||
{
|
||||
if (is_bf16_exp == false && signedness == false)
|
||||
{
|
||||
// remapping bypass
|
||||
memcpy(blk_out, blk_in, sizeof(uint8_t) * 16);
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_bf16_exp == true)
|
||||
{
|
||||
// center circular shift
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
blk_out[i] = center_shift(blk_in[i], bias0, zero_guard);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// two-side circular shift
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
int8_t shift_data_i = two_side_circular_shift((int8_t)blk_in[i], bias0, bias1);
|
||||
blk_out[i] = sign_to_unsign(shift_data_i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void inv_symbol_remapping(uint8_t *blk_in, uint8_t *blk_out, uint8_t bias0, uint8_t bias1, uint8_t signedness, uint8_t is_bf16_exp, uint8_t zero_guard)
|
||||
{
|
||||
if (is_bf16_exp == false && signedness == false)
|
||||
{
|
||||
// remapping bypass
|
||||
memcpy(blk_out, blk_in, sizeof(uint8_t) * 16);
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_bf16_exp == true)
|
||||
{
|
||||
// center circular shift
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
blk_out[i] = inv_center_shift(blk_in[i], bias0, zero_guard);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// two-side circular shift
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
int8_t sign_data_i = unsign_to_sign(blk_in[i]);
|
||||
blk_out[i] = (uint8_t)inv_two_side_circular_shift(sign_data_i, bias0, bias1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline int vlc_estimate_block_order(uint8_t *blk_in, uint8_t bf16_zvc_en)
|
||||
{
|
||||
int best_k = 0;
|
||||
int best_bs_size = 0x7FFFFFFF;
|
||||
|
||||
for (int k = 0; k <= (int)MAX_ORDER_K; k++)
|
||||
{
|
||||
uint8_t remain_field_size = k << 4;
|
||||
int unary_field_len = 0;
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
uint8_t group_idx = blk_in[i] >> k;
|
||||
unary_field_len += (group_idx + 1);
|
||||
}
|
||||
int znum_bit = (bf16_zvc_en && k > 0) ? 4 : 0;
|
||||
int blk_size = (unary_field_len <= MAX_UNARY_FIELD_SIZE)
|
||||
? remain_field_size + unary_field_len + znum_bit
|
||||
: 255;
|
||||
if (blk_size < best_bs_size)
|
||||
{
|
||||
best_k = k;
|
||||
best_bs_size = blk_size;
|
||||
}
|
||||
}
|
||||
|
||||
best_k = (best_bs_size > 128) ? -1 : best_k;
|
||||
return best_k;
|
||||
}
|
||||
// -- vlc block parrelel GR encode/decode --
|
||||
static inline uint8_t vlc_gr_enc_block_data(uint8_t *blk_in, StreamBuffer *bs, int order_k, uint8_t bf16_zvc_en)
|
||||
{
|
||||
// uncompressed mode
|
||||
if (order_k == -1)
|
||||
{
|
||||
write_stream(bs, blk_in, 128);
|
||||
return 128;
|
||||
}
|
||||
|
||||
// remain field
|
||||
uint8_t remain_field[16] = {0};
|
||||
uint8_t unary_field[8] = {0};
|
||||
uint8_t sym_end_pos[16] = {0};
|
||||
uint8_t unary_field_len = 0;
|
||||
int sym_end_pos_accum = -1;
|
||||
|
||||
// bit plane encode for remain field
|
||||
for (int k = 0; k < order_k; k++)
|
||||
{
|
||||
uint8_t bit_plane0 = 0, bit_plane1 = 0;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
bit_plane0 |= (get_bit_val(blk_in, i, k) << i);
|
||||
bit_plane1 |= (get_bit_val(blk_in, i + 8, k) << i);
|
||||
}
|
||||
remain_field[k << 1] = bit_plane0;
|
||||
remain_field[(k << 1) + 1] = bit_plane1;
|
||||
}
|
||||
write_stream(bs, remain_field, order_k << 4);
|
||||
|
||||
if (bf16_zvc_en && order_k > 0)
|
||||
{
|
||||
int zero_num = 0;
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
if (blk_in[i] == 0)
|
||||
zero_num++;
|
||||
}
|
||||
assert(zero_num < 16);
|
||||
write_stream(bs, (uint8_t *)&zero_num, 4);
|
||||
}
|
||||
|
||||
// unary encode for unary field
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
int group_idx = blk_in[i] >> order_k;
|
||||
sym_end_pos_accum += (group_idx + 1);
|
||||
sym_end_pos[i] = sym_end_pos_accum;
|
||||
int byte_idx = sym_end_pos[i] / 8;
|
||||
int bit_idx = sym_end_pos[i] % 8;
|
||||
unary_field[byte_idx] |= (1 << (bit_idx));
|
||||
}
|
||||
unary_field_len = sym_end_pos[15] + 1;
|
||||
assert(unary_field_len <= MAX_UNARY_FIELD_SIZE);
|
||||
uint8_t ulen = (unary_field_len - 16) & 0x1F;
|
||||
write_stream(bs, unary_field, unary_field_len);
|
||||
|
||||
return ulen;
|
||||
}
|
||||
|
||||
static inline void vlc_gr_dec_block_data(StreamBuffer *bs, uint8_t bs_size, uint8_t *rec, int order_k, uint8_t bf16_zvc_en)
|
||||
{
|
||||
assert(bs_size <= 128);
|
||||
// uncompressed mode
|
||||
if (order_k == -1)
|
||||
{
|
||||
parse_stream(bs, rec, 128);
|
||||
return;
|
||||
}
|
||||
|
||||
// remain field
|
||||
uint8_t remain_data[16] = {0};
|
||||
uint8_t remain_bs[16] = {0};
|
||||
uint8_t unary_field[8] = {0};
|
||||
uint8_t sym_end_pos[16] = {0};
|
||||
uint8_t unary_sym[16] = {0};
|
||||
uint8_t remain_field_size = order_k << 4;
|
||||
|
||||
parse_stream(bs, remain_bs, remain_field_size);
|
||||
// bit plane encode for remain field
|
||||
for (int k = 0; k < order_k; k++)
|
||||
{
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
remain_data[i] |= (get_bit_val(remain_bs, k << 1, i) << k);
|
||||
remain_data[i + 8] |= (get_bit_val(remain_bs, (k << 1) + 1, i) << k);
|
||||
}
|
||||
}
|
||||
|
||||
// zero number info
|
||||
int znum_bit = (bf16_zvc_en && order_k > 0) ? 4 : 0;
|
||||
uint8_t znum = 0;
|
||||
parse_stream(bs, &znum, znum_bit);
|
||||
|
||||
// unary encode for unary field
|
||||
uint8_t unary_field_len = bs_size - remain_field_size - znum_bit;
|
||||
parse_stream(bs, unary_field, unary_field_len);
|
||||
|
||||
int sym_cnt = 0;
|
||||
for (uint8_t ubit_i = 0; ubit_i < unary_field_len; ubit_i++)
|
||||
{
|
||||
int byte_idx = ubit_i / 8;
|
||||
int bit_idx = ubit_i % 8;
|
||||
if (get_bit_val(unary_field, byte_idx, bit_idx) == 1)
|
||||
{
|
||||
sym_end_pos[sym_cnt] = ubit_i;
|
||||
sym_cnt++;
|
||||
}
|
||||
}
|
||||
unary_sym[0] = sym_end_pos[0];
|
||||
for (int i = 1; i < 16; i++)
|
||||
{
|
||||
unary_sym[i] = sym_end_pos[i] - sym_end_pos[i - 1] - 1;
|
||||
}
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
rec[i] = (unary_sym[i] << order_k) + remain_data[i];
|
||||
}
|
||||
}
|
||||
|
||||
// -- vlc encode int8 entry function --
|
||||
static inline void bm_vlc_enc_int8(const uint8_t *ibuf, size_t isz, uint8_t *obuf, size_t *osz, CommandInfo *cmd_info)
|
||||
{
|
||||
StreamBuffer bs_header, bs_kmap, bs_data;
|
||||
size_t blk_num = (isz + 15) >> 4;
|
||||
size_t header_size = 16;
|
||||
size_t kmap_size = ceiling_func(blk_num, 16) << 4;
|
||||
size_t bs_buf_size = header_size + kmap_size + (blk_num << 4);
|
||||
uint8_t *bsbuf = (uint8_t *)calloc(bs_buf_size, sizeof(uint8_t));
|
||||
|
||||
// block encode
|
||||
init_stream(&bs_kmap, bsbuf + header_size, kmap_size, false);
|
||||
init_stream(&bs_data, bsbuf + header_size + kmap_size, blk_num << 4, false);
|
||||
|
||||
for (size_t blk_idx = 0; blk_idx < blk_num; blk_idx++)
|
||||
{
|
||||
uint8_t blk_data[16] = {0}, blk_sr_data[16] = {0};
|
||||
size_t in_size = (blk_idx == (blk_num - 1)) ? isz - (blk_idx << 4) : 16;
|
||||
memcpy(blk_data, &ibuf[blk_idx << 4], sizeof(uint8_t) * in_size);
|
||||
|
||||
symbol_remapping(blk_data, blk_sr_data, cmd_info->bias0, cmd_info->bias1, cmd_info->signedness, false, false);
|
||||
|
||||
int k = vlc_estimate_block_order(blk_sr_data, false);
|
||||
uint8_t ulen = vlc_gr_enc_block_data(blk_sr_data, &bs_data, k, false);
|
||||
uint8_t k_info = (k == -1) ? 0xE0 : (k << 5) + ulen;
|
||||
write_stream(&bs_kmap, &k_info, 8);
|
||||
}
|
||||
|
||||
int blk_bs_size = ceiling_func(((bs_data.bit_pos + 7) >> 3), 16) << 4; // 16 byte align
|
||||
*osz = header_size + kmap_size + blk_bs_size;
|
||||
|
||||
// write header
|
||||
init_stream(&bs_header, bsbuf, header_size, false);
|
||||
vlc_enc_header(&bs_header, cmd_info, blk_bs_size);
|
||||
|
||||
memcpy(obuf, bsbuf, (*osz) * sizeof(uint8_t));
|
||||
free(bsbuf);
|
||||
}
|
||||
|
||||
// -- vlc decode int8 entry function --
|
||||
static inline void bm_vlc_dec_int8_ext(const uint8_t *ibuf, size_t isz, uint8_t *obuf, size_t *bs_size)
|
||||
{
|
||||
StreamBuffer bs_header, bs_kmap, bs_data;
|
||||
CommandInfo cmd_info;
|
||||
memset(&cmd_info, 0, sizeof(CommandInfo));
|
||||
|
||||
size_t blk_num = (isz + 15) >> 4;
|
||||
int header_size = 16;
|
||||
int kmap_size = ceiling_func(blk_num, 16) << 4;
|
||||
|
||||
// parse header
|
||||
init_stream(&bs_header, ibuf, header_size, true);
|
||||
vlc_dec_header_ext(&bs_header, &cmd_info, bs_size);
|
||||
|
||||
// Check whether valid header
|
||||
size_t bs_buf_size = get_out_bs_buf_size(isz, 0); // int8
|
||||
ASSERT(*bs_size <= bs_buf_size);
|
||||
ASSERT(cmd_info.is_bfloat16 == 0);
|
||||
|
||||
// block decode
|
||||
init_stream(&bs_kmap, ibuf + header_size, kmap_size, true);
|
||||
init_stream(&bs_data, ibuf + header_size + kmap_size, blk_num << 4, true);
|
||||
|
||||
for (size_t blk_idx = 0; blk_idx < blk_num; blk_idx++)
|
||||
{
|
||||
uint8_t blk_data[16] = {0}, blk_sr_data[16] = {0};
|
||||
uint8_t k_info = 0;
|
||||
parse_stream(&bs_kmap, &k_info, 8);
|
||||
uint8_t ulen = k_info & 0x1F;
|
||||
int k = (k_info >> 5 == 7) ? -1 : k_info >> 5;
|
||||
int blk_bs_size = (k == -1) ? 128 : (k << 4) + ulen + 16;
|
||||
vlc_gr_dec_block_data(&bs_data, blk_bs_size, blk_data, k, false);
|
||||
|
||||
inv_symbol_remapping(blk_data, blk_sr_data, cmd_info.bias0, cmd_info.bias1, cmd_info.signedness, false, false);
|
||||
|
||||
int out_size = (blk_idx == (blk_num - 1)) ? isz - (blk_idx << 4) : 16;
|
||||
memcpy(&obuf[blk_idx << 4], blk_sr_data, sizeof(uint8_t) * out_size);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void bm_vlc_dec_int8(const uint8_t *ibuf, size_t isz, uint8_t *obuf)
|
||||
{
|
||||
size_t bs_size;
|
||||
bm_vlc_dec_int8_ext(ibuf, isz, obuf, &bs_size);
|
||||
}
|
||||
|
||||
// -- vlc encode bfloat16 entry function --
|
||||
static inline void bm_vlc_enc_bf16(const uint16_t *ibuf, size_t isz, uint8_t *obuf, size_t *osz, CommandInfo *cmd_info)
|
||||
{
|
||||
StreamBuffer bs_header, bs_kmap, bs_data;
|
||||
size_t blk_num = (isz + 31) >> 5; // 32 bytes per blok
|
||||
size_t header_size = 16;
|
||||
size_t kmap_size = ceiling_func(blk_num, 16) << 4;
|
||||
size_t bs_buf_size = header_size + kmap_size + (blk_num << 5);
|
||||
uint8_t *bsbuf = (uint8_t *)calloc(bs_buf_size, sizeof(uint8_t));
|
||||
|
||||
// block encode
|
||||
init_stream(&bs_kmap, bsbuf + header_size, kmap_size, false);
|
||||
init_stream(&bs_data, bsbuf + header_size + kmap_size, blk_num << 5, false);
|
||||
|
||||
for (size_t blk_idx = 0; blk_idx < blk_num; blk_idx++)
|
||||
{
|
||||
uint8_t blk_data[16] = {0}, blk_sr_data[16] = {0}, blk_data_frac[16] = {0};
|
||||
size_t in_num = (blk_idx == (blk_num - 1)) ? ((isz >> 1) - (blk_idx << 4)) : 16;
|
||||
dispatch_bf16_data(&ibuf[blk_idx << 4], blk_data, blk_data_frac, in_num);
|
||||
|
||||
// exp: BGR encode
|
||||
symbol_remapping(blk_data, blk_sr_data, cmd_info->bias0, cmd_info->bias1, false, true, cmd_info->zero_guard_en);
|
||||
|
||||
int k = vlc_estimate_block_order(blk_sr_data, cmd_info->zero_guard_en);
|
||||
uint8_t ulen = vlc_gr_enc_block_data(blk_sr_data, &bs_data, k, cmd_info->zero_guard_en);
|
||||
uint8_t k_info = (k == -1) ? 0xE0 : (k << 5) + ulen;
|
||||
write_stream(&bs_kmap, &k_info, 8);
|
||||
|
||||
// frac: implicit zero compression
|
||||
for (size_t i = 0; i < 16; i++)
|
||||
{
|
||||
if (!cmd_info->zero_guard_en || blk_data[i] != 0)
|
||||
{
|
||||
write_stream(&bs_data, &blk_data_frac[i], 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int blk_bs_size = ceiling_func(((bs_data.bit_pos + 7) >> 3), 16) << 4; // 16 byte align
|
||||
*osz = header_size + kmap_size + blk_bs_size;
|
||||
|
||||
// write header
|
||||
init_stream(&bs_header, bsbuf, header_size, false);
|
||||
vlc_enc_header(&bs_header, cmd_info, blk_bs_size);
|
||||
|
||||
memcpy(obuf, bsbuf, (*osz) * sizeof(uint8_t));
|
||||
free(bsbuf);
|
||||
}
|
||||
|
||||
// -- vlc decode bfloat16 entry function --
|
||||
static inline void bm_vlc_dec_bf16_ext(const uint8_t *ibuf, size_t isz, uint16_t *obuf, size_t *bs_size)
|
||||
{
|
||||
StreamBuffer bs_header, bs_kmap, bs_data;
|
||||
CommandInfo cmd_info;
|
||||
memset(&cmd_info, 0, sizeof(CommandInfo));
|
||||
|
||||
size_t blk_num = (isz + 31) >> 5; // 32 bytes per blok
|
||||
int header_size = 16;
|
||||
int kmap_size = ceiling_func(blk_num, 16) << 4;
|
||||
|
||||
// parse header
|
||||
init_stream(&bs_header, ibuf, header_size, true);
|
||||
vlc_dec_header_ext(&bs_header, &cmd_info, bs_size);
|
||||
|
||||
// Check whether valid header
|
||||
size_t bs_buf_size = get_out_bs_buf_size(isz, 1); // bf16
|
||||
ASSERT(*bs_size <= bs_buf_size);
|
||||
ASSERT(cmd_info.is_bfloat16 == 1);
|
||||
|
||||
// block decode
|
||||
init_stream(&bs_kmap, ibuf + header_size, kmap_size, true);
|
||||
init_stream(&bs_data, ibuf + header_size + kmap_size, blk_num << 5, true);
|
||||
|
||||
for (size_t blk_idx = 0; blk_idx < blk_num; blk_idx++)
|
||||
{
|
||||
uint8_t blk_data[16] = {0}, blk_sr_data[16] = {0}, blk_data_frac[16] = {0};
|
||||
uint8_t k_info = 0;
|
||||
parse_stream(&bs_kmap, &k_info, 8);
|
||||
uint8_t ulen = k_info & 0x1F;
|
||||
int k = (k_info >> 5 == 7) ? -1 : k_info >> 5;
|
||||
int znum_bit = (cmd_info.zero_guard_en && k > 0) ? 4 : 0;
|
||||
uint8_t blk_bs_size = (k == -1) ? 128 : (k << 4) + ulen + 16 + znum_bit;
|
||||
|
||||
// exp: BGR decode
|
||||
vlc_gr_dec_block_data(&bs_data, blk_bs_size, blk_data, k, cmd_info.zero_guard_en);
|
||||
|
||||
inv_symbol_remapping(blk_data, blk_sr_data, cmd_info.bias0, cmd_info.bias1, false, true, cmd_info.zero_guard_en);
|
||||
|
||||
size_t out_num = (blk_idx == (blk_num - 1)) ? ((isz >> 1) - (blk_idx << 4)) : 16;
|
||||
|
||||
// frac: implicit zero compression
|
||||
for (size_t i = 0; i < out_num; i++)
|
||||
{
|
||||
if (!cmd_info.zero_guard_en || blk_sr_data[i] != 0)
|
||||
{
|
||||
parse_stream(&bs_data, &blk_data_frac[i], 8);
|
||||
}
|
||||
}
|
||||
merge_bf16_data(blk_sr_data, blk_data_frac, &obuf[blk_idx << 4], out_num);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void bm_vlc_dec_bf16(const uint8_t *ibuf, size_t isz, uint16_t *obuf)
|
||||
{
|
||||
size_t bs_size;
|
||||
bm_vlc_dec_bf16_ext(ibuf, isz, obuf, &bs_size);
|
||||
}
|
||||
|
||||
// -- offline estimate model weight params --
|
||||
static inline void bm_vlc_est_weight_bias(const uint8_t *ibuf, size_t isz, uint8_t signedness, uint8_t isBfloat16, CommandInfo *cmd_info)
|
||||
{
|
||||
assert(!(isBfloat16 && signedness)); // WARNING: signedness MUST be 0 as isBfloat16==True
|
||||
|
||||
cmd_info->is_bfloat16 = isBfloat16;
|
||||
if (isBfloat16 == false && signedness == true)
|
||||
{
|
||||
// two-side circular shift
|
||||
int hist[256] = {0};
|
||||
for (size_t i = 0; i < isz; i++)
|
||||
{
|
||||
hist[ibuf[i]]++;
|
||||
}
|
||||
|
||||
int8_t pos_v = 1;
|
||||
//while (pos_v < 128)
|
||||
// comparison is always true due to limited range of data type [-Werror=type-limits]
|
||||
while (true)
|
||||
{
|
||||
if (hist[((uint8_t)pos_v)] == 0)
|
||||
{
|
||||
pos_v++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
//cmd_info->bias0 = (pos_v > 1 && pos_v < 128) ? (pos_v - 1) : 0;
|
||||
// comparison is always true due to limited range of data type [-Werror=type-limits]
|
||||
cmd_info->bias0 = (pos_v > 1) ? (pos_v - 1) : 0;
|
||||
int8_t neg_v = -1;
|
||||
//while (neg_v >= (-128)) // comparison is always true due to limited range of data type [-Werror=type-limits]
|
||||
while (true)
|
||||
{
|
||||
if (hist[(uint8_t)neg_v] == 0)
|
||||
{
|
||||
neg_v--;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
//cmd_info->bias1 = (neg_v < -1 && neg_v >= -128) ? abs(neg_v + 1) : 0;
|
||||
// comparison is always true due to limited range of data type [-Werror=type-limits]
|
||||
cmd_info->bias1 = (neg_v < -1) ? abs(neg_v + 1) : 0;
|
||||
cmd_info->signedness = true;
|
||||
}
|
||||
|
||||
if (isBfloat16 == true)
|
||||
{
|
||||
// center shift
|
||||
int64_t exp_accum = 0;
|
||||
uint16_t *bf16_in = (uint16_t *)ibuf;
|
||||
size_t inum = (isz >> 1), cnt = 0;
|
||||
for (size_t i = 0; i < inum; i++)
|
||||
{
|
||||
uint8_t exp = ((bf16_in[i] >> 7) & 0xFF);
|
||||
if (exp != 0)
|
||||
{
|
||||
exp_accum += exp;
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
if (cnt > 0)
|
||||
{
|
||||
cmd_info->bias0 = (uint8_t)((exp_accum / (float)cnt) + 0.5);
|
||||
}
|
||||
cmd_info->zero_guard_en = (inum == cnt) ? false : true;
|
||||
cmd_info->signedness = false;
|
||||
}
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __BM_VLC_COMPRESS_H__ */
|
||||
1176
cvikernel/include/bmkernel/bm1822/bmkernel_1822.h
Normal file
1176
cvikernel/include/bmkernel/bm1822/bmkernel_1822.h
Normal file
File diff suppressed because it is too large
Load Diff
369
cvikernel/include/bmkernel/bm1822/compression.h
Normal file
369
cvikernel/include/bmkernel/bm1822/compression.h
Normal file
@ -0,0 +1,369 @@
|
||||
#ifndef COMPRESSION_H
|
||||
#define COMPRESSION_H
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
typedef struct {
|
||||
uint32_t compress_md;
|
||||
uint32_t bit_length;
|
||||
int is_signed;
|
||||
|
||||
uint64_t total_data_num;
|
||||
uint32_t non_zero_data_num;
|
||||
|
||||
uint64_t header_bytes;
|
||||
uint64_t map_bytes;
|
||||
uint64_t data_bytes;
|
||||
uint64_t total_bytes;
|
||||
|
||||
int compressed_min;
|
||||
int compressed_max;
|
||||
} compression_info_t;
|
||||
|
||||
typedef struct {
|
||||
uint64_t header_offset;
|
||||
uint64_t header_size;
|
||||
uint64_t map_offset;
|
||||
uint64_t map_size;
|
||||
uint64_t data_offset;
|
||||
uint64_t data_size;
|
||||
uint64_t total_size;
|
||||
} compress_addr_info;
|
||||
|
||||
static uint64_t compression_map_bytes(uint64_t total_data_num)
|
||||
{
|
||||
uint64_t bit_alignment = 16 * 8;
|
||||
uint64_t bits = total_data_num;
|
||||
|
||||
return ceiling_func(bits, bit_alignment)*16;
|
||||
}
|
||||
|
||||
static uint64_t compression_map_clear_bytes(uint64_t total_data_num)
|
||||
{
|
||||
uint64_t bit_alignment = 2 * 8;
|
||||
uint64_t bits = total_data_num;
|
||||
|
||||
return ceiling_func(bits, bit_alignment)*2;
|
||||
}
|
||||
|
||||
|
||||
static uint64_t compression_data_bytes(uint64_t non_zero_data_num, uint32_t bit_length)
|
||||
{
|
||||
if (bit_length == 1)
|
||||
return 0;
|
||||
|
||||
uint64_t bit_alignment = 8;
|
||||
uint64_t bits = non_zero_data_num * bit_length;
|
||||
|
||||
return ceiling_func(bits, bit_alignment);
|
||||
}
|
||||
|
||||
static inline uint32_t compression_bit_length(uint32_t compress_md)
|
||||
{
|
||||
switch (compress_md) {
|
||||
case 0:
|
||||
return 8;
|
||||
case 1:
|
||||
return 4;
|
||||
case 2:
|
||||
return 2;
|
||||
case 3:
|
||||
return 1;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void compute_compressed_range(
|
||||
uint32_t bit_length, int is_signed, int *min, int *max)
|
||||
{
|
||||
if (is_signed) {
|
||||
switch (bit_length) {
|
||||
case 1:
|
||||
*min = -1;
|
||||
*max = 0;
|
||||
return;
|
||||
case 2:
|
||||
*min = -2;
|
||||
*max = 1;
|
||||
return;
|
||||
case 4:
|
||||
*min = -8;
|
||||
*max = 7;
|
||||
return;
|
||||
case 8:
|
||||
*min = -128;
|
||||
*max = 127;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
*min = 0;
|
||||
switch (bit_length) {
|
||||
case 1:
|
||||
*max = 1;
|
||||
return;
|
||||
case 2:
|
||||
*max = 3;
|
||||
return;
|
||||
case 4:
|
||||
*max = 15;
|
||||
return;
|
||||
case 8:
|
||||
*max = 255;
|
||||
return;
|
||||
}
|
||||
}
|
||||
assert(0);
|
||||
}
|
||||
|
||||
static inline int saturate(int val, int max, int min)
|
||||
{
|
||||
if (val < min)
|
||||
return min;
|
||||
else if (val > max)
|
||||
return max;
|
||||
else
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline uint64_t count_non_zero_results(
|
||||
uint8_t buf[], uint64_t size, int is_signed, int max, int min)
|
||||
{
|
||||
uint64_t n = 0;
|
||||
|
||||
for (uint64_t i = 0; i < size; i++) {
|
||||
int val = is_signed? (int8_t)buf[i]: buf[i];
|
||||
int res = saturate(val, max, min);
|
||||
if (res != 0)
|
||||
n++;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static inline void set_map_bit(uint8_t map[], uint64_t i)
|
||||
{
|
||||
uint64_t byte_i = i / 8;
|
||||
uint64_t bit_i = i % 8;
|
||||
|
||||
map[byte_i] |= (1 << bit_i);
|
||||
}
|
||||
|
||||
static inline uint8_t read_map_bit(uint8_t map[], uint64_t i)
|
||||
{
|
||||
uint64_t byte_i = i / 8;
|
||||
uint64_t bit_i = i % 8;
|
||||
|
||||
return (map[byte_i] >> bit_i) & 1;
|
||||
}
|
||||
|
||||
static inline void parse_header(
|
||||
uint32_t header, int *is_signed, uint32_t *compress_md, uint32_t *nz_num)
|
||||
{
|
||||
*is_signed = (header >> 29) & 1;
|
||||
*compress_md = (header >> 24) & 0b11;
|
||||
*nz_num = header & 0xffffff;
|
||||
}
|
||||
|
||||
static inline void fill_header(uint32_t *hdr, compression_info_t *info)
|
||||
{
|
||||
if(compression_bit_length(info->compress_md)!=1)
|
||||
{
|
||||
*hdr = (info->is_signed << 29) | (1 << 28) |
|
||||
(info->compress_md << 24) |
|
||||
info->non_zero_data_num;
|
||||
}else
|
||||
{
|
||||
*hdr = (info->is_signed << 29) | (1 << 28) |
|
||||
(info->compress_md << 24);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void fill_map(uint8_t map[], uint8_t buf[], compression_info_t *info)
|
||||
{
|
||||
int min = info->compressed_min;
|
||||
int max = info->compressed_max;
|
||||
|
||||
uint64_t clear_map = compression_map_clear_bytes(info->total_data_num);
|
||||
for (uint64_t i = 0; i < clear_map; i++)
|
||||
map[i] = 0;
|
||||
|
||||
for (uint64_t i = 0; i < info->total_data_num; i++) {
|
||||
int val = info->is_signed? (int8_t)buf[i]: buf[i];
|
||||
int res = saturate(val, max, min);
|
||||
if (res != 0)
|
||||
set_map_bit(map, i);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void compress_one_data(
|
||||
uint8_t data[], uint64_t i, uint8_t val, compression_info_t *info)
|
||||
{
|
||||
uint32_t bit_len = info->bit_length;
|
||||
uint32_t data_per_byte = 8 / bit_len;
|
||||
|
||||
uint32_t byte_i = i / data_per_byte;
|
||||
uint32_t bit_i = (i % data_per_byte) * bit_len;
|
||||
uint8_t mask = (1 << bit_len) - 1;
|
||||
|
||||
data[byte_i] |= (val & mask) << bit_i;
|
||||
}
|
||||
|
||||
static inline uint8_t sign_extend(uint8_t val, uint32_t bit_len)
|
||||
{
|
||||
int shift = 8 - bit_len;
|
||||
return (int8_t)(val << shift) >> shift;
|
||||
}
|
||||
|
||||
static inline uint8_t decompress_one_data(
|
||||
uint8_t data[], uint64_t i, compression_info_t *info)
|
||||
{
|
||||
uint32_t bit_len = info->bit_length;
|
||||
uint32_t data_per_byte = 8 / bit_len;
|
||||
|
||||
uint32_t byte_i = i / data_per_byte;
|
||||
uint32_t bit_i = (i % data_per_byte) * bit_len;
|
||||
uint8_t mask = (1 << bit_len) - 1;
|
||||
|
||||
uint8_t val = (data[byte_i] >> bit_i) & mask;
|
||||
if (info->is_signed)
|
||||
val = sign_extend(val, bit_len);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline void fill_data(uint8_t data[], uint8_t buf[], compression_info_t *info)
|
||||
{
|
||||
int min = info->compressed_min;
|
||||
int max = info->compressed_max;
|
||||
|
||||
for (uint64_t i = 0; i < info->data_bytes; i++)
|
||||
data[i] = 0;
|
||||
|
||||
uint64_t nz_i = 0;
|
||||
for (uint64_t i = 0; i < info->total_data_num; i++) {
|
||||
int val = info->is_signed? (int8_t)buf[i]: buf[i];
|
||||
int res = saturate(val, max, min);
|
||||
if (res != 0) {
|
||||
compress_one_data(data, nz_i, res, info);
|
||||
nz_i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline compression_info_t make_compression_info(
|
||||
uint8_t buf[], uint64_t size, uint32_t compress_md, int is_signed)
|
||||
{
|
||||
uint32_t bit_length = compression_bit_length(compress_md);
|
||||
|
||||
int min, max;
|
||||
compute_compressed_range(bit_length, is_signed, &min, &max);
|
||||
|
||||
uint32_t nz_num = count_non_zero_results(buf, size, is_signed, max, min);
|
||||
assert(nz_num <= 0xffffff);
|
||||
|
||||
compression_info_t info;
|
||||
info.compress_md = compress_md;
|
||||
info.bit_length = bit_length;
|
||||
info.is_signed = is_signed;
|
||||
info.total_data_num = size;
|
||||
info.non_zero_data_num = nz_num;
|
||||
info.header_bytes = 16;
|
||||
info.map_bytes = compression_map_bytes(size);
|
||||
info.data_bytes = compression_data_bytes(nz_num, bit_length);
|
||||
info.total_bytes = info.header_bytes + info.map_bytes + info.data_bytes;
|
||||
info.compressed_min = min;
|
||||
info.compressed_max = max;
|
||||
return info;
|
||||
}
|
||||
|
||||
static inline compression_info_t parse_compression_info(
|
||||
uint8_t compressed_buf[], uint64_t max_size, uint64_t total_data_num)
|
||||
{
|
||||
uint64_t header_bytes = 16;
|
||||
assert(header_bytes <= max_size);
|
||||
|
||||
int is_signed;
|
||||
uint32_t compress_md, nz_num;
|
||||
parse_header(*(uint32_t *)compressed_buf, &is_signed, &compress_md, &nz_num);
|
||||
|
||||
uint32_t bit_length = compression_bit_length(compress_md);
|
||||
int min, max;
|
||||
compute_compressed_range(bit_length, is_signed, &min, &max);
|
||||
|
||||
compression_info_t info;
|
||||
info.compress_md = compress_md;
|
||||
info.bit_length = compression_bit_length(compress_md);
|
||||
info.is_signed = is_signed;
|
||||
info.total_data_num = total_data_num;
|
||||
info.non_zero_data_num = nz_num;
|
||||
info.header_bytes = header_bytes;
|
||||
info.map_bytes = compression_map_bytes(total_data_num);
|
||||
info.data_bytes = compression_data_bytes(nz_num, info.bit_length);
|
||||
info.total_bytes = header_bytes + info.map_bytes + info.data_bytes;
|
||||
info.compressed_min = min;
|
||||
info.compressed_max = max;
|
||||
|
||||
assert(info.total_bytes <= max_size);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
static inline uint8_t * compress(
|
||||
uint8_t buf[], uint64_t size, uint32_t compress_md, int is_signed, compress_addr_info *compressed_data)
|
||||
{
|
||||
compression_info_t info =
|
||||
make_compression_info(buf, size, compress_md, is_signed);
|
||||
|
||||
assert(info.total_bytes < 0x100000);
|
||||
static uint8_t *result = new uint8_t[0x100000];
|
||||
uint32_t *hdr = (uint32_t *)result;
|
||||
uint8_t *map = &result[info.header_bytes];
|
||||
uint8_t *data = &map[info.map_bytes];
|
||||
|
||||
fill_header(hdr, &info);
|
||||
fill_map(map, buf, &info);
|
||||
if (info.bit_length != 1)
|
||||
fill_data(data, buf, &info);
|
||||
|
||||
compressed_data->header_offset = 0;
|
||||
compressed_data->header_size = 4;
|
||||
compressed_data->map_offset = info.header_bytes;
|
||||
compressed_data->map_size = compression_map_clear_bytes(info.total_data_num);
|
||||
compressed_data->data_offset = info.map_bytes + info.header_bytes;
|
||||
compressed_data->data_size = info.data_bytes;
|
||||
compressed_data->total_size = info.total_bytes;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline void decompress(
|
||||
uint8_t buf[], uint64_t size, uint8_t compressed_buf[], uint64_t max_size)
|
||||
{
|
||||
compression_info_t info =
|
||||
parse_compression_info(compressed_buf, max_size, size);
|
||||
assert(info.total_bytes <= max_size);
|
||||
assert(info.total_data_num == size);
|
||||
|
||||
uint8_t *map = &compressed_buf[info.header_bytes];
|
||||
if (info.bit_length == 1) {
|
||||
for (uint64_t i = 0; i < size; i++) {
|
||||
uint8_t val = read_map_bit(map, i);
|
||||
buf[i] = info.is_signed? sign_extend(val, 1): val;
|
||||
}
|
||||
} else {
|
||||
uint8_t *data = &map[info.map_bytes];
|
||||
uint64_t data_i = 0;
|
||||
for (uint64_t i = 0; i < size; i++) {
|
||||
uint8_t val = read_map_bit(map, i);
|
||||
if (val == 0) {
|
||||
buf[i] = 0;
|
||||
} else {
|
||||
buf[i] = decompress_one_data(data, data_i, &info);
|
||||
data_i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* COMPRESSION_H */
|
||||
338
cvikernel/include/bmkernel/bm1880v2/1880v2_fp_convert.h
Executable file
338
cvikernel/include/bmkernel/bm1880v2/1880v2_fp_convert.h
Executable file
@ -0,0 +1,338 @@
|
||||
#ifndef ATOMIC_FP_H_
|
||||
#define ATOMIC_FP_H_
|
||||
|
||||
#if __arm__
|
||||
#define __DISABLE_FENV__
|
||||
#endif
|
||||
|
||||
#ifndef __DISABLE_FENV__
|
||||
#include <fenv.h>
|
||||
#endif
|
||||
#include <math.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static inline uint8_t convert_bf16_u8(uint16_t data);
|
||||
static inline uint8_t _convert_bf16_u8(uint16_t data, int int8_rnd_md);
|
||||
static inline int8_t _convert_bf16_s8(uint16_t data, int int8_rnd_md);
|
||||
static inline int8_t convert_bf16_s8(uint16_t data);
|
||||
static inline uint16_t convert_int8_bf16(uint8_t data, uint8_t sign);
|
||||
static inline uint32_t convert_fp32_u32(float fp32);
|
||||
static inline uint32_t convert_fp32_hex(float val);
|
||||
static inline float convert_hex_fp32(uint32_t hval);
|
||||
|
||||
static inline float convert_bf16_fp32(uint16_t bf16);
|
||||
static inline uint16_t convert_fp32_bf16(float fp32);
|
||||
|
||||
static inline void f32_integer(void *if32, void *o_integer, int integer_size, int accumulate, int int8_signed, int int8_rnd_md);
|
||||
//static inline void f32_integer(void *if32, void *o_integer,
|
||||
// 0 for 32 bit , 1 for 16 bit , 2 for 8 bit
|
||||
// int integer_size, int accumulate = 0, int int8_signed = 1, int int8_rnd_md = 0);
|
||||
|
||||
union convert_type_float {
|
||||
float fval;
|
||||
uint16_t bf16[2];
|
||||
uint32_t ival;
|
||||
};
|
||||
|
||||
typedef union convert_type_float convert_int_float;
|
||||
static const uint16_t NAN_VALUE = 0x7FC0;
|
||||
|
||||
//static int round_mode = 0;
|
||||
static uint8_t float_isnan(const float x) {
|
||||
//return isnan(x);
|
||||
return x != x;
|
||||
}
|
||||
|
||||
static inline int set_store_feround()
|
||||
{
|
||||
#ifndef __DISABLE_FENV__
|
||||
int round_mode = fegetround();
|
||||
fesetround(FE_TOWARDZERO);
|
||||
return round_mode;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void restore_feround(int round_mode)
|
||||
{
|
||||
#ifndef __DISABLE_FENV__
|
||||
fesetround(round_mode);
|
||||
#else
|
||||
(void)round_mode;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline uint8_t _convert_bf16_u8(uint16_t data, int int8_rnd_md)
|
||||
{
|
||||
/* convert bf16 to float32*/
|
||||
float fp32;
|
||||
convert_int_float convert_val;
|
||||
fp32 = convert_bf16_fp32(data);
|
||||
/* convert float32 to uint8_t*/
|
||||
f32_integer((void*)&fp32, &convert_val.ival, 2, 0, 0, int8_rnd_md);
|
||||
return (uint8_t) convert_val.ival;
|
||||
}
|
||||
|
||||
static inline uint8_t convert_bf16_u8(uint16_t data)
|
||||
{
|
||||
return (uint8_t) _convert_bf16_u8(data, 0);
|
||||
}
|
||||
|
||||
static inline int8_t _convert_bf16_s8(uint16_t data, int int8_rnd_md)
|
||||
{
|
||||
/* convert bf16 to float32*/
|
||||
float fp32;
|
||||
convert_int_float convert_val;
|
||||
fp32 = convert_bf16_fp32(data);
|
||||
/* convert float32 to uint8_t*/
|
||||
f32_integer((void*)&fp32, &convert_val.ival, 2, 0, 1, int8_rnd_md);
|
||||
return (int8_t) convert_val.ival;
|
||||
}
|
||||
|
||||
static inline int8_t convert_bf16_s8(uint16_t data)
|
||||
{
|
||||
return (int8_t) _convert_bf16_s8(data, 0);
|
||||
}
|
||||
|
||||
static inline uint16_t convert_int8_bf16(uint8_t data, uint8_t sign)
|
||||
{
|
||||
int32_t val = sign ? (int8_t) data : (uint8_t) data;
|
||||
/* need to round to bf16 mode */
|
||||
return convert_fp32_bf16((float) val);
|
||||
}
|
||||
|
||||
static inline uint16_t convert_fp32_bf16(float fp32)
|
||||
{
|
||||
if (float_isnan(fp32))
|
||||
return NAN_VALUE;
|
||||
convert_int_float convert_val;
|
||||
convert_val.fval = fp32;
|
||||
uint32_t input = convert_val.ival;
|
||||
uint32_t lsb = (input >> 16) & 1;
|
||||
uint32_t rounding_bias = 0x7fff + lsb;
|
||||
input += rounding_bias;
|
||||
convert_val.bf16[1] = (uint16_t) (input >> 16);
|
||||
|
||||
/* HW behavior */
|
||||
if ((convert_val.bf16[1] & 0x7f80) == 0x7f80) {
|
||||
convert_val.bf16[1] = 0x7f7f;
|
||||
}
|
||||
return convert_val.bf16[1];
|
||||
}
|
||||
|
||||
static inline uint8_t convert_fp32_u8(float fp32)
|
||||
{
|
||||
convert_int_float convert_val;
|
||||
f32_integer((void*)&fp32, &convert_val.ival, 2, 0, 0, 0);
|
||||
return (uint8_t) convert_val.ival;
|
||||
}
|
||||
|
||||
static inline int8_t convert_fp32_s8(float fp32)
|
||||
{
|
||||
convert_int_float convert_val;
|
||||
f32_integer((void*)&fp32, &convert_val.ival, 2, 0, 1, 0);
|
||||
return (int8_t) convert_val.ival;
|
||||
}
|
||||
|
||||
static inline uint32_t convert_fp32_u32(float fp32)
|
||||
{
|
||||
convert_int_float convert_val;
|
||||
f32_integer((void*)&fp32, &convert_val.ival, 0, 0, 0, 0);
|
||||
return (uint32_t) convert_val.ival;
|
||||
}
|
||||
|
||||
static inline int32_t convert_fp32_s32(float fp32)
|
||||
{
|
||||
convert_int_float convert_val;
|
||||
f32_integer((void*)&fp32, &convert_val.ival, 0, 0, 1, 0);
|
||||
return (int32_t) convert_val.ival;
|
||||
}
|
||||
|
||||
/* convert hex to float directly */
|
||||
static inline float convert_hex_fp32(uint32_t hval)
|
||||
{
|
||||
convert_int_float convert_val;
|
||||
convert_val.ival = hval;
|
||||
return convert_val.fval;
|
||||
}
|
||||
/* convert float to hex directly */
|
||||
static inline uint32_t convert_fp32_hex(float val)
|
||||
{
|
||||
convert_int_float convert_val;
|
||||
convert_val.fval = val;
|
||||
return convert_val.ival;
|
||||
}
|
||||
static inline float convert_bf16_fp32(uint16_t bf16)
|
||||
{
|
||||
convert_int_float convert_val;
|
||||
convert_val.bf16[1] = bf16;
|
||||
convert_val.bf16[0] = 0;
|
||||
return convert_val.fval;
|
||||
}
|
||||
|
||||
static inline void flt2int_flt(float x, unsigned long long* integer_part, float * sub_part, uint8_t sign)
|
||||
{
|
||||
convert_int_float work_x;
|
||||
int level_code;
|
||||
unsigned long tail_code;
|
||||
work_x.fval = x;
|
||||
level_code = ((work_x.ival >> 23) & 0xff) - 127;
|
||||
|
||||
//if the level code is negaive, the integer part of the float is zero
|
||||
if ( level_code < 0 ){
|
||||
*integer_part = 0;
|
||||
*sub_part = x;
|
||||
}
|
||||
else {
|
||||
tail_code = (work_x.ival) & 0x7fffff;
|
||||
tail_code = tail_code | 0x800000;
|
||||
|
||||
if (level_code < 23){
|
||||
tail_code >>= (23 - level_code);
|
||||
*integer_part = tail_code;
|
||||
work_x.ival &= 0xffffffff << (23 - level_code);
|
||||
*sub_part = x - work_x.fval;
|
||||
}
|
||||
else {
|
||||
tail_code <<= (level_code - 23);
|
||||
*integer_part = tail_code;
|
||||
if(level_code>30){
|
||||
*integer_part = 0x7fffffff;
|
||||
if(sign)*integer_part = 0x800000000;
|
||||
}
|
||||
*sub_part = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline static int flt2int(float ifval, int int8_rnd_md)
|
||||
{
|
||||
union {
|
||||
float floatNum;
|
||||
unsigned long intNum;
|
||||
} tempIfval;
|
||||
tempIfval.floatNum = ifval;
|
||||
uint8_t isPositive = ((tempIfval.intNum & 0x80000000UL) == 0x80000000UL) ? 0 : 1 ;
|
||||
float abs_fval = (!isPositive) ? -ifval : ifval;
|
||||
double sub_part;
|
||||
double integer;
|
||||
unsigned long long integer_part;
|
||||
//uint8_t sign = !isPositive;
|
||||
//flt2int_flt(abs_fval, &integer_part, &sub_part, sign);
|
||||
sub_part = modf((double)abs_fval, &integer);
|
||||
integer_part = (unsigned long long)integer;
|
||||
if (!isPositive)
|
||||
{
|
||||
unsigned long long result;
|
||||
if(int8_rnd_md == 0) { // round to nearest even
|
||||
if ( sub_part > 0.5f )
|
||||
{
|
||||
result = integer_part + 1;
|
||||
}
|
||||
else if (sub_part == 0.5f)
|
||||
{
|
||||
if ( integer_part & 0x1 )
|
||||
{
|
||||
result = integer_part + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = integer_part;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = integer_part;
|
||||
}
|
||||
} else { //round to zero
|
||||
result = integer_part;
|
||||
}
|
||||
if ( result > 0x80000000UL )
|
||||
{
|
||||
result = 0x80000000UL;
|
||||
}
|
||||
return -result;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned long long result;
|
||||
if(int8_rnd_md == 0) { // round to nearest even
|
||||
if ( sub_part > 0.5f )
|
||||
{
|
||||
result = integer_part + 1;
|
||||
}
|
||||
else if ( sub_part == 0.5f )
|
||||
{
|
||||
if ( integer_part & 0x1 )
|
||||
{
|
||||
result = integer_part + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = integer_part;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = integer_part;
|
||||
}
|
||||
} else {
|
||||
result = integer_part;
|
||||
}
|
||||
if ( result > 0x7fffffff )
|
||||
{
|
||||
result = 0x7fffffff;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void f32_integer(void *if32, void *o_integer, int integer_size, int accumulate, int int8_signed, int int8_rnd_md)
|
||||
{
|
||||
int i_tmp;
|
||||
float *f_tmp;
|
||||
f_tmp = (float *)if32;
|
||||
i_tmp = flt2int(*f_tmp, int8_rnd_md);
|
||||
int *o32 = (int *)o_integer;
|
||||
int dst_f32 = *o32;
|
||||
short *o16 = (short *)o_integer;
|
||||
short dst_o16 = *o32;
|
||||
char *o8 = (char *)o_integer;
|
||||
char dst_o8 = *o8;
|
||||
|
||||
if (integer_size == 0) {
|
||||
*o32 = i_tmp;
|
||||
} else if (integer_size == 1) {
|
||||
*o16 = i_tmp;
|
||||
} else{
|
||||
*o8 = i_tmp;
|
||||
int min = (int8_signed) ? -128 : 0;
|
||||
int max = (int8_signed) ? 127 : 255;
|
||||
if (i_tmp < min ){
|
||||
*o8 = min;
|
||||
}
|
||||
else if (i_tmp > max){
|
||||
*o8 = max;
|
||||
}
|
||||
//*o8 = i_tmp;
|
||||
}
|
||||
if (accumulate) {
|
||||
if (integer_size == 0) {
|
||||
*o32 += dst_f32;
|
||||
} else if (integer_size == 1) {
|
||||
*o16 += dst_o16;
|
||||
} else
|
||||
*o8 += dst_o8;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ATOMIC_FP_H_ */
|
||||
|
||||
301
cvikernel/include/bmkernel/bm1880v2/bm1880v2_tdma_reg.h
Normal file
301
cvikernel/include/bmkernel/bm1880v2/bm1880v2_tdma_reg.h
Normal file
@ -0,0 +1,301 @@
|
||||
#ifndef BM1880v2_TDMA_REG_V1_32_H
|
||||
#define BM1880v2_TDMA_REG_V1_32_H
|
||||
|
||||
/*
|
||||
* This file is generated by tools. Do not edit it manually.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef unsigned long long ullong;
|
||||
|
||||
typedef struct {
|
||||
uint32_t vld;
|
||||
uint32_t compress_en;
|
||||
uint32_t eod;
|
||||
uint32_t intp_en;
|
||||
uint32_t bar_en;
|
||||
uint32_t check_bf16_value;
|
||||
uint32_t trans_dir;
|
||||
uint32_t rsv00;
|
||||
uint32_t trans_fmt;
|
||||
uint32_t transpose_md;
|
||||
uint32_t rsv01;
|
||||
uint32_t outstanding_en;
|
||||
uint32_t cmd_id;
|
||||
uint32_t spec_func;
|
||||
uint32_t dst_fmt;
|
||||
uint32_t src_fmt;
|
||||
uint32_t cmprs_fmt;
|
||||
uint32_t sys_dtype;
|
||||
uint32_t rsv2_1;
|
||||
uint32_t int8_sign;
|
||||
uint32_t compress_zero_guard;
|
||||
uint32_t int8_rnd_mode;
|
||||
uint32_t wait_id_tpu;
|
||||
uint32_t wait_id_other_tdma;
|
||||
uint32_t wait_id_sdma;
|
||||
uint32_t const_val;
|
||||
uint32_t src_base_reg_sel;
|
||||
uint32_t mv_lut_idx;
|
||||
uint32_t dst_base_reg_sel;
|
||||
uint32_t mv_lut_base;
|
||||
uint32_t rsv4_5;
|
||||
uint32_t dst_h_stride;
|
||||
uint32_t dst_c_stride_low;
|
||||
uint32_t dst_n_stride;
|
||||
uint32_t src_h_stride;
|
||||
uint32_t src_c_stride_low;
|
||||
uint32_t src_n_stride;
|
||||
uint32_t dst_c;
|
||||
uint32_t src_c;
|
||||
uint32_t dst_w;
|
||||
uint32_t dst_h;
|
||||
uint32_t src_w;
|
||||
uint32_t src_h;
|
||||
uint32_t dst_base_addr_low;
|
||||
uint32_t src_base_addr_low;
|
||||
uint32_t src_n;
|
||||
uint32_t dst_base_addr_high;
|
||||
uint32_t src_base_addr_high;
|
||||
uint32_t src_c_stride_high;
|
||||
uint32_t dst_c_stride_high;
|
||||
uint32_t compress_bias0;
|
||||
uint32_t compress_bias1;
|
||||
uint32_t layer_ID;
|
||||
} tdma_reg_t;
|
||||
|
||||
static inline void parse_tdma_reg(tdma_reg_t *r, const uint32_t *p)
|
||||
{
|
||||
r->vld = p[0] & 1;
|
||||
r->compress_en = (p[0] >> 1) & 1;
|
||||
r->eod = (p[0] >> 2) & 1;
|
||||
r->intp_en = (p[0] >> 3) & 1;
|
||||
r->bar_en = (p[0] >> 4) & 1;
|
||||
r->check_bf16_value = (p[0] >> 5) & 1;
|
||||
r->trans_dir = (p[0] >> 6) & ((1u << 2) - 1);
|
||||
r->rsv00 = (p[0] >> 8) & ((1u << 2) - 1);
|
||||
r->trans_fmt = (p[0] >> 10) & 1;
|
||||
r->transpose_md = (p[0] >> 11) & ((1u << 2) - 1);
|
||||
r->rsv01 = (p[0] >> 13) & ((1u << 2) - 1);
|
||||
r->outstanding_en = (p[0] >> 15) & 1;
|
||||
r->cmd_id = (p[0] >> 16) & ((1u << 16) - 1);
|
||||
r->spec_func = p[1] & ((1u << 3) - 1);
|
||||
r->dst_fmt = (p[1] >> 3) & ((1u << 2) - 1);
|
||||
r->src_fmt = (p[1] >> 5) & ((1u << 2) - 1);
|
||||
r->cmprs_fmt = (p[1] >> 7) & 1;
|
||||
r->sys_dtype = (p[1] >> 8) & 1;
|
||||
r->rsv2_1 = (p[1] >> 9) & ((1u << 4) - 1);
|
||||
r->int8_sign = (p[1] >> 13) & 1;
|
||||
r->compress_zero_guard = (p[1] >> 14) & 1;
|
||||
r->int8_rnd_mode = (p[1] >> 15) & 1;
|
||||
r->wait_id_tpu = (p[1] >> 16) & ((1u << 16) - 1);
|
||||
r->wait_id_other_tdma = p[2] & ((1u << 16) - 1);
|
||||
r->wait_id_sdma = (p[2] >> 16) & ((1u << 16) - 1);
|
||||
r->const_val = p[3] & ((1u << 16) - 1);
|
||||
r->src_base_reg_sel = (p[3] >> 16) & ((1u << 3) - 1);
|
||||
r->mv_lut_idx = (p[3] >> 19) & 1;
|
||||
r->dst_base_reg_sel = (p[3] >> 20) & ((1u << 3) - 1);
|
||||
r->mv_lut_base = (p[3] >> 23) & 1;
|
||||
r->rsv4_5 = (p[3] >> 24) & ((1u << 8) - 1);
|
||||
r->dst_h_stride = p[4] & ((1u << 16) - 1);
|
||||
r->dst_c_stride_low = (p[4] >> 16) & ((1u << 16) - 1);
|
||||
r->dst_n_stride = p[5];
|
||||
r->src_h_stride = p[6] & ((1u << 16) - 1);
|
||||
r->src_c_stride_low = (p[6] >> 16) & ((1u << 16) - 1);
|
||||
r->src_n_stride = p[7];
|
||||
r->dst_c = p[8] & ((1u << 16) - 1);
|
||||
r->src_c = (p[8] >> 16) & ((1u << 16) - 1);
|
||||
r->dst_w = p[9] & ((1u << 16) - 1);
|
||||
r->dst_h = (p[9] >> 16) & ((1u << 16) - 1);
|
||||
r->src_w = p[10] & ((1u << 16) - 1);
|
||||
r->src_h = (p[10] >> 16) & ((1u << 16) - 1);
|
||||
r->dst_base_addr_low = p[11];
|
||||
r->src_base_addr_low = p[12];
|
||||
r->src_n = p[13] & ((1u << 16) - 1);
|
||||
r->dst_base_addr_high = (p[13] >> 16) & ((1u << 8) - 1);
|
||||
r->src_base_addr_high = (p[13] >> 24) & ((1u << 8) - 1);
|
||||
r->src_c_stride_high = p[14] & ((1u << 16) - 1);
|
||||
r->dst_c_stride_high = (p[14] >> 16) & ((1u << 16) - 1);
|
||||
r->compress_bias0 = p[15] & ((1u << 8) - 1);
|
||||
r->compress_bias1 = (p[15] >> 8) & ((1u << 8) - 1);
|
||||
r->layer_ID = (p[15] >> 16) & ((1u << 16) - 1);
|
||||
}
|
||||
|
||||
static inline void emit_tdma_reg(const tdma_reg_t *r, uint32_t *_p)
|
||||
{
|
||||
volatile uint32_t *p = (typeof(p))_p;
|
||||
p[15] = (r->compress_bias0 & ((1u << 8) - 1)) |
|
||||
((r->compress_bias1 & ((1u << 8) - 1)) << 8) |
|
||||
((r->layer_ID & ((1u << 16) - 1)) << 16);
|
||||
p[14] = (r->src_c_stride_high & ((1u << 16) - 1)) |
|
||||
((r->dst_c_stride_high & ((1u << 16) - 1)) << 16);
|
||||
p[13] = (r->src_n & ((1u << 16) - 1)) |
|
||||
((r->dst_base_addr_high & ((1u << 8) - 1)) << 16) |
|
||||
((r->src_base_addr_high & ((1u << 8) - 1)) << 24);
|
||||
p[12] = (r->src_base_addr_low & (((uint64_t)1 << 32) - 1));
|
||||
p[11] = (r->dst_base_addr_low & (((uint64_t)1 << 32) - 1));
|
||||
p[10] = (r->src_w & ((1u << 16) - 1)) |
|
||||
((r->src_h & ((1u << 16) - 1)) << 16);
|
||||
p[9] = (r->dst_w & ((1u << 16) - 1)) |
|
||||
((r->dst_h & ((1u << 16) - 1)) << 16);
|
||||
p[8] = (r->dst_c & ((1u << 16) - 1)) |
|
||||
((r->src_c & ((1u << 16) - 1)) << 16);
|
||||
p[7] = (r->src_n_stride & (((uint64_t)1 << 32) - 1));
|
||||
p[6] = (r->src_h_stride & ((1u << 16) - 1)) |
|
||||
((r->src_c_stride_low & ((1u << 16) - 1)) << 16);
|
||||
p[5] = (r->dst_n_stride & (((uint64_t)1 << 32) - 1));
|
||||
p[4] = (r->dst_h_stride & ((1u << 16) - 1)) |
|
||||
((r->dst_c_stride_low & ((1u << 16) - 1)) << 16);
|
||||
p[3] = (r->const_val & ((1u << 16) - 1)) |
|
||||
((r->src_base_reg_sel & ((1u << 3) - 1)) << 16) |
|
||||
((r->mv_lut_idx & 1) << 19) |
|
||||
((r->dst_base_reg_sel & ((1u << 3) - 1)) << 20) |
|
||||
((r->mv_lut_base & 1) << 23) |
|
||||
((r->rsv4_5 & ((1u << 8) - 1)) << 24);
|
||||
p[2] = (r->wait_id_other_tdma & ((1u << 16) - 1)) |
|
||||
((r->wait_id_sdma & ((1u << 16) - 1)) << 16);
|
||||
p[1] = (r->spec_func & ((1u << 3) - 1)) |
|
||||
((r->dst_fmt & ((1u << 2) - 1)) << 3) |
|
||||
((r->src_fmt & ((1u << 2) - 1)) << 5) |
|
||||
((r->cmprs_fmt & 1) << 7) |
|
||||
((r->sys_dtype & 1) << 8) |
|
||||
((r->rsv2_1 & ((1u << 4) - 1)) << 9) |
|
||||
((r->int8_sign & 1) << 13) |
|
||||
((r->compress_zero_guard & 1) << 14) |
|
||||
((r->int8_rnd_mode & 1) << 15) |
|
||||
((r->wait_id_tpu & ((1u << 16) - 1)) << 16);
|
||||
p[0] = (r->vld & 1) |
|
||||
((r->compress_en & 1) << 1) |
|
||||
((r->eod & 1) << 2) |
|
||||
((r->intp_en & 1) << 3) |
|
||||
((r->bar_en & 1) << 4) |
|
||||
((r->check_bf16_value & 1) << 5) |
|
||||
((r->trans_dir & ((1u << 2) - 1)) << 6) |
|
||||
((r->rsv00 & ((1u << 2) - 1)) << 8) |
|
||||
((r->trans_fmt & 1) << 10) |
|
||||
((r->transpose_md & ((1u << 2) - 1)) << 11) |
|
||||
((r->rsv01 & ((1u << 2) - 1)) << 13) |
|
||||
((r->outstanding_en & 1) << 15) |
|
||||
((r->cmd_id & ((1u << 16) - 1)) << 16);
|
||||
}
|
||||
|
||||
static inline void reset_tdma_reg(tdma_reg_t *r)
|
||||
{
|
||||
r->vld = 0x0;
|
||||
r->compress_en = 0x0;
|
||||
r->eod = 0x0;
|
||||
r->intp_en = 0x0;
|
||||
r->bar_en = 0x0;
|
||||
r->check_bf16_value = 0x0;
|
||||
r->trans_dir = 0x0;
|
||||
r->rsv00 = 0x0;
|
||||
r->trans_fmt = 0x0;
|
||||
r->transpose_md = 0x0;
|
||||
r->rsv01 = 0x0;
|
||||
r->outstanding_en = 0x0;
|
||||
r->cmd_id = 0x0;
|
||||
r->spec_func = 0x0;
|
||||
r->dst_fmt = 0x1;
|
||||
r->src_fmt = 0x1;
|
||||
r->cmprs_fmt = 0x0;
|
||||
r->sys_dtype = 0x0;
|
||||
r->rsv2_1 = 0x0;
|
||||
r->int8_sign = 0x0;
|
||||
r->compress_zero_guard = 0x0;
|
||||
r->int8_rnd_mode = 0x0;
|
||||
r->wait_id_tpu = 0x0;
|
||||
r->wait_id_other_tdma = 0x0;
|
||||
r->wait_id_sdma = 0x0;
|
||||
r->const_val = 0x0;
|
||||
r->src_base_reg_sel = 0x0;
|
||||
r->mv_lut_idx = 0x0;
|
||||
r->dst_base_reg_sel = 0x0;
|
||||
r->mv_lut_base = 0x0;
|
||||
r->rsv4_5 = 0x0;
|
||||
r->dst_h_stride = 0x1;
|
||||
r->dst_c_stride_low = 0x1;
|
||||
r->dst_n_stride = 0x1;
|
||||
r->src_h_stride = 0x1;
|
||||
r->src_c_stride_low = 0x1;
|
||||
r->src_n_stride = 0x1;
|
||||
r->dst_c = 0x1;
|
||||
r->src_c = 0x1;
|
||||
r->dst_w = 0x1;
|
||||
r->dst_h = 0x1;
|
||||
r->src_w = 0x1;
|
||||
r->src_h = 0x1;
|
||||
r->dst_base_addr_low = 0x0;
|
||||
r->src_base_addr_low = 0x0;
|
||||
r->src_n = 0x1;
|
||||
r->dst_base_addr_high = 0x0;
|
||||
r->src_base_addr_high = 0x0;
|
||||
r->src_c_stride_high = 0x0;
|
||||
r->dst_c_stride_high = 0x0;
|
||||
r->compress_bias0 = 0x0;
|
||||
r->compress_bias1 = 0x0;
|
||||
r->layer_ID = 0x0;
|
||||
}
|
||||
|
||||
static inline void trace_tdma_reg(tdma_reg_t *r, const char *tag)
|
||||
{
|
||||
#define trace_one_reg(name) \
|
||||
printf(" %s: 0x%llx\n", #name, (ullong)r->name)
|
||||
|
||||
printf("--- %s ---\n", tag);
|
||||
trace_one_reg(vld);
|
||||
trace_one_reg(compress_en);
|
||||
trace_one_reg(eod);
|
||||
trace_one_reg(intp_en);
|
||||
trace_one_reg(bar_en);
|
||||
trace_one_reg(check_bf16_value);
|
||||
trace_one_reg(trans_dir);
|
||||
trace_one_reg(rsv00);
|
||||
trace_one_reg(trans_fmt);
|
||||
trace_one_reg(transpose_md);
|
||||
trace_one_reg(rsv01);
|
||||
trace_one_reg(outstanding_en);
|
||||
trace_one_reg(cmd_id);
|
||||
trace_one_reg(spec_func);
|
||||
trace_one_reg(dst_fmt);
|
||||
trace_one_reg(src_fmt);
|
||||
trace_one_reg(cmprs_fmt);
|
||||
trace_one_reg(sys_dtype);
|
||||
trace_one_reg(rsv2_1);
|
||||
trace_one_reg(int8_sign);
|
||||
trace_one_reg(compress_zero_guard);
|
||||
trace_one_reg(int8_rnd_mode);
|
||||
trace_one_reg(wait_id_tpu);
|
||||
trace_one_reg(wait_id_other_tdma);
|
||||
trace_one_reg(wait_id_sdma);
|
||||
trace_one_reg(const_val);
|
||||
trace_one_reg(src_base_reg_sel);
|
||||
trace_one_reg(mv_lut_idx);
|
||||
trace_one_reg(dst_base_reg_sel);
|
||||
trace_one_reg(mv_lut_base);
|
||||
trace_one_reg(rsv4_5);
|
||||
trace_one_reg(dst_h_stride);
|
||||
trace_one_reg(dst_c_stride_low);
|
||||
trace_one_reg(dst_n_stride);
|
||||
trace_one_reg(src_h_stride);
|
||||
trace_one_reg(src_c_stride_low);
|
||||
trace_one_reg(src_n_stride);
|
||||
trace_one_reg(dst_c);
|
||||
trace_one_reg(src_c);
|
||||
trace_one_reg(dst_w);
|
||||
trace_one_reg(dst_h);
|
||||
trace_one_reg(src_w);
|
||||
trace_one_reg(src_h);
|
||||
trace_one_reg(dst_base_addr_low);
|
||||
trace_one_reg(src_base_addr_low);
|
||||
trace_one_reg(src_n);
|
||||
trace_one_reg(dst_base_addr_high);
|
||||
trace_one_reg(src_base_addr_high);
|
||||
trace_one_reg(src_c_stride_high);
|
||||
trace_one_reg(dst_c_stride_high);
|
||||
trace_one_reg(compress_bias0);
|
||||
trace_one_reg(compress_bias1);
|
||||
trace_one_reg(layer_ID);
|
||||
}
|
||||
#endif /* BM1880v2_TDMA_REG_V1_32_H */
|
||||
574
cvikernel/include/bmkernel/bm1880v2/bm1880v2_tiu_reg.h
Normal file
574
cvikernel/include/bmkernel/bm1880v2/bm1880v2_tiu_reg.h
Normal file
@ -0,0 +1,574 @@
|
||||
#ifndef BM1880v2_TIU_REG_V2_11_H
|
||||
#define BM1880v2_TIU_REG_V2_11_H
|
||||
|
||||
/*
|
||||
* This file is generated by tools. Do not edit it manually.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef uint8_t uint8_t;
|
||||
typedef uint64_t uint64_t;
|
||||
typedef unsigned long long ullong;
|
||||
|
||||
typedef struct {
|
||||
uint32_t cmd_en;
|
||||
uint32_t cmd_end;
|
||||
uint32_t cmd_id_en;
|
||||
uint32_t cmd_id_tpu;
|
||||
uint32_t cmd_id_gdma;
|
||||
uint32_t cmd_keep;
|
||||
uint32_t cmd_intr_en;
|
||||
uint32_t tsk_typ;
|
||||
uint32_t tsk_eu_typ;
|
||||
uint32_t tsk_opd_num;
|
||||
uint32_t opt_right_shift;
|
||||
uint32_t opt_left_shift;
|
||||
uint32_t opt_shift_typ;
|
||||
uint32_t opt_rshift_typ;
|
||||
uint32_t opt_res_add;
|
||||
uint32_t opt_relu;
|
||||
uint32_t opt_left_tran;
|
||||
uint32_t opt_chl_quan;
|
||||
uint32_t tens_mdsum;
|
||||
uint32_t tens_lookup;
|
||||
uint32_t opt_res0_sign;
|
||||
uint32_t opt_opd0_sign;
|
||||
uint32_t opt_opd1_sign;
|
||||
uint32_t opt_opd2_sign;
|
||||
uint32_t opt_res0_int8;
|
||||
uint32_t opt_opd0_int8;
|
||||
uint32_t opt_opd1_int8;
|
||||
uint32_t opt_opd2_int8;
|
||||
uint32_t opt_opd0_const;
|
||||
uint32_t opt_opd1_const;
|
||||
uint32_t opt_opd2_const;
|
||||
uint32_t short_nchwstr_same;
|
||||
uint32_t short_res0_str;
|
||||
uint32_t short_opd0_str;
|
||||
uint32_t short_opd1_str;
|
||||
uint32_t short_opd2_str;
|
||||
uint32_t conv_opd0_x_ins0;
|
||||
uint32_t conv_opd0_y_ins0;
|
||||
uint32_t conv_opd0_x_ins0_last;
|
||||
uint32_t conv_opd0_y_ins0_last;
|
||||
uint32_t conv_opd1_x_ins0;
|
||||
uint32_t conv_opd1_y_ins0;
|
||||
uint32_t opd0_ins_val;
|
||||
uint32_t ps32_md;
|
||||
uint32_t double_conv;
|
||||
uint32_t rsvd0;
|
||||
uint32_t res0_n;
|
||||
uint32_t res0_c;
|
||||
uint32_t res0_h;
|
||||
uint32_t res0_w;
|
||||
uint32_t res0_addr;
|
||||
uint32_t opd0_addr;
|
||||
uint32_t opd1_addr;
|
||||
uint32_t rsvd1;
|
||||
uint32_t opd2_addr;
|
||||
uint32_t opd0_c;
|
||||
uint32_t opd0_h;
|
||||
uint32_t opd0_w;
|
||||
uint32_t opd1_h;
|
||||
uint32_t opd1_w;
|
||||
uint32_t conv_opd0_up_pad;
|
||||
uint32_t conv_opd0_dn_pad;
|
||||
uint32_t conv_opd0_lf_pad;
|
||||
uint32_t conv_opd0_rt_pad;
|
||||
uint32_t conv_op_x_str;
|
||||
uint32_t conv_op_y_str;
|
||||
uint32_t opd0_ins_fp;
|
||||
uint32_t rsvd2;
|
||||
uint32_t opd0_n;
|
||||
uint32_t opd1_n;
|
||||
uint32_t opd1_c;
|
||||
uint32_t opd2_n;
|
||||
uint32_t opd2_c;
|
||||
uint32_t opd2_h;
|
||||
uint32_t opd2_w;
|
||||
uint32_t quan_m;
|
||||
uint32_t opd_typ;
|
||||
uint32_t fp_round_typ;
|
||||
uint32_t rsvd7;
|
||||
uint32_t rsvd3;
|
||||
uint32_t res0_n_str;
|
||||
uint32_t res0_c_str;
|
||||
uint32_t res0_h_str;
|
||||
uint32_t res0_w_str;
|
||||
uint32_t res0_b_str;
|
||||
uint32_t opd0_n_str;
|
||||
uint32_t opd0_c_str;
|
||||
uint32_t rsvd4;
|
||||
uint32_t opd0_h_str;
|
||||
uint32_t opd0_w_str;
|
||||
uint32_t opd0_b_str;
|
||||
uint32_t opd1_n_str;
|
||||
uint32_t opd1_c_str;
|
||||
uint32_t opd1_h_str;
|
||||
uint32_t opd1_w_str;
|
||||
uint32_t rsvd5;
|
||||
uint32_t opd1_b_str;
|
||||
uint32_t opd2_n_str;
|
||||
uint32_t opd2_c_str;
|
||||
uint32_t opd2_h_str;
|
||||
uint32_t opd2_w_str;
|
||||
uint32_t opd2_b_str;
|
||||
uint32_t layer_info;
|
||||
uint32_t rsvd6;
|
||||
} tiu_reg_t;
|
||||
|
||||
static inline void parse_tiu_reg(tiu_reg_t *r, const uint32_t *p)
|
||||
{
|
||||
r->cmd_en = p[0] & 1;
|
||||
r->cmd_end = (p[0] >> 1) & 1;
|
||||
r->cmd_id_en = (p[0] >> 2) & 1;
|
||||
r->cmd_id_tpu = (p[0] >> 3) & ((1u << 16) - 1);
|
||||
r->cmd_id_gdma = (p[0] >> 19) & ((1u << 13) - 1);
|
||||
r->cmd_id_gdma |= (uint64_t)(p[1] & ((1u << 3) - 1)) << 13;
|
||||
r->cmd_keep = (p[1] >> 3) & 1;
|
||||
r->cmd_intr_en = (p[1] >> 4) & 1;
|
||||
r->tsk_typ = (p[1] >> 5) & ((1u << 4) - 1);
|
||||
r->tsk_eu_typ = (p[1] >> 9) & ((1u << 8) - 1);
|
||||
r->tsk_opd_num = (p[1] >> 17) & ((1u << 2) - 1);
|
||||
r->opt_right_shift = (p[1] >> 19) & ((1u << 5) - 1);
|
||||
r->opt_left_shift = (p[1] >> 24) & ((1u << 5) - 1);
|
||||
r->opt_shift_typ = (p[1] >> 29) & 1;
|
||||
r->opt_rshift_typ = (p[1] >> 30) & 1;
|
||||
r->opt_res_add = (p[1] >> 31) & 1;
|
||||
r->opt_relu = p[2] & 1;
|
||||
r->opt_left_tran = (p[2] >> 1) & 1;
|
||||
r->opt_chl_quan = (p[2] >> 2) & 1;
|
||||
r->tens_mdsum = (p[2] >> 3) & 1;
|
||||
r->tens_lookup = (p[2] >> 4) & 1;
|
||||
r->opt_res0_sign = (p[2] >> 5) & 1;
|
||||
r->opt_opd0_sign = (p[2] >> 6) & 1;
|
||||
r->opt_opd1_sign = (p[2] >> 7) & 1;
|
||||
r->opt_opd2_sign = (p[2] >> 8) & 1;
|
||||
r->opt_res0_int8 = (p[2] >> 9) & 1;
|
||||
r->opt_opd0_int8 = (p[2] >> 10) & 1;
|
||||
r->opt_opd1_int8 = (p[2] >> 11) & 1;
|
||||
r->opt_opd2_int8 = (p[2] >> 12) & 1;
|
||||
r->opt_opd0_const = (p[2] >> 13) & 1;
|
||||
r->opt_opd1_const = (p[2] >> 14) & 1;
|
||||
r->opt_opd2_const = (p[2] >> 15) & 1;
|
||||
r->short_nchwstr_same = (p[2] >> 16) & 1;
|
||||
r->short_res0_str = (p[2] >> 17) & ((1u << 2) - 1);
|
||||
r->short_opd0_str = (p[2] >> 19) & ((1u << 2) - 1);
|
||||
r->short_opd1_str = (p[2] >> 21) & ((1u << 2) - 1);
|
||||
r->short_opd2_str = (p[2] >> 23) & ((1u << 2) - 1);
|
||||
r->conv_opd0_x_ins0 = (p[2] >> 25) & ((1u << 4) - 1);
|
||||
r->conv_opd0_y_ins0 = (p[2] >> 29) & ((1u << 3) - 1);
|
||||
r->conv_opd0_y_ins0 |= (uint64_t)(p[3] & 1) << 3;
|
||||
r->conv_opd0_x_ins0_last = (p[3] >> 1) & ((1u << 4) - 1);
|
||||
r->conv_opd0_y_ins0_last = (p[3] >> 5) & ((1u << 4) - 1);
|
||||
r->conv_opd1_x_ins0 = (p[3] >> 9) & ((1u << 4) - 1);
|
||||
r->conv_opd1_y_ins0 = (p[3] >> 13) & ((1u << 4) - 1);
|
||||
r->opd0_ins_val = (p[3] >> 17) & ((1u << 8) - 1);
|
||||
r->ps32_md = (p[3] >> 25) & ((1u << 2) - 1);
|
||||
r->double_conv = (p[3] >> 27) & 1;
|
||||
r->rsvd0 = (p[3] >> 28) & ((1u << 4) - 1);
|
||||
r->res0_n = p[4] & ((1u << 12) - 1);
|
||||
r->res0_c = (p[4] >> 12) & ((1u << 12) - 1);
|
||||
r->res0_h = (p[4] >> 24) & ((1u << 8) - 1);
|
||||
r->res0_h |= (uint64_t)(p[5] & ((1u << 4) - 1)) << 8;
|
||||
r->res0_w = (p[5] >> 4) & ((1u << 12) - 1);
|
||||
r->res0_addr = (p[5] >> 16) & ((1u << 16) - 1);
|
||||
r->res0_addr |= (uint64_t)(p[6] & ((1u << 8) - 1)) << 16;
|
||||
r->opd0_addr = (p[6] >> 8) & ((1u << 24) - 1);
|
||||
r->opd1_addr = p[7] & ((1u << 16) - 1);
|
||||
r->rsvd1 = (p[7] >> 16) & ((1u << 16) - 1);
|
||||
r->opd2_addr = p[8] & ((1u << 16) - 1);
|
||||
r->opd0_c = (p[8] >> 16) & ((1u << 12) - 1);
|
||||
r->opd0_h = (p[8] >> 28) & ((1u << 4) - 1);
|
||||
r->opd0_h |= (uint64_t)(p[9] & ((1u << 8) - 1)) << 4;
|
||||
r->opd0_w = (p[9] >> 8) & ((1u << 12) - 1);
|
||||
r->opd1_h = (p[9] >> 20) & ((1u << 12) - 1);
|
||||
r->opd1_w = p[10] & ((1u << 12) - 1);
|
||||
r->conv_opd0_up_pad = (p[10] >> 12) & ((1u << 4) - 1);
|
||||
r->conv_opd0_dn_pad = (p[10] >> 16) & ((1u << 4) - 1);
|
||||
r->conv_opd0_lf_pad = (p[10] >> 20) & ((1u << 4) - 1);
|
||||
r->conv_opd0_rt_pad = (p[10] >> 24) & ((1u << 4) - 1);
|
||||
r->conv_op_x_str = (p[10] >> 28) & ((1u << 4) - 1);
|
||||
r->conv_op_y_str = p[11] & ((1u << 4) - 1);
|
||||
r->opd0_ins_fp = (p[11] >> 4) & ((1u << 16) - 1);
|
||||
r->rsvd2 = (p[11] >> 20) & ((1u << 12) - 1);
|
||||
r->opd0_n = p[12] & ((1u << 12) - 1);
|
||||
r->opd1_n = (p[12] >> 12) & ((1u << 12) - 1);
|
||||
r->opd1_c = (p[12] >> 24) & ((1u << 8) - 1);
|
||||
r->opd1_c |= (uint64_t)(p[13] & ((1u << 4) - 1)) << 8;
|
||||
r->opd2_n = (p[13] >> 4) & ((1u << 12) - 1);
|
||||
r->opd2_c = (p[13] >> 16) & ((1u << 12) - 1);
|
||||
r->opd2_h = (p[13] >> 28) & ((1u << 4) - 1);
|
||||
r->opd2_h |= (uint64_t)(p[14] & ((1u << 8) - 1)) << 4;
|
||||
r->opd2_w = (p[14] >> 8) & ((1u << 12) - 1);
|
||||
r->quan_m = (p[14] >> 20) & ((1u << 12) - 1);
|
||||
r->quan_m |= (uint64_t)(p[15] & ((1u << 20) - 1)) << 12;
|
||||
r->opd_typ = (p[15] >> 20) & 1;
|
||||
r->fp_round_typ = (p[15] >> 21) & ((1u << 3) - 1);
|
||||
r->rsvd7 = (p[15] >> 24) & ((1u << 4) - 1);
|
||||
r->rsvd3 = (p[15] >> 28) & ((1u << 4) - 1);
|
||||
r->res0_n_str = p[16] & ((1u << 16) - 1);
|
||||
r->res0_c_str = (p[16] >> 16) & ((1u << 16) - 1);
|
||||
r->res0_h_str = p[17] & ((1u << 16) - 1);
|
||||
r->res0_w_str = (p[17] >> 16) & ((1u << 16) - 1);
|
||||
r->res0_b_str = p[18] & ((1u << 16) - 1);
|
||||
r->opd0_n_str = (p[18] >> 16) & ((1u << 16) - 1);
|
||||
r->opd0_c_str = p[19] & ((1u << 16) - 1);
|
||||
r->rsvd4 = (p[19] >> 16) & ((1u << 16) - 1);
|
||||
r->opd0_h_str = p[20] & ((1u << 16) - 1);
|
||||
r->opd0_w_str = (p[20] >> 16) & ((1u << 16) - 1);
|
||||
r->opd0_b_str = p[21] & ((1u << 16) - 1);
|
||||
r->opd1_n_str = (p[21] >> 16) & ((1u << 16) - 1);
|
||||
r->opd1_c_str = p[22] & ((1u << 16) - 1);
|
||||
r->opd1_h_str = (p[22] >> 16) & ((1u << 16) - 1);
|
||||
r->opd1_w_str = p[23] & ((1u << 16) - 1);
|
||||
r->rsvd5 = (p[23] >> 16) & ((1u << 16) - 1);
|
||||
r->opd1_b_str = p[24] & ((1u << 16) - 1);
|
||||
r->opd2_n_str = (p[24] >> 16) & ((1u << 16) - 1);
|
||||
r->opd2_c_str = p[25] & ((1u << 16) - 1);
|
||||
r->opd2_h_str = (p[25] >> 16) & ((1u << 16) - 1);
|
||||
r->opd2_w_str = p[26] & ((1u << 16) - 1);
|
||||
r->opd2_b_str = (p[26] >> 16) & ((1u << 16) - 1);
|
||||
r->layer_info = p[27] & ((1u << 28) - 1);
|
||||
r->rsvd6 = (p[27] >> 28) & ((1u << 4) - 1);
|
||||
}
|
||||
|
||||
static inline void emit_tiu_reg(const tiu_reg_t *r, uint32_t *_p)
|
||||
{
|
||||
volatile uint32_t *p = (typeof(p))_p;
|
||||
p[27] = (r->layer_info & ((1u << 28) - 1)) |
|
||||
((r->rsvd6 & ((1u << 4) - 1)) << 28);
|
||||
p[26] = (r->opd2_w_str & ((1u << 16) - 1)) |
|
||||
((r->opd2_b_str & ((1u << 16) - 1)) << 16);
|
||||
p[25] = (r->opd2_c_str & ((1u << 16) - 1)) |
|
||||
((r->opd2_h_str & ((1u << 16) - 1)) << 16);
|
||||
p[24] = (r->opd1_b_str & ((1u << 16) - 1)) |
|
||||
((r->opd2_n_str & ((1u << 16) - 1)) << 16);
|
||||
p[23] = (r->opd1_w_str & ((1u << 16) - 1)) |
|
||||
((r->rsvd5 & ((1u << 16) - 1)) << 16);
|
||||
p[22] = (r->opd1_c_str & ((1u << 16) - 1)) |
|
||||
((r->opd1_h_str & ((1u << 16) - 1)) << 16);
|
||||
p[21] = (r->opd0_b_str & ((1u << 16) - 1)) |
|
||||
((r->opd1_n_str & ((1u << 16) - 1)) << 16);
|
||||
p[20] = (r->opd0_h_str & ((1u << 16) - 1)) |
|
||||
((r->opd0_w_str & ((1u << 16) - 1)) << 16);
|
||||
p[19] = (r->opd0_c_str & ((1u << 16) - 1)) |
|
||||
((r->rsvd4 & ((1u << 16) - 1)) << 16);
|
||||
p[18] = (r->res0_b_str & ((1u << 16) - 1)) |
|
||||
((r->opd0_n_str & ((1u << 16) - 1)) << 16);
|
||||
p[17] = (r->res0_h_str & ((1u << 16) - 1)) |
|
||||
((r->res0_w_str & ((1u << 16) - 1)) << 16);
|
||||
p[16] = (r->res0_n_str & ((1u << 16) - 1)) |
|
||||
((r->res0_c_str & ((1u << 16) - 1)) << 16);
|
||||
p[15] = ((r->quan_m >> 12) & ((1u << 20) - 1)) |
|
||||
((r->opd_typ & 1) << 20) |
|
||||
((r->fp_round_typ & ((1u << 3) - 1)) << 21) |
|
||||
((r->rsvd7 & ((1u << 4) - 1)) << 24) |
|
||||
((r->rsvd3 & ((1u << 4) - 1)) << 28);
|
||||
p[14] = ((r->opd2_h >> 4) & ((1u << 8) - 1)) |
|
||||
((r->opd2_w & ((1u << 12) - 1)) << 8) |
|
||||
((r->quan_m & ((1u << 12) - 1)) << 20);
|
||||
p[13] = ((r->opd1_c >> 8) & ((1u << 4) - 1)) |
|
||||
((r->opd2_n & ((1u << 12) - 1)) << 4) |
|
||||
((r->opd2_c & ((1u << 12) - 1)) << 16) |
|
||||
((r->opd2_h & ((1u << 4) - 1)) << 28);
|
||||
p[12] = (r->opd0_n & ((1u << 12) - 1)) |
|
||||
((r->opd1_n & ((1u << 12) - 1)) << 12) |
|
||||
((r->opd1_c & ((1u << 8) - 1)) << 24);
|
||||
p[11] = (r->conv_op_y_str & ((1u << 4) - 1)) |
|
||||
((r->opd0_ins_fp & ((1u << 16) - 1)) << 4) |
|
||||
((r->rsvd2 & ((1u << 12) - 1)) << 20);
|
||||
p[10] = (r->opd1_w & ((1u << 12) - 1)) |
|
||||
((r->conv_opd0_up_pad & ((1u << 4) - 1)) << 12) |
|
||||
((r->conv_opd0_dn_pad & ((1u << 4) - 1)) << 16) |
|
||||
((r->conv_opd0_lf_pad & ((1u << 4) - 1)) << 20) |
|
||||
((r->conv_opd0_rt_pad & ((1u << 4) - 1)) << 24) |
|
||||
((r->conv_op_x_str & ((1u << 4) - 1)) << 28);
|
||||
p[9] = ((r->opd0_h >> 4) & ((1u << 8) - 1)) |
|
||||
((r->opd0_w & ((1u << 12) - 1)) << 8) |
|
||||
((r->opd1_h & ((1u << 12) - 1)) << 20);
|
||||
p[8] = (r->opd2_addr & ((1u << 16) - 1)) |
|
||||
((r->opd0_c & ((1u << 12) - 1)) << 16) |
|
||||
((r->opd0_h & ((1u << 4) - 1)) << 28);
|
||||
p[7] = (r->opd1_addr & ((1u << 16) - 1)) |
|
||||
((r->rsvd1 & ((1u << 16) - 1)) << 16);
|
||||
p[6] = ((r->res0_addr >> 16) & ((1u << 8) - 1)) |
|
||||
((r->opd0_addr & ((1u << 24) - 1)) << 8);
|
||||
p[5] = ((r->res0_h >> 8) & ((1u << 4) - 1)) |
|
||||
((r->res0_w & ((1u << 12) - 1)) << 4) |
|
||||
((r->res0_addr & ((1u << 16) - 1)) << 16);
|
||||
p[4] = (r->res0_n & ((1u << 12) - 1)) |
|
||||
((r->res0_c & ((1u << 12) - 1)) << 12) |
|
||||
((r->res0_h & ((1u << 8) - 1)) << 24);
|
||||
p[3] = ((r->conv_opd0_y_ins0 >> 3) & 1) |
|
||||
((r->conv_opd0_x_ins0_last & ((1u << 4) - 1)) << 1) |
|
||||
((r->conv_opd0_y_ins0_last & ((1u << 4) - 1)) << 5) |
|
||||
((r->conv_opd1_x_ins0 & ((1u << 4) - 1)) << 9) |
|
||||
((r->conv_opd1_y_ins0 & ((1u << 4) - 1)) << 13) |
|
||||
((r->opd0_ins_val & ((1u << 8) - 1)) << 17) |
|
||||
((r->ps32_md & ((1u << 2) - 1)) << 25) |
|
||||
((r->double_conv & 1) << 27) |
|
||||
((r->rsvd0 & ((1u << 4) - 1)) << 28);
|
||||
p[2] = (r->opt_relu & 1) |
|
||||
((r->opt_left_tran & 1) << 1) |
|
||||
((r->opt_chl_quan & 1) << 2) |
|
||||
((r->tens_mdsum & 1) << 3) |
|
||||
((r->tens_lookup & 1) << 4) |
|
||||
((r->opt_res0_sign & 1) << 5) |
|
||||
((r->opt_opd0_sign & 1) << 6) |
|
||||
((r->opt_opd1_sign & 1) << 7) |
|
||||
((r->opt_opd2_sign & 1) << 8) |
|
||||
((r->opt_res0_int8 & 1) << 9) |
|
||||
((r->opt_opd0_int8 & 1) << 10) |
|
||||
((r->opt_opd1_int8 & 1) << 11) |
|
||||
((r->opt_opd2_int8 & 1) << 12) |
|
||||
((r->opt_opd0_const & 1) << 13) |
|
||||
((r->opt_opd1_const & 1) << 14) |
|
||||
((r->opt_opd2_const & 1) << 15) |
|
||||
((r->short_nchwstr_same & 1) << 16) |
|
||||
((r->short_res0_str & ((1u << 2) - 1)) << 17) |
|
||||
((r->short_opd0_str & ((1u << 2) - 1)) << 19) |
|
||||
((r->short_opd1_str & ((1u << 2) - 1)) << 21) |
|
||||
((r->short_opd2_str & ((1u << 2) - 1)) << 23) |
|
||||
((r->conv_opd0_x_ins0 & ((1u << 4) - 1)) << 25) |
|
||||
((r->conv_opd0_y_ins0 & ((1u << 3) - 1)) << 29);
|
||||
p[1] = ((r->cmd_id_gdma >> 13) & ((1u << 3) - 1)) |
|
||||
((r->cmd_keep & 1) << 3) |
|
||||
((r->cmd_intr_en & 1) << 4) |
|
||||
((r->tsk_typ & ((1u << 4) - 1)) << 5) |
|
||||
((r->tsk_eu_typ & ((1u << 8) - 1)) << 9) |
|
||||
((r->tsk_opd_num & ((1u << 2) - 1)) << 17) |
|
||||
((r->opt_right_shift & ((1u << 5) - 1)) << 19) |
|
||||
((r->opt_left_shift & ((1u << 5) - 1)) << 24) |
|
||||
((r->opt_shift_typ & 1) << 29) |
|
||||
((r->opt_rshift_typ & 1) << 30) |
|
||||
((r->opt_res_add & 1) << 31);
|
||||
p[0] = (r->cmd_en & 1) |
|
||||
((r->cmd_end & 1) << 1) |
|
||||
((r->cmd_id_en & 1) << 2) |
|
||||
((r->cmd_id_tpu & ((1u << 16) - 1)) << 3) |
|
||||
((r->cmd_id_gdma & ((1u << 13) - 1)) << 19);
|
||||
}
|
||||
|
||||
static inline void reset_tiu_reg(tiu_reg_t *r)
|
||||
{
|
||||
r->cmd_en = 0b0;
|
||||
r->cmd_end = 0b0;
|
||||
r->cmd_id_en = 0b0;
|
||||
r->cmd_id_tpu = 0;
|
||||
r->cmd_id_gdma = 0;
|
||||
r->cmd_keep = 0b0;
|
||||
r->cmd_intr_en = 0b0;
|
||||
r->tsk_typ = 0;
|
||||
r->tsk_eu_typ = 0;
|
||||
r->tsk_opd_num = 0b11;
|
||||
r->opt_right_shift = 10;
|
||||
r->opt_left_shift = 2;
|
||||
r->opt_shift_typ = 0b1;
|
||||
r->opt_rshift_typ = 0b1;
|
||||
r->opt_res_add = 0b0;
|
||||
r->opt_relu = 0b1;
|
||||
r->opt_left_tran = 0b0;
|
||||
r->opt_chl_quan = 0b0;
|
||||
r->tens_mdsum = 0b0;
|
||||
r->tens_lookup = 0b0;
|
||||
r->opt_res0_sign = 0b0;
|
||||
r->opt_opd0_sign = 0b0;
|
||||
r->opt_opd1_sign = 0b1;
|
||||
r->opt_opd2_sign = 0b1;
|
||||
r->opt_res0_int8 = 0b1;
|
||||
r->opt_opd0_int8 = 0b1;
|
||||
r->opt_opd1_int8 = 0b1;
|
||||
r->opt_opd2_int8 = 0b0;
|
||||
r->opt_opd0_const = 0b0;
|
||||
r->opt_opd1_const = 0b0;
|
||||
r->opt_opd2_const = 0b0;
|
||||
r->short_nchwstr_same = 0b0;
|
||||
r->short_res0_str = 0b00;
|
||||
r->short_opd0_str = 0b00;
|
||||
r->short_opd1_str = 0b00;
|
||||
r->short_opd2_str = 0b00;
|
||||
r->conv_opd0_x_ins0 = 0;
|
||||
r->conv_opd0_y_ins0 = 0;
|
||||
r->conv_opd0_x_ins0_last = 0;
|
||||
r->conv_opd0_y_ins0_last = 0;
|
||||
r->conv_opd1_x_ins0 = 0;
|
||||
r->conv_opd1_y_ins0 = 0;
|
||||
r->opd0_ins_val = 0;
|
||||
r->ps32_md = 0;
|
||||
r->double_conv = 0;
|
||||
r->rsvd0 = 0;
|
||||
r->res0_n = 1;
|
||||
r->res0_c = 1;
|
||||
r->res0_h = 1;
|
||||
r->res0_w = 16;
|
||||
r->res0_addr = 0;
|
||||
r->opd0_addr = 0;
|
||||
r->opd1_addr = 0;
|
||||
r->rsvd1 = 0;
|
||||
r->opd2_addr = 0;
|
||||
r->opd0_c = 1;
|
||||
r->opd0_h = 1;
|
||||
r->opd0_w = 16;
|
||||
r->opd1_h = 1;
|
||||
r->opd1_w = 16;
|
||||
r->conv_opd0_up_pad = 0;
|
||||
r->conv_opd0_dn_pad = 0;
|
||||
r->conv_opd0_lf_pad = 0;
|
||||
r->conv_opd0_rt_pad = 0;
|
||||
r->conv_op_x_str = 1;
|
||||
r->conv_op_y_str = 1;
|
||||
r->opd0_ins_fp = 0;
|
||||
r->rsvd2 = 0;
|
||||
r->opd0_n = 1;
|
||||
r->opd1_n = 1;
|
||||
r->opd1_c = 1;
|
||||
r->opd2_n = 1;
|
||||
r->opd2_c = 1;
|
||||
r->opd2_h = 1;
|
||||
r->opd2_w = 16;
|
||||
r->quan_m = 0;
|
||||
r->opd_typ = 0;
|
||||
r->fp_round_typ = 0;
|
||||
r->rsvd7 = 0;
|
||||
r->rsvd3 = 0;
|
||||
r->res0_n_str = 16;
|
||||
r->res0_c_str = 16;
|
||||
r->res0_h_str = 0;
|
||||
r->res0_w_str = 1;
|
||||
r->res0_b_str = 16;
|
||||
r->opd0_n_str = 16;
|
||||
r->opd0_c_str = 16;
|
||||
r->rsvd4 = 0;
|
||||
r->opd0_h_str = 0;
|
||||
r->opd0_w_str = 1;
|
||||
r->opd0_b_str = 16;
|
||||
r->opd1_n_str = 16;
|
||||
r->opd1_c_str = 16;
|
||||
r->opd1_h_str = 0;
|
||||
r->opd1_w_str = 1;
|
||||
r->rsvd5 = 0;
|
||||
r->opd1_b_str = 16;
|
||||
r->opd2_n_str = 16;
|
||||
r->opd2_c_str = 16;
|
||||
r->opd2_h_str = 0;
|
||||
r->opd2_w_str = 1;
|
||||
r->opd2_b_str = 16;
|
||||
r->layer_info = 0;
|
||||
r->rsvd6 = 0;
|
||||
}
|
||||
|
||||
static inline void trace_tiu_reg(tiu_reg_t *r, const char *tag)
|
||||
{
|
||||
#define trace_one_reg(name) \
|
||||
printf(" %s: 0x%llx\n", #name, (ullong)r->name)
|
||||
|
||||
printf("--- %s ---\n", tag);
|
||||
trace_one_reg(cmd_en);
|
||||
trace_one_reg(cmd_end);
|
||||
trace_one_reg(cmd_id_en);
|
||||
trace_one_reg(cmd_id_tpu);
|
||||
trace_one_reg(cmd_id_gdma);
|
||||
trace_one_reg(cmd_keep);
|
||||
trace_one_reg(cmd_intr_en);
|
||||
trace_one_reg(tsk_typ);
|
||||
trace_one_reg(tsk_eu_typ);
|
||||
trace_one_reg(tsk_opd_num);
|
||||
trace_one_reg(opt_right_shift);
|
||||
trace_one_reg(opt_left_shift);
|
||||
trace_one_reg(opt_shift_typ);
|
||||
trace_one_reg(opt_rshift_typ);
|
||||
trace_one_reg(opt_res_add);
|
||||
trace_one_reg(opt_relu);
|
||||
trace_one_reg(opt_left_tran);
|
||||
trace_one_reg(opt_chl_quan);
|
||||
trace_one_reg(tens_mdsum);
|
||||
trace_one_reg(tens_lookup);
|
||||
trace_one_reg(opt_res0_sign);
|
||||
trace_one_reg(opt_opd0_sign);
|
||||
trace_one_reg(opt_opd1_sign);
|
||||
trace_one_reg(opt_opd2_sign);
|
||||
trace_one_reg(opt_res0_int8);
|
||||
trace_one_reg(opt_opd0_int8);
|
||||
trace_one_reg(opt_opd1_int8);
|
||||
trace_one_reg(opt_opd2_int8);
|
||||
trace_one_reg(opt_opd0_const);
|
||||
trace_one_reg(opt_opd1_const);
|
||||
trace_one_reg(opt_opd2_const);
|
||||
trace_one_reg(short_nchwstr_same);
|
||||
trace_one_reg(short_res0_str);
|
||||
trace_one_reg(short_opd0_str);
|
||||
trace_one_reg(short_opd1_str);
|
||||
trace_one_reg(short_opd2_str);
|
||||
trace_one_reg(conv_opd0_x_ins0);
|
||||
trace_one_reg(conv_opd0_y_ins0);
|
||||
trace_one_reg(conv_opd0_x_ins0_last);
|
||||
trace_one_reg(conv_opd0_y_ins0_last);
|
||||
trace_one_reg(conv_opd1_x_ins0);
|
||||
trace_one_reg(conv_opd1_y_ins0);
|
||||
trace_one_reg(opd0_ins_val);
|
||||
trace_one_reg(ps32_md);
|
||||
trace_one_reg(double_conv);
|
||||
trace_one_reg(rsvd0);
|
||||
trace_one_reg(res0_n);
|
||||
trace_one_reg(res0_c);
|
||||
trace_one_reg(res0_h);
|
||||
trace_one_reg(res0_w);
|
||||
trace_one_reg(res0_addr);
|
||||
trace_one_reg(opd0_addr);
|
||||
trace_one_reg(opd1_addr);
|
||||
trace_one_reg(rsvd1);
|
||||
trace_one_reg(opd2_addr);
|
||||
trace_one_reg(opd0_c);
|
||||
trace_one_reg(opd0_h);
|
||||
trace_one_reg(opd0_w);
|
||||
trace_one_reg(opd1_h);
|
||||
trace_one_reg(opd1_w);
|
||||
trace_one_reg(conv_opd0_up_pad);
|
||||
trace_one_reg(conv_opd0_dn_pad);
|
||||
trace_one_reg(conv_opd0_lf_pad);
|
||||
trace_one_reg(conv_opd0_rt_pad);
|
||||
trace_one_reg(conv_op_x_str);
|
||||
trace_one_reg(conv_op_y_str);
|
||||
trace_one_reg(opd0_ins_fp);
|
||||
trace_one_reg(rsvd2);
|
||||
trace_one_reg(opd0_n);
|
||||
trace_one_reg(opd1_n);
|
||||
trace_one_reg(opd1_c);
|
||||
trace_one_reg(opd2_n);
|
||||
trace_one_reg(opd2_c);
|
||||
trace_one_reg(opd2_h);
|
||||
trace_one_reg(opd2_w);
|
||||
trace_one_reg(quan_m);
|
||||
trace_one_reg(opd_typ);
|
||||
trace_one_reg(fp_round_typ);
|
||||
trace_one_reg(rsvd7);
|
||||
trace_one_reg(rsvd3);
|
||||
trace_one_reg(res0_n_str);
|
||||
trace_one_reg(res0_c_str);
|
||||
trace_one_reg(res0_h_str);
|
||||
trace_one_reg(res0_w_str);
|
||||
trace_one_reg(res0_b_str);
|
||||
trace_one_reg(opd0_n_str);
|
||||
trace_one_reg(opd0_c_str);
|
||||
trace_one_reg(rsvd4);
|
||||
trace_one_reg(opd0_h_str);
|
||||
trace_one_reg(opd0_w_str);
|
||||
trace_one_reg(opd0_b_str);
|
||||
trace_one_reg(opd1_n_str);
|
||||
trace_one_reg(opd1_c_str);
|
||||
trace_one_reg(opd1_h_str);
|
||||
trace_one_reg(opd1_w_str);
|
||||
trace_one_reg(rsvd5);
|
||||
trace_one_reg(opd1_b_str);
|
||||
trace_one_reg(opd2_n_str);
|
||||
trace_one_reg(opd2_c_str);
|
||||
trace_one_reg(opd2_h_str);
|
||||
trace_one_reg(opd2_w_str);
|
||||
trace_one_reg(opd2_b_str);
|
||||
trace_one_reg(layer_info);
|
||||
trace_one_reg(rsvd6);
|
||||
}
|
||||
#endif /* BM1880v2_TIU_REG_V2_11_H */
|
||||
37
cvikernel/include/bmkernel/bm1880v2/bm1880v2_tpu_cfg.h
Normal file
37
cvikernel/include/bmkernel/bm1880v2/bm1880v2_tpu_cfg.h
Normal file
@ -0,0 +1,37 @@
|
||||
#ifndef __BM1880V2_TPU_CFG__
|
||||
#define __BM1880V2_TPU_CFG__
|
||||
|
||||
#define BM1880V2_VER 18802
|
||||
#define BM1880V2_HW_NPU_SHIFT 5
|
||||
#define BM1880V2_HW_EU_SHIFT 4
|
||||
#define BM1880V2_HW_LMEM_SHIFT 15
|
||||
#define BM1880V2_HW_LMEM_BANKS 8
|
||||
#define BM1880V2_HW_LMEM_BANK_SIZE 0x1000
|
||||
#define BM1880V2_HW_NODE_CHIP_SHIFT 0
|
||||
#define BM1880V2_HW_NPU_NUM (1 << BM1880V2_HW_NPU_SHIFT)
|
||||
#define BM1880V2_HW_EU_NUM (1 << BM1880V2_HW_EU_SHIFT)
|
||||
#define BM1880V2_HW_LMEM_SIZE (1 << BM1880V2_HW_LMEM_SHIFT)
|
||||
#define BM1880V2_HW_NODE_CHIP_NUM (1 << BM1880V2_HW_NODE_CHIP_SHIFT)
|
||||
|
||||
#if (BM1880V2_HW_LMEM_SIZE != (BM1880V2_HW_LMEM_BANK_SIZE * BM1880V2_HW_LMEM_BANKS))
|
||||
#error "Set wrong TPU configuraiton."
|
||||
#endif
|
||||
|
||||
#define BM1880V2_GLOBAL_MEM_START_ADDR 0x100000000
|
||||
#define BM1880V2_GLOBAL_MEM_SIZE 0x100000000
|
||||
|
||||
#define BM1880V2_GLOBAL_TIU_CMDBUF_ADDR 0x00000000
|
||||
#define BM1880V2_GLOBAL_TDMA_CMDBUF_ADDR 0x01400000
|
||||
#define BM1880V2_GLOBAL_TIU_CMDBUF_RESERVED_SIZE 0x01400000
|
||||
#define BM1880V2_GLOBAL_TDMA_CMDBUF_RESERVED_SIZE 0x01400000
|
||||
#define BM1880V2_GLOBAL_POOL_RESERVED_SIZE (BM1880V2_GLOBAL_MEM_SIZE - BM1880V2_GLOBAL_TIU_CMDBUF_RESERVED_SIZE - BM1880V2_GLOBAL_TDMA_CMDBUF_RESERVED_SIZE)
|
||||
|
||||
#define BM1880V2_UART_CTLR_BASE_ADDR 0x04140000
|
||||
|
||||
#define BM1880V2_TDMA_ENGINE_BASE_ADDR 0x0C100000
|
||||
#define BM1880V2_TDMA_ENGINE_END_ADDR (BM1880V2_TDMA_ENGINE_BASE_ADDR + 0x1000)
|
||||
|
||||
#define BM1880V2_TIU_ENGINE_BASE_ADDR 0x0C101000 //"NPS Register" in memory map?
|
||||
#define BM1880V2_TIU_ENGINE_END_ADDR (BM1880V2_TIU_ENGINE_BASE_ADDR + 0x1000)
|
||||
|
||||
#endif
|
||||
708
cvikernel/include/bmkernel/bm1880v2/bm_vlc_compress.h
Normal file
708
cvikernel/include/bmkernel/bm1880v2/bm_vlc_compress.h
Normal file
@ -0,0 +1,708 @@
|
||||
#ifndef __BM_VLC_COMPRESS_H__
|
||||
#define __BM_VLC_COMPRESS_H__
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define MAX_UNARY_FIELD_SIZE 47
|
||||
#define MAX_ORDER_K 5
|
||||
|
||||
/**
|
||||
* \data_type 0 means 8bit, 1 means 16bit
|
||||
*/
|
||||
static inline size_t get_out_bs_buf_size(uint64_t in_size, uint8_t data_type) {
|
||||
size_t blk_num = (data_type) ? ((in_size + 31) >> 5) : ((in_size + 15) >> 4);
|
||||
size_t in_size_pad = blk_num << (4 + data_type);
|
||||
size_t bs_buf_size = in_size_pad + (ceiling_func(blk_num, 16) << 4) + 16;
|
||||
return bs_buf_size;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t signedness;
|
||||
uint8_t is_bfloat16;
|
||||
uint8_t bias0;
|
||||
uint8_t bias1;
|
||||
uint8_t zero_guard_en;
|
||||
} CommandInfo;
|
||||
typedef struct
|
||||
{
|
||||
uint8_t *stream; // stream buffer pointer
|
||||
int bit_pos; // current pointer (in bit)
|
||||
int buf_size; // in byte
|
||||
} StreamBuffer;
|
||||
|
||||
static inline int8_t two_side_circular_shift(int8_t val, uint8_t bias0, uint8_t bias1);
|
||||
static inline int8_t inv_two_side_circular_shift(int8_t val, uint8_t bias0, uint8_t bias1);
|
||||
static inline uint8_t center_shift(uint8_t val, uint8_t bias, uint8_t zero_guard);
|
||||
static inline uint8_t inv_center_shift(uint8_t val, uint8_t bias, uint8_t zero_guard);
|
||||
|
||||
static inline void init_stream(StreamBuffer *bs, const uint8_t *buf, int buf_size, uint8_t read_only);
|
||||
|
||||
static inline void bm_vlc_est_weight_bias(const uint8_t *ibuf, size_t isz, uint8_t signedness, uint8_t isBfloat16, CommandInfo *cmd_info);
|
||||
static inline void bm_vlc_enc_int8(const uint8_t *ibuf, size_t isz, uint8_t *obuf, size_t *osz, CommandInfo *cmd_info);
|
||||
static inline void bm_vlc_dec_int8_ext(const uint8_t *ibuf, size_t isz, uint8_t *obuf, size_t *bs_size);
|
||||
static inline void bm_vlc_dec_int8(const uint8_t *ibuf, size_t isz, uint8_t *obuf);
|
||||
static inline void bm_vlc_enc_bf16(const uint16_t *ibuf, size_t isz, uint8_t *obuf, size_t *osz, CommandInfo *cmd_info);
|
||||
static inline void bm_vlc_dec_bf16_ext(const uint8_t *ibuf, size_t isz, uint16_t *obuf, size_t *bs_size);
|
||||
static inline void bm_vlc_dec_bf16(const uint8_t *ibuf, size_t isz, uint16_t *obuf);
|
||||
|
||||
static inline uint8_t get_bit_val(uint8_t *buf, int byte_idx, int bit_idx)
|
||||
{
|
||||
return (buf[byte_idx] >> bit_idx) & 0x1;
|
||||
}
|
||||
|
||||
static inline uint8_t sign_to_unsign(uint8_t val)
|
||||
{
|
||||
uint8_t sign_i = (val >> 7) & 0x1;
|
||||
int abs_data_i = abs(((int8_t)val));
|
||||
return ((abs_data_i << 1) - sign_i);
|
||||
}
|
||||
|
||||
static inline int8_t unsign_to_sign(uint8_t val)
|
||||
{
|
||||
uint8_t sign_i = val & 0x1;
|
||||
int abs_data_i = (((int)val) + 1) >> 1;
|
||||
return (uint8_t)((sign_i == 1) ? (-abs_data_i) : abs_data_i);
|
||||
}
|
||||
|
||||
static inline void dispatch_bf16_data(const uint16_t *bf16_in, uint8_t *exp, uint8_t *frac, size_t isz)
|
||||
{
|
||||
for (size_t i = 0; i < isz; i++)
|
||||
{
|
||||
exp[i] = (uint8_t)((bf16_in[i] >> 7) & 0xFF);
|
||||
frac[i] = (uint8_t)(((bf16_in[i] >> 15) << 7) | (bf16_in[i] & 0x7F));
|
||||
}
|
||||
}
|
||||
|
||||
static inline void merge_bf16_data(const uint8_t *exp_in, const uint8_t *frac_in, uint16_t *bf16_out, size_t isz)
|
||||
{
|
||||
memset(bf16_out, 0, sizeof(uint16_t));
|
||||
for (size_t i = 0; i < isz; i++)
|
||||
{
|
||||
bf16_out[i] = ((frac_in[i] >> 7) << 15) | (exp_in[i] << 7) | (frac_in[i] & 0x7F);
|
||||
}
|
||||
}
|
||||
|
||||
// -- streaming operation handler --
|
||||
static inline void init_stream(StreamBuffer *bs, const uint8_t *buf, int buf_size, uint8_t read_only)
|
||||
{
|
||||
bs->bit_pos = 0;
|
||||
bs->stream = (uint8_t *)buf;
|
||||
bs->buf_size = buf_size;
|
||||
if (!read_only)
|
||||
memset((uint8_t *)buf, 0, sizeof(uint8_t) * buf_size);
|
||||
}
|
||||
|
||||
static inline void write_stream(StreamBuffer *bs, uint8_t *src, int bit_len)
|
||||
{
|
||||
for (int bit = 0; bit < bit_len; bit++)
|
||||
{
|
||||
int src_byte_i = bit / 8;
|
||||
int src_bit_i = bit % 8;
|
||||
int dest_byte_i = (bs->bit_pos + bit) / 8;
|
||||
int dest_bit_i = (bs->bit_pos + bit) % 8;
|
||||
bs->stream[dest_byte_i] |= (get_bit_val(src, src_byte_i, src_bit_i) << dest_bit_i);
|
||||
}
|
||||
bs->bit_pos += bit_len;
|
||||
}
|
||||
|
||||
static inline void move_stream_ptr(StreamBuffer *bs, int bit_len)
|
||||
{
|
||||
bs->bit_pos += bit_len;
|
||||
}
|
||||
|
||||
static inline void parse_stream(StreamBuffer *bs, uint8_t *dest, int bit_len)
|
||||
{
|
||||
memset(dest, 0, sizeof(uint8_t) * (bit_len + 7) >> 3);
|
||||
for (int bit = 0; bit < bit_len; bit++)
|
||||
{
|
||||
int dest_byte_i = bit / 8;
|
||||
int dest_bit_i = bit % 8;
|
||||
int bs_byte_i = (bs->bit_pos + bit) / 8;
|
||||
int bs_bit_i = (bs->bit_pos + bit) % 8;
|
||||
dest[dest_byte_i] |= (get_bit_val(bs->stream, bs_byte_i, bs_bit_i) << dest_bit_i);
|
||||
}
|
||||
bs->bit_pos += bit_len;
|
||||
}
|
||||
|
||||
// -- header read/write operation handler --
|
||||
static inline void vlc_enc_header(StreamBuffer *bs_header, CommandInfo *cmd_info, size_t blk_bs_size)
|
||||
{
|
||||
write_stream(bs_header, (uint8_t *)&blk_bs_size, 24); // bit[23:0] compressed block stream size
|
||||
move_stream_ptr(bs_header, 4); // bit[27:24] reserved
|
||||
write_stream(bs_header, (uint8_t *)&cmd_info->signedness, 1); // bit[28] signedness
|
||||
write_stream(bs_header, (uint8_t *)&cmd_info->is_bfloat16, 1); // bit[29] data type
|
||||
move_stream_ptr(bs_header, 2); // bit[31:30] bit depth
|
||||
write_stream(bs_header, (uint8_t *)&cmd_info->bias0, 8); // bit[39:32] bias0 for symbol remapping
|
||||
write_stream(bs_header, (uint8_t *)&cmd_info->bias1, 7); // bit[46:40] bias1 for symbol remapping
|
||||
write_stream(bs_header, (uint8_t *)&cmd_info->zero_guard_en, 1); // bit[47] zero guard
|
||||
}
|
||||
|
||||
static inline void vlc_dec_header(StreamBuffer *bs_header, CommandInfo *cmd_info)
|
||||
{
|
||||
move_stream_ptr(bs_header, 28); // bit[27:24] reserved
|
||||
parse_stream(bs_header, (uint8_t *)&cmd_info->signedness, 1); // bit[28] signedness
|
||||
parse_stream(bs_header, (uint8_t *)&cmd_info->is_bfloat16, 1); // bit[29] data type
|
||||
move_stream_ptr(bs_header, 2);
|
||||
parse_stream(bs_header, (uint8_t *)&cmd_info->bias0, 8); // bit[39:32] bias0 for symbol remapping
|
||||
parse_stream(bs_header, (uint8_t *)&cmd_info->bias1, 7); // bit[46:40] bias1 for symbol remapping
|
||||
parse_stream(bs_header, (uint8_t *)&cmd_info->zero_guard_en, 1); // bit[47] zero guard
|
||||
}
|
||||
|
||||
static inline void vlc_dec_header_ext(StreamBuffer *bs_header, CommandInfo *cmd_info, size_t *bs_size)
|
||||
{
|
||||
parse_stream(bs_header, (uint8_t *)bs_size, 24); // bit[23:0] compressed block stream size
|
||||
move_stream_ptr(bs_header, 4); // bit[27:24] reserved
|
||||
parse_stream(bs_header, (uint8_t *)&cmd_info->signedness, 1); // bit[28] signedness
|
||||
parse_stream(bs_header, (uint8_t *)&cmd_info->is_bfloat16, 1); // bit[29] data type
|
||||
move_stream_ptr(bs_header, 2);
|
||||
parse_stream(bs_header, (uint8_t *)&cmd_info->bias0, 8); // bit[39:32] bias0 for symbol remapping
|
||||
parse_stream(bs_header, (uint8_t *)&cmd_info->bias1, 7); // bit[46:40] bias1 for symbol remapping
|
||||
parse_stream(bs_header, (uint8_t *)&cmd_info->zero_guard_en, 1); // bit[47] zero guard
|
||||
}
|
||||
|
||||
// -- symbol remmaping handler --
|
||||
static inline uint8_t center_shift(uint8_t val, uint8_t bias, uint8_t zero_guard)
|
||||
{
|
||||
if (val == 0 && zero_guard)
|
||||
return 0;
|
||||
|
||||
int16_t shift_data_i = val - bias;
|
||||
uint8_t range = (bias <= 128) ? bias : 255 - bias;
|
||||
if (bias <= 128)
|
||||
{
|
||||
return (val >= (range << 1)) ? val : sign_to_unsign(shift_data_i) + zero_guard;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (val < (bias - range)) ? (range + bias - val + zero_guard) : (sign_to_unsign(shift_data_i) + zero_guard);
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint8_t inv_center_shift(uint8_t val, uint8_t bias, uint8_t zero_guard)
|
||||
{
|
||||
if (val == 0 && zero_guard)
|
||||
return 0;
|
||||
|
||||
uint8_t unsign_data_i = val - zero_guard;
|
||||
uint8_t range = (bias <= 128) ? bias : 255 - bias;
|
||||
if (bias <= 128)
|
||||
{
|
||||
return (val >= (range << 1)) ? val : unsign_to_sign(unsign_data_i) + bias;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (unsign_data_i > (range << 1)) ? (range + bias - val + zero_guard) : unsign_to_sign(unsign_data_i) + bias;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int8_t two_side_circular_shift(int8_t val, uint8_t bias0, uint8_t bias1)
|
||||
{
|
||||
if (val == 0)
|
||||
return 0;
|
||||
|
||||
uint8_t sign = (val < 0) ? true : false;
|
||||
int32_t abs_val = abs(val);
|
||||
abs_val -= (sign) ? bias1 : bias0;
|
||||
abs_val += (abs_val <= 0) ? (127 + sign) : 0;
|
||||
return (sign) ? -abs_val : abs_val;
|
||||
}
|
||||
|
||||
static inline int8_t inv_two_side_circular_shift(int8_t val, uint8_t bias0, uint8_t bias1)
|
||||
{
|
||||
if (val == 0)
|
||||
return 0;
|
||||
|
||||
uint8_t sign = (val < 0) ? true : false;
|
||||
uint32_t abs_val = abs(val);
|
||||
abs_val += (sign) ? bias1 : bias0;
|
||||
int32_t abs_val_minus = abs_val - (127 + sign);
|
||||
uint8_t abs_val_lsb = ((abs_val_minus <= 0)
|
||||
? abs_val
|
||||
: abs_val_minus) &
|
||||
0xFF;
|
||||
return (sign) ? -abs_val_lsb : abs_val_lsb;
|
||||
}
|
||||
|
||||
static inline void symbol_remapping(uint8_t *blk_in, uint8_t *blk_out, uint8_t bias0, uint8_t bias1, uint8_t signedness, uint8_t is_bf16_exp, uint8_t zero_guard)
|
||||
{
|
||||
if (is_bf16_exp == false && signedness == false)
|
||||
{
|
||||
// remapping bypass
|
||||
memcpy(blk_out, blk_in, sizeof(uint8_t) * 16);
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_bf16_exp == true)
|
||||
{
|
||||
// center circular shift
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
blk_out[i] = center_shift(blk_in[i], bias0, zero_guard);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// two-side circular shift
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
int8_t shift_data_i = two_side_circular_shift((int8_t)blk_in[i], bias0, bias1);
|
||||
blk_out[i] = sign_to_unsign(shift_data_i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void inv_symbol_remapping(uint8_t *blk_in, uint8_t *blk_out, uint8_t bias0, uint8_t bias1, uint8_t signedness, uint8_t is_bf16_exp, uint8_t zero_guard)
|
||||
{
|
||||
if (is_bf16_exp == false && signedness == false)
|
||||
{
|
||||
// remapping bypass
|
||||
memcpy(blk_out, blk_in, sizeof(uint8_t) * 16);
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_bf16_exp == true)
|
||||
{
|
||||
// center circular shift
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
blk_out[i] = inv_center_shift(blk_in[i], bias0, zero_guard);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// two-side circular shift
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
int8_t sign_data_i = unsign_to_sign(blk_in[i]);
|
||||
blk_out[i] = (uint8_t)inv_two_side_circular_shift(sign_data_i, bias0, bias1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline int vlc_estimate_block_order(uint8_t *blk_in, uint8_t bf16_zvc_en)
|
||||
{
|
||||
int best_k = 0;
|
||||
int best_bs_size = 0x7FFFFFFF;
|
||||
|
||||
for (int k = 0; k <= (int)MAX_ORDER_K; k++)
|
||||
{
|
||||
uint8_t remain_field_size = k << 4;
|
||||
int unary_field_len = 0;
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
uint8_t group_idx = blk_in[i] >> k;
|
||||
unary_field_len += (group_idx + 1);
|
||||
}
|
||||
int znum_bit = (bf16_zvc_en && k > 0) ? 4 : 0;
|
||||
int blk_size = (unary_field_len <= MAX_UNARY_FIELD_SIZE)
|
||||
? remain_field_size + unary_field_len + znum_bit
|
||||
: 255;
|
||||
if (blk_size < best_bs_size)
|
||||
{
|
||||
best_k = k;
|
||||
best_bs_size = blk_size;
|
||||
}
|
||||
}
|
||||
|
||||
best_k = (best_bs_size > 128) ? -1 : best_k;
|
||||
return best_k;
|
||||
}
|
||||
// -- vlc block parrelel GR encode/decode --
|
||||
static inline uint8_t vlc_gr_enc_block_data(uint8_t *blk_in, StreamBuffer *bs, int order_k, uint8_t bf16_zvc_en)
|
||||
{
|
||||
// uncompressed mode
|
||||
if (order_k == -1)
|
||||
{
|
||||
write_stream(bs, blk_in, 128);
|
||||
return 128;
|
||||
}
|
||||
|
||||
// remain field
|
||||
uint8_t remain_field[16] = {0};
|
||||
uint8_t unary_field[8] = {0};
|
||||
uint8_t sym_end_pos[16] = {0};
|
||||
uint8_t unary_field_len = 0;
|
||||
int sym_end_pos_accum = -1;
|
||||
|
||||
// bit plane encode for remain field
|
||||
for (int k = 0; k < order_k; k++)
|
||||
{
|
||||
uint8_t bit_plane0 = 0, bit_plane1 = 0;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
bit_plane0 |= (get_bit_val(blk_in, i, k) << i);
|
||||
bit_plane1 |= (get_bit_val(blk_in, i + 8, k) << i);
|
||||
}
|
||||
remain_field[k << 1] = bit_plane0;
|
||||
remain_field[(k << 1) + 1] = bit_plane1;
|
||||
}
|
||||
write_stream(bs, remain_field, order_k << 4);
|
||||
|
||||
if (bf16_zvc_en && order_k > 0)
|
||||
{
|
||||
int zero_num = 0;
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
if (blk_in[i] == 0)
|
||||
zero_num++;
|
||||
}
|
||||
assert(zero_num < 16);
|
||||
write_stream(bs, (uint8_t *)&zero_num, 4);
|
||||
}
|
||||
|
||||
// unary encode for unary field
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
int group_idx = blk_in[i] >> order_k;
|
||||
sym_end_pos_accum += (group_idx + 1);
|
||||
sym_end_pos[i] = sym_end_pos_accum;
|
||||
int byte_idx = sym_end_pos[i] / 8;
|
||||
int bit_idx = sym_end_pos[i] % 8;
|
||||
unary_field[byte_idx] |= (1 << (bit_idx));
|
||||
}
|
||||
unary_field_len = sym_end_pos[15] + 1;
|
||||
assert(unary_field_len <= MAX_UNARY_FIELD_SIZE);
|
||||
uint8_t ulen = (unary_field_len - 16) & 0x1F;
|
||||
write_stream(bs, unary_field, unary_field_len);
|
||||
|
||||
return ulen;
|
||||
}
|
||||
|
||||
static inline void vlc_gr_dec_block_data(StreamBuffer *bs, uint8_t bs_size, uint8_t *rec, int order_k, uint8_t bf16_zvc_en)
|
||||
{
|
||||
assert(bs_size <= 128);
|
||||
// uncompressed mode
|
||||
if (order_k == -1)
|
||||
{
|
||||
parse_stream(bs, rec, 128);
|
||||
return;
|
||||
}
|
||||
|
||||
// remain field
|
||||
uint8_t remain_data[16] = {0};
|
||||
uint8_t remain_bs[16] = {0};
|
||||
uint8_t unary_field[8] = {0};
|
||||
uint8_t sym_end_pos[16] = {0};
|
||||
uint8_t unary_sym[16] = {0};
|
||||
uint8_t remain_field_size = order_k << 4;
|
||||
|
||||
parse_stream(bs, remain_bs, remain_field_size);
|
||||
// bit plane encode for remain field
|
||||
for (int k = 0; k < order_k; k++)
|
||||
{
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
remain_data[i] |= (get_bit_val(remain_bs, k << 1, i) << k);
|
||||
remain_data[i + 8] |= (get_bit_val(remain_bs, (k << 1) + 1, i) << k);
|
||||
}
|
||||
}
|
||||
|
||||
// zero number info
|
||||
int znum_bit = (bf16_zvc_en && order_k > 0) ? 4 : 0;
|
||||
uint8_t znum = 0;
|
||||
parse_stream(bs, &znum, znum_bit);
|
||||
|
||||
// unary encode for unary field
|
||||
uint8_t unary_field_len = bs_size - remain_field_size - znum_bit;
|
||||
parse_stream(bs, unary_field, unary_field_len);
|
||||
|
||||
int sym_cnt = 0;
|
||||
for (uint8_t ubit_i = 0; ubit_i < unary_field_len; ubit_i++)
|
||||
{
|
||||
int byte_idx = ubit_i / 8;
|
||||
int bit_idx = ubit_i % 8;
|
||||
if (get_bit_val(unary_field, byte_idx, bit_idx) == 1)
|
||||
{
|
||||
sym_end_pos[sym_cnt] = ubit_i;
|
||||
sym_cnt++;
|
||||
}
|
||||
}
|
||||
unary_sym[0] = sym_end_pos[0];
|
||||
for (int i = 1; i < 16; i++)
|
||||
{
|
||||
unary_sym[i] = sym_end_pos[i] - sym_end_pos[i - 1] - 1;
|
||||
}
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
rec[i] = (unary_sym[i] << order_k) + remain_data[i];
|
||||
}
|
||||
}
|
||||
|
||||
// -- vlc encode int8 entry funtion --
|
||||
static inline void bm_vlc_enc_int8(const uint8_t *ibuf, size_t isz, uint8_t *obuf, size_t *osz, CommandInfo *cmd_info)
|
||||
{
|
||||
StreamBuffer bs_header, bs_kmap, bs_data;
|
||||
size_t blk_num = (isz + 15) >> 4;
|
||||
size_t header_size = 16;
|
||||
size_t kmap_size = ceiling_func(blk_num, 16) << 4;
|
||||
size_t bs_buf_size = header_size + kmap_size + (blk_num << 4);
|
||||
uint8_t *bsbuf = (uint8_t *)calloc(bs_buf_size, sizeof(uint8_t));
|
||||
|
||||
// block encode
|
||||
init_stream(&bs_kmap, bsbuf + header_size, kmap_size, false);
|
||||
init_stream(&bs_data, bsbuf + header_size + kmap_size, blk_num << 4, false);
|
||||
|
||||
for (size_t blk_idx = 0; blk_idx < blk_num; blk_idx++)
|
||||
{
|
||||
uint8_t blk_data[16] = {0}, blk_sr_data[16] = {0};
|
||||
size_t in_size = (blk_idx == (blk_num - 1)) ? isz - (blk_idx << 4) : 16;
|
||||
memcpy(blk_data, &ibuf[blk_idx << 4], sizeof(uint8_t) * in_size);
|
||||
|
||||
symbol_remapping(blk_data, blk_sr_data, cmd_info->bias0, cmd_info->bias1, cmd_info->signedness, false, false);
|
||||
|
||||
int k = vlc_estimate_block_order(blk_sr_data, false);
|
||||
uint8_t ulen = vlc_gr_enc_block_data(blk_sr_data, &bs_data, k, false);
|
||||
uint8_t k_info = (k == -1) ? 0xE0 : (k << 5) + ulen;
|
||||
write_stream(&bs_kmap, &k_info, 8);
|
||||
}
|
||||
|
||||
int blk_bs_size = ceiling_func(((bs_data.bit_pos + 7) >> 3), 16) << 4; // 16 byte align
|
||||
*osz = header_size + kmap_size + blk_bs_size;
|
||||
|
||||
// write header
|
||||
init_stream(&bs_header, bsbuf, header_size, false);
|
||||
vlc_enc_header(&bs_header, cmd_info, blk_bs_size);
|
||||
|
||||
memcpy(obuf, bsbuf, (*osz) * sizeof(uint8_t));
|
||||
free(bsbuf);
|
||||
}
|
||||
|
||||
// -- vlc decode int8 entry funtion --
|
||||
static inline void bm_vlc_dec_int8_ext(const uint8_t *ibuf, size_t isz, uint8_t *obuf, size_t *bs_size)
|
||||
{
|
||||
StreamBuffer bs_header, bs_kmap, bs_data;
|
||||
CommandInfo cmd_info;
|
||||
memset(&cmd_info, 0, sizeof(CommandInfo));
|
||||
|
||||
size_t blk_num = (isz + 15) >> 4;
|
||||
int header_size = 16;
|
||||
int kmap_size = ceiling_func(blk_num, 16) << 4;
|
||||
|
||||
// parse header
|
||||
init_stream(&bs_header, ibuf, header_size, true);
|
||||
vlc_dec_header_ext(&bs_header, &cmd_info, bs_size);
|
||||
|
||||
// Check whether valid header
|
||||
size_t bs_buf_size = get_out_bs_buf_size(isz, 0); // int8
|
||||
ASSERT(*bs_size <= bs_buf_size);
|
||||
ASSERT(cmd_info.is_bfloat16 == 0);
|
||||
|
||||
// block decode
|
||||
init_stream(&bs_kmap, ibuf + header_size, kmap_size, true);
|
||||
init_stream(&bs_data, ibuf + header_size + kmap_size, blk_num << 4, true);
|
||||
|
||||
for (size_t blk_idx = 0; blk_idx < blk_num; blk_idx++)
|
||||
{
|
||||
uint8_t blk_data[16] = {0}, blk_sr_data[16] = {0};
|
||||
uint8_t k_info = 0;
|
||||
parse_stream(&bs_kmap, &k_info, 8);
|
||||
uint8_t ulen = k_info & 0x1F;
|
||||
int k = (k_info >> 5 == 7) ? -1 : k_info >> 5;
|
||||
int blk_bs_size = (k == -1) ? 128 : (k << 4) + ulen + 16;
|
||||
vlc_gr_dec_block_data(&bs_data, blk_bs_size, blk_data, k, false);
|
||||
|
||||
inv_symbol_remapping(blk_data, blk_sr_data, cmd_info.bias0, cmd_info.bias1, cmd_info.signedness, false, false);
|
||||
|
||||
int out_size = (blk_idx == (blk_num - 1)) ? isz - (blk_idx << 4) : 16;
|
||||
memcpy(&obuf[blk_idx << 4], blk_sr_data, sizeof(uint8_t) * out_size);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void bm_vlc_dec_int8(const uint8_t *ibuf, size_t isz, uint8_t *obuf)
|
||||
{
|
||||
size_t bs_size;
|
||||
bm_vlc_dec_int8_ext(ibuf, isz, obuf, &bs_size);
|
||||
}
|
||||
|
||||
// -- vlc encode bfloat16 entry funtion --
|
||||
static inline void bm_vlc_enc_bf16(const uint16_t *ibuf, size_t isz, uint8_t *obuf, size_t *osz, CommandInfo *cmd_info)
|
||||
{
|
||||
StreamBuffer bs_header, bs_kmap, bs_data;
|
||||
size_t blk_num = (isz + 31) >> 5; // 32 bytes per blok
|
||||
size_t header_size = 16;
|
||||
size_t kmap_size = ceiling_func(blk_num, 16) << 4;
|
||||
size_t bs_buf_size = header_size + kmap_size + (blk_num << 5);
|
||||
uint8_t *bsbuf = (uint8_t *)calloc(bs_buf_size, sizeof(uint8_t));
|
||||
|
||||
// block encode
|
||||
init_stream(&bs_kmap, bsbuf + header_size, kmap_size, false);
|
||||
init_stream(&bs_data, bsbuf + header_size + kmap_size, blk_num << 5, false);
|
||||
|
||||
for (size_t blk_idx = 0; blk_idx < blk_num; blk_idx++)
|
||||
{
|
||||
uint8_t blk_data[16] = {0}, blk_sr_data[16] = {0}, blk_data_frac[16] = {0};
|
||||
size_t in_num = (blk_idx == (blk_num - 1)) ? ((isz >> 1) - (blk_idx << 4)) : 16;
|
||||
dispatch_bf16_data(&ibuf[blk_idx << 4], blk_data, blk_data_frac, in_num);
|
||||
|
||||
// exp: BGR encode
|
||||
symbol_remapping(blk_data, blk_sr_data, cmd_info->bias0, cmd_info->bias1, false, true, cmd_info->zero_guard_en);
|
||||
|
||||
int k = vlc_estimate_block_order(blk_sr_data, cmd_info->zero_guard_en);
|
||||
uint8_t ulen = vlc_gr_enc_block_data(blk_sr_data, &bs_data, k, cmd_info->zero_guard_en);
|
||||
uint8_t k_info = (k == -1) ? 0xE0 : (k << 5) + ulen;
|
||||
write_stream(&bs_kmap, &k_info, 8);
|
||||
|
||||
// frac: implicit zero compression
|
||||
for (size_t i = 0; i < 16; i++)
|
||||
{
|
||||
if (!cmd_info->zero_guard_en || blk_data[i] != 0)
|
||||
{
|
||||
write_stream(&bs_data, &blk_data_frac[i], 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int blk_bs_size = ceiling_func(((bs_data.bit_pos + 7) >> 3), 16) << 4; // 16 byte align
|
||||
*osz = header_size + kmap_size + blk_bs_size;
|
||||
|
||||
// write header
|
||||
init_stream(&bs_header, bsbuf, header_size, false);
|
||||
vlc_enc_header(&bs_header, cmd_info, blk_bs_size);
|
||||
|
||||
memcpy(obuf, bsbuf, (*osz) * sizeof(uint8_t));
|
||||
free(bsbuf);
|
||||
}
|
||||
|
||||
// -- vlc decode bfloat16 entry funtion --
|
||||
static inline void bm_vlc_dec_bf16_ext(const uint8_t *ibuf, size_t isz, uint16_t *obuf, size_t *bs_size)
|
||||
{
|
||||
StreamBuffer bs_header, bs_kmap, bs_data;
|
||||
CommandInfo cmd_info;
|
||||
memset(&cmd_info, 0, sizeof(CommandInfo));
|
||||
|
||||
size_t blk_num = (isz + 31) >> 5; // 32 bytes per blok
|
||||
int header_size = 16;
|
||||
int kmap_size = ceiling_func(blk_num, 16) << 4;
|
||||
|
||||
// parse header
|
||||
init_stream(&bs_header, ibuf, header_size, true);
|
||||
vlc_dec_header_ext(&bs_header, &cmd_info, bs_size);
|
||||
|
||||
// Check whether valid header
|
||||
size_t bs_buf_size = get_out_bs_buf_size(isz, 1); // bf16
|
||||
ASSERT(*bs_size <= bs_buf_size);
|
||||
ASSERT(cmd_info.is_bfloat16 == 1);
|
||||
|
||||
// block decode
|
||||
init_stream(&bs_kmap, ibuf + header_size, kmap_size, true);
|
||||
init_stream(&bs_data, ibuf + header_size + kmap_size, blk_num << 5, true);
|
||||
|
||||
for (size_t blk_idx = 0; blk_idx < blk_num; blk_idx++)
|
||||
{
|
||||
uint8_t blk_data[16] = {0}, blk_sr_data[16] = {0}, blk_data_frac[16] = {0};
|
||||
uint8_t k_info = 0;
|
||||
parse_stream(&bs_kmap, &k_info, 8);
|
||||
uint8_t ulen = k_info & 0x1F;
|
||||
int k = (k_info >> 5 == 7) ? -1 : k_info >> 5;
|
||||
int znum_bit = (cmd_info.zero_guard_en && k > 0) ? 4 : 0;
|
||||
uint8_t blk_bs_size = (k == -1) ? 128 : (k << 4) + ulen + 16 + znum_bit;
|
||||
|
||||
// exp: BGR decode
|
||||
vlc_gr_dec_block_data(&bs_data, blk_bs_size, blk_data, k, cmd_info.zero_guard_en);
|
||||
|
||||
inv_symbol_remapping(blk_data, blk_sr_data, cmd_info.bias0, cmd_info.bias1, false, true, cmd_info.zero_guard_en);
|
||||
|
||||
size_t out_num = (blk_idx == (blk_num - 1)) ? ((isz >> 1) - (blk_idx << 4)) : 16;
|
||||
|
||||
// frac: implicit zero compression
|
||||
for (size_t i = 0; i < out_num; i++)
|
||||
{
|
||||
if (!cmd_info.zero_guard_en || blk_sr_data[i] != 0)
|
||||
{
|
||||
parse_stream(&bs_data, &blk_data_frac[i], 8);
|
||||
}
|
||||
}
|
||||
merge_bf16_data(blk_sr_data, blk_data_frac, &obuf[blk_idx << 4], out_num);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void bm_vlc_dec_bf16(const uint8_t *ibuf, size_t isz, uint16_t *obuf)
|
||||
{
|
||||
size_t bs_size;
|
||||
bm_vlc_dec_bf16_ext(ibuf, isz, obuf, &bs_size);
|
||||
}
|
||||
|
||||
// -- offline estimate model weight params --
|
||||
static inline void bm_vlc_est_weight_bias(const uint8_t *ibuf, size_t isz, uint8_t signedness, uint8_t isBfloat16, CommandInfo *cmd_info)
|
||||
{
|
||||
assert(!(isBfloat16 && signedness)); // WARNING: signedness MUST be 0 as isBfloat16==True
|
||||
|
||||
cmd_info->is_bfloat16 = isBfloat16;
|
||||
if (isBfloat16 == false && signedness == true)
|
||||
{
|
||||
// two-side circular shift
|
||||
int hist[256] = {0};
|
||||
for (size_t i = 0; i < isz; i++)
|
||||
{
|
||||
hist[ibuf[i]]++;
|
||||
}
|
||||
|
||||
int8_t pos_v = 1;
|
||||
//while (pos_v < 128)
|
||||
// comparison is always true due to limited range of data type [-Werror=type-limits]
|
||||
while (true)
|
||||
{
|
||||
if (hist[((uint8_t)pos_v)] == 0)
|
||||
{
|
||||
pos_v++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
//cmd_info->bias0 = (pos_v > 1 && pos_v < 128) ? (pos_v - 1) : 0;
|
||||
// comparison is always true due to limited range of data type [-Werror=type-limits]
|
||||
cmd_info->bias0 = (pos_v > 1) ? (pos_v - 1) : 0;
|
||||
int8_t neg_v = -1;
|
||||
//while (neg_v >= (-128)) // comparison is always true due to limited range of data type [-Werror=type-limits]
|
||||
while (true)
|
||||
{
|
||||
if (hist[(uint8_t)neg_v] == 0)
|
||||
{
|
||||
neg_v--;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
//cmd_info->bias1 = (neg_v < -1 && neg_v >= -128) ? abs(neg_v + 1) : 0;
|
||||
// comparison is always true due to limited range of data type [-Werror=type-limits]
|
||||
cmd_info->bias1 = (neg_v < -1) ? abs(neg_v + 1) : 0;
|
||||
cmd_info->signedness = true;
|
||||
}
|
||||
|
||||
if (isBfloat16 == true)
|
||||
{
|
||||
// center shift
|
||||
int64_t exp_accum = 0;
|
||||
uint16_t *bf16_in = (uint16_t *)ibuf;
|
||||
size_t inum = (isz >> 1), cnt = 0;
|
||||
for (size_t i = 0; i < inum; i++)
|
||||
{
|
||||
uint8_t exp = ((bf16_in[i] >> 7) & 0xFF);
|
||||
if (exp != 0)
|
||||
{
|
||||
exp_accum += exp;
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
if (cnt > 0)
|
||||
{
|
||||
cmd_info->bias0 = (uint8_t)((exp_accum / (float)cnt) + 0.5);
|
||||
}
|
||||
cmd_info->zero_guard_en = (inum == cnt) ? false : true;
|
||||
cmd_info->signedness = false;
|
||||
}
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __BM_VLC_COMPRESS_H__ */
|
||||
1042
cvikernel/include/bmkernel/bm1880v2/bmkernel_1880v2.h
Normal file
1042
cvikernel/include/bmkernel/bm1880v2/bmkernel_1880v2.h
Normal file
File diff suppressed because it is too large
Load Diff
369
cvikernel/include/bmkernel/bm1880v2/compression.h
Normal file
369
cvikernel/include/bmkernel/bm1880v2/compression.h
Normal file
@ -0,0 +1,369 @@
|
||||
#ifndef COMPRESSION_H
|
||||
#define COMPRESSION_H
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
typedef struct {
|
||||
uint32_t compress_md;
|
||||
uint32_t bit_length;
|
||||
int is_signed;
|
||||
|
||||
uint64_t total_data_num;
|
||||
uint32_t non_zero_data_num;
|
||||
|
||||
uint64_t header_bytes;
|
||||
uint64_t map_bytes;
|
||||
uint64_t data_bytes;
|
||||
uint64_t total_bytes;
|
||||
|
||||
int compressed_min;
|
||||
int compressed_max;
|
||||
} compression_info_t;
|
||||
|
||||
typedef struct {
|
||||
uint64_t header_offset;
|
||||
uint64_t header_size;
|
||||
uint64_t map_offset;
|
||||
uint64_t map_size;
|
||||
uint64_t data_offset;
|
||||
uint64_t data_size;
|
||||
uint64_t total_size;
|
||||
} compress_addr_info;
|
||||
|
||||
static uint64_t compression_map_bytes(uint64_t total_data_num)
|
||||
{
|
||||
uint64_t bit_alignment = 16 * 8;
|
||||
uint64_t bits = total_data_num;
|
||||
|
||||
return ceiling_func(bits, bit_alignment)*16;
|
||||
}
|
||||
|
||||
static uint64_t compression_map_clear_bytes(uint64_t total_data_num)
|
||||
{
|
||||
uint64_t bit_alignment = 2 * 8;
|
||||
uint64_t bits = total_data_num;
|
||||
|
||||
return ceiling_func(bits, bit_alignment)*2;
|
||||
}
|
||||
|
||||
|
||||
static uint64_t compression_data_bytes(uint64_t non_zero_data_num, uint32_t bit_length)
|
||||
{
|
||||
if (bit_length == 1)
|
||||
return 0;
|
||||
|
||||
uint64_t bit_alignment = 8;
|
||||
uint64_t bits = non_zero_data_num * bit_length;
|
||||
|
||||
return ceiling_func(bits, bit_alignment);
|
||||
}
|
||||
|
||||
static inline uint32_t compression_bit_length(uint32_t compress_md)
|
||||
{
|
||||
switch (compress_md) {
|
||||
case 0:
|
||||
return 8;
|
||||
case 1:
|
||||
return 4;
|
||||
case 2:
|
||||
return 2;
|
||||
case 3:
|
||||
return 1;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void compute_compressed_range(
|
||||
uint32_t bit_length, int is_signed, int *min, int *max)
|
||||
{
|
||||
if (is_signed) {
|
||||
switch (bit_length) {
|
||||
case 1:
|
||||
*min = -1;
|
||||
*max = 0;
|
||||
return;
|
||||
case 2:
|
||||
*min = -2;
|
||||
*max = 1;
|
||||
return;
|
||||
case 4:
|
||||
*min = -8;
|
||||
*max = 7;
|
||||
return;
|
||||
case 8:
|
||||
*min = -128;
|
||||
*max = 127;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
*min = 0;
|
||||
switch (bit_length) {
|
||||
case 1:
|
||||
*max = 1;
|
||||
return;
|
||||
case 2:
|
||||
*max = 3;
|
||||
return;
|
||||
case 4:
|
||||
*max = 15;
|
||||
return;
|
||||
case 8:
|
||||
*max = 255;
|
||||
return;
|
||||
}
|
||||
}
|
||||
assert(0);
|
||||
}
|
||||
|
||||
static inline int saturate(int val, int max, int min)
|
||||
{
|
||||
if (val < min)
|
||||
return min;
|
||||
else if (val > max)
|
||||
return max;
|
||||
else
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline uint64_t count_non_zero_results(
|
||||
uint8_t buf[], uint64_t size, int is_signed, int max, int min)
|
||||
{
|
||||
uint64_t n = 0;
|
||||
|
||||
for (uint64_t i = 0; i < size; i++) {
|
||||
int val = is_signed? (int8_t)buf[i]: buf[i];
|
||||
int res = saturate(val, max, min);
|
||||
if (res != 0)
|
||||
n++;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static inline void set_map_bit(uint8_t map[], uint64_t i)
|
||||
{
|
||||
uint64_t byte_i = i / 8;
|
||||
uint64_t bit_i = i % 8;
|
||||
|
||||
map[byte_i] |= (1 << bit_i);
|
||||
}
|
||||
|
||||
static inline uint8_t read_map_bit(uint8_t map[], uint64_t i)
|
||||
{
|
||||
uint64_t byte_i = i / 8;
|
||||
uint64_t bit_i = i % 8;
|
||||
|
||||
return (map[byte_i] >> bit_i) & 1;
|
||||
}
|
||||
|
||||
static inline void parse_header(
|
||||
uint32_t header, int *is_signed, uint32_t *compress_md, uint32_t *nz_num)
|
||||
{
|
||||
*is_signed = (header >> 29) & 1;
|
||||
*compress_md = (header >> 24) & 0b11;
|
||||
*nz_num = header & 0xffffff;
|
||||
}
|
||||
|
||||
static inline void fill_header(uint32_t *hdr, compression_info_t *info)
|
||||
{
|
||||
if(compression_bit_length(info->compress_md)!=1)
|
||||
{
|
||||
*hdr = (info->is_signed << 29) | (1 << 28) |
|
||||
(info->compress_md << 24) |
|
||||
info->non_zero_data_num;
|
||||
}else
|
||||
{
|
||||
*hdr = (info->is_signed << 29) | (1 << 28) |
|
||||
(info->compress_md << 24);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void fill_map(uint8_t map[], uint8_t buf[], compression_info_t *info)
|
||||
{
|
||||
int min = info->compressed_min;
|
||||
int max = info->compressed_max;
|
||||
|
||||
uint64_t clear_map = compression_map_clear_bytes(info->total_data_num);
|
||||
for (uint64_t i = 0; i < clear_map; i++)
|
||||
map[i] = 0;
|
||||
|
||||
for (uint64_t i = 0; i < info->total_data_num; i++) {
|
||||
int val = info->is_signed? (int8_t)buf[i]: buf[i];
|
||||
int res = saturate(val, max, min);
|
||||
if (res != 0)
|
||||
set_map_bit(map, i);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void compress_one_data(
|
||||
uint8_t data[], uint64_t i, uint8_t val, compression_info_t *info)
|
||||
{
|
||||
uint32_t bit_len = info->bit_length;
|
||||
uint32_t data_per_byte = 8 / bit_len;
|
||||
|
||||
uint32_t byte_i = i / data_per_byte;
|
||||
uint32_t bit_i = (i % data_per_byte) * bit_len;
|
||||
uint8_t mask = (1 << bit_len) - 1;
|
||||
|
||||
data[byte_i] |= (val & mask) << bit_i;
|
||||
}
|
||||
|
||||
static inline uint8_t sign_extend(uint8_t val, uint32_t bit_len)
|
||||
{
|
||||
int shift = 8 - bit_len;
|
||||
return (int8_t)(val << shift) >> shift;
|
||||
}
|
||||
|
||||
static inline uint8_t decompress_one_data(
|
||||
uint8_t data[], uint64_t i, compression_info_t *info)
|
||||
{
|
||||
uint32_t bit_len = info->bit_length;
|
||||
uint32_t data_per_byte = 8 / bit_len;
|
||||
|
||||
uint32_t byte_i = i / data_per_byte;
|
||||
uint32_t bit_i = (i % data_per_byte) * bit_len;
|
||||
uint8_t mask = (1 << bit_len) - 1;
|
||||
|
||||
uint8_t val = (data[byte_i] >> bit_i) & mask;
|
||||
if (info->is_signed)
|
||||
val = sign_extend(val, bit_len);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline void fill_data(uint8_t data[], uint8_t buf[], compression_info_t *info)
|
||||
{
|
||||
int min = info->compressed_min;
|
||||
int max = info->compressed_max;
|
||||
|
||||
for (uint64_t i = 0; i < info->data_bytes; i++)
|
||||
data[i] = 0;
|
||||
|
||||
uint64_t nz_i = 0;
|
||||
for (uint64_t i = 0; i < info->total_data_num; i++) {
|
||||
int val = info->is_signed? (int8_t)buf[i]: buf[i];
|
||||
int res = saturate(val, max, min);
|
||||
if (res != 0) {
|
||||
compress_one_data(data, nz_i, res, info);
|
||||
nz_i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline compression_info_t make_compression_info(
|
||||
uint8_t buf[], uint64_t size, uint32_t compress_md, int is_signed)
|
||||
{
|
||||
uint32_t bit_length = compression_bit_length(compress_md);
|
||||
|
||||
int min, max;
|
||||
compute_compressed_range(bit_length, is_signed, &min, &max);
|
||||
|
||||
uint32_t nz_num = count_non_zero_results(buf, size, is_signed, max, min);
|
||||
assert(nz_num <= 0xffffff);
|
||||
|
||||
compression_info_t info;
|
||||
info.compress_md = compress_md;
|
||||
info.bit_length = bit_length;
|
||||
info.is_signed = is_signed;
|
||||
info.total_data_num = size;
|
||||
info.non_zero_data_num = nz_num;
|
||||
info.header_bytes = 16;
|
||||
info.map_bytes = compression_map_bytes(size);
|
||||
info.data_bytes = compression_data_bytes(nz_num, bit_length);
|
||||
info.total_bytes = info.header_bytes + info.map_bytes + info.data_bytes;
|
||||
info.compressed_min = min;
|
||||
info.compressed_max = max;
|
||||
return info;
|
||||
}
|
||||
|
||||
static inline compression_info_t parse_compression_info(
|
||||
uint8_t compressed_buf[], uint64_t max_size, uint64_t total_data_num)
|
||||
{
|
||||
uint64_t header_bytes = 16;
|
||||
assert(header_bytes <= max_size);
|
||||
|
||||
int is_signed;
|
||||
uint32_t compress_md, nz_num;
|
||||
parse_header(*(uint32_t *)compressed_buf, &is_signed, &compress_md, &nz_num);
|
||||
|
||||
uint32_t bit_length = compression_bit_length(compress_md);
|
||||
int min, max;
|
||||
compute_compressed_range(bit_length, is_signed, &min, &max);
|
||||
|
||||
compression_info_t info;
|
||||
info.compress_md = compress_md;
|
||||
info.bit_length = compression_bit_length(compress_md);
|
||||
info.is_signed = is_signed;
|
||||
info.total_data_num = total_data_num;
|
||||
info.non_zero_data_num = nz_num;
|
||||
info.header_bytes = header_bytes;
|
||||
info.map_bytes = compression_map_bytes(total_data_num);
|
||||
info.data_bytes = compression_data_bytes(nz_num, info.bit_length);
|
||||
info.total_bytes = header_bytes + info.map_bytes + info.data_bytes;
|
||||
info.compressed_min = min;
|
||||
info.compressed_max = max;
|
||||
|
||||
assert(info.total_bytes <= max_size);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
static inline uint8_t * compress(
|
||||
uint8_t buf[], uint64_t size, uint32_t compress_md, int is_signed, compress_addr_info *compressed_data)
|
||||
{
|
||||
compression_info_t info =
|
||||
make_compression_info(buf, size, compress_md, is_signed);
|
||||
|
||||
assert(info.total_bytes < 0x100000);
|
||||
static uint8_t *result = new uint8_t[0x100000];
|
||||
uint32_t *hdr = (uint32_t *)result;
|
||||
uint8_t *map = &result[info.header_bytes];
|
||||
uint8_t *data = &map[info.map_bytes];
|
||||
|
||||
fill_header(hdr, &info);
|
||||
fill_map(map, buf, &info);
|
||||
if (info.bit_length != 1)
|
||||
fill_data(data, buf, &info);
|
||||
|
||||
compressed_data->header_offset = 0;
|
||||
compressed_data->header_size = 4;
|
||||
compressed_data->map_offset = info.header_bytes;
|
||||
compressed_data->map_size = compression_map_clear_bytes(info.total_data_num);
|
||||
compressed_data->data_offset = info.map_bytes + info.header_bytes;
|
||||
compressed_data->data_size = info.data_bytes;
|
||||
compressed_data->total_size = info.total_bytes;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline void decompress(
|
||||
uint8_t buf[], uint64_t size, uint8_t compressed_buf[], uint64_t max_size)
|
||||
{
|
||||
compression_info_t info =
|
||||
parse_compression_info(compressed_buf, max_size, size);
|
||||
assert(info.total_bytes <= max_size);
|
||||
assert(info.total_data_num == size);
|
||||
|
||||
uint8_t *map = &compressed_buf[info.header_bytes];
|
||||
if (info.bit_length == 1) {
|
||||
for (uint64_t i = 0; i < size; i++) {
|
||||
uint8_t val = read_map_bit(map, i);
|
||||
buf[i] = info.is_signed? sign_extend(val, 1): val;
|
||||
}
|
||||
} else {
|
||||
uint8_t *data = &map[info.map_bytes];
|
||||
uint64_t data_i = 0;
|
||||
for (uint64_t i = 0; i < size; i++) {
|
||||
uint8_t val = read_map_bit(map, i);
|
||||
if (val == 0) {
|
||||
buf[i] = 0;
|
||||
} else {
|
||||
buf[i] = decompress_one_data(data, data_i, &info);
|
||||
data_i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* COMPRESSION_H */
|
||||
300
cvikernel/include/bmkernel/bm1880v2/non_atomic.h
Normal file
300
cvikernel/include/bmkernel/bm1880v2/non_atomic.h
Normal file
@ -0,0 +1,300 @@
|
||||
#ifndef __BMKERNEL_1880v2_NON_ATOMIC_H__
|
||||
#define __BMKERNEL_1880v2_NON_ATOMIC_H__
|
||||
|
||||
#include "bmkernel_1880v2.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// non atomic
|
||||
void bf16_table_shape(bmk1880v2_context_t *ctx, bmk1880v2_tensor_lmem_shape_t *s);
|
||||
|
||||
int bf16_emit_sqrt(bmk1880v2_context_t *ctx, bmk1880v2_tensor_lmem_t *tl_ifmap,
|
||||
bmk1880v2_tensor_lmem_t *tl_buf, bmk1880v2_tensor_lmem_t *tbl_answer,
|
||||
bmk1880v2_tensor_lmem_t *tbl_answer_mantissa,
|
||||
bmk1880v2_tensor_lmem_t *tl_ofmap_bf16);
|
||||
void bf16_gen_sqrt(uint16_t *table_data, bmk1880v2_tensor_lmem_shape_t *table_shape);
|
||||
void bf16_gen_sqrt_mantissa(uint16_t *table_mantissa, bmk1880v2_tensor_lmem_shape_t *table_shape);
|
||||
void bf16_sqrt_tbl(uint16_t *sqrt_table_data, uint16_t *sqrt_table_data_mantissa,
|
||||
bmk1880v2_tensor_lmem_shape_t *table_shape);
|
||||
|
||||
int bf16_emit_reciprocal(bmk1880v2_context_t *ctx, bmk1880v2_tensor_lmem_t *tl_ifmap,
|
||||
bmk1880v2_tensor_lmem_t *tl_buf, bmk1880v2_tensor_lmem_t *tbl_answer,
|
||||
bmk1880v2_tensor_lmem_t *tbl_answer_mantissa,
|
||||
bmk1880v2_tensor_lmem_t *tl_ofmap_bf16);
|
||||
void bf16_gen_reciprocal(uint16_t *table_data, bmk1880v2_tensor_lmem_shape_t *table_shape);
|
||||
void bf16_gen_reciprocal_mantissa(uint16_t *table_mantissa, bmk1880v2_tensor_lmem_shape_t *table_shape);
|
||||
void bf16_reciprocal_tbl(uint16_t *table_data, uint16_t *table_mantissa,
|
||||
bmk1880v2_tensor_lmem_shape_t *table_shape);
|
||||
|
||||
void bf16_atan_y0(uint16_t *table_data_y0, bmk1880v2_tensor_lmem_shape_t *table_shape);
|
||||
void bf16_atan_fast_degree_y0(uint16_t *table_data_y0, bmk1880v2_tensor_lmem_shape_t *table_shape);
|
||||
void bf16_atan_slope(uint16_t *table_slope, bmk1880v2_tensor_lmem_shape_t *table_shape);
|
||||
void bf16_atan_s_01(uint16_t *table_invert, bmk1880v2_tensor_lmem_shape_t *table_shape);
|
||||
void bf16_atan_pos_neg(uint16_t *table_pos_neg, bmk1880v2_tensor_lmem_shape_t *table_shape);
|
||||
int bf16_atan_slope_multipilier(bmk1880v2_context_t *ctx, bmk1880v2_tensor_lmem_t *tl_buf,
|
||||
bmk1880v2_tensor_lmem_t *tl_buf2, bmk1880v2_tensor_lmem_t *tl_buf3,
|
||||
bmk1880v2_tensor_lmem_t *tl_ifmap,
|
||||
bmk1880v2_tensor_lmem_t *tl_ofmap_bf16, fmt_t fmt);
|
||||
|
||||
int bf16_atan_emit(bmk1880v2_context_t *ctx, bmk1880v2_tensor_lmem_t *tl_ifmap,
|
||||
bmk1880v2_tensor_lmem_t *tl_buf, bmk1880v2_tensor_lmem_t *tl_buf2,
|
||||
bmk1880v2_tensor_lmem_t *tl_buf3, bmk1880v2_tensor_lmem_t *tl_y0_buf,
|
||||
bmk1880v2_tensor_lmem_t *tl_slope_buf, bmk1880v2_tensor_lmem_t *tl_invert_buf,
|
||||
bmk1880v2_tensor_lmem_t *tl_pos_neg_buf,
|
||||
bmk1880v2_tensor_lmem_t *tl_table_answer,
|
||||
bmk1880v2_tensor_lmem_t *tl_table_answer_mantissa,
|
||||
bmk1880v2_tensor_lmem_t *tl_ofmap_bf16, fmt_t fmt);
|
||||
|
||||
int bf16_atan_fast_emit(bmk1880v2_context_t *ctx, bmk1880v2_tensor_lmem_t *tl_ifmap,
|
||||
bmk1880v2_tensor_lmem_t *tl_buf, bmk1880v2_tensor_lmem_t *tl_buf2,
|
||||
bmk1880v2_tensor_lmem_t *tl_y0_buf,
|
||||
bmk1880v2_tensor_lmem_t *tl_invert_buf,
|
||||
bmk1880v2_tensor_lmem_t *tl_pos_neg_buf,
|
||||
bmk1880v2_tensor_lmem_t *tl_table_answer,
|
||||
bmk1880v2_tensor_lmem_t *tl_table_answer_mantissa,
|
||||
bmk1880v2_tensor_lmem_t *tl_ofmap_bf16, fmt_t fmt,
|
||||
uint8_t is_dirty_ifmap);
|
||||
|
||||
void bf16_atan2_fast_emit(bmk1880v2_context_t *ctx, bmk1880v2_tensor_lmem_t *y,
|
||||
bmk1880v2_tensor_lmem_t *x, bmk1880v2_tensor_lmem_t *tl_buf,
|
||||
bmk1880v2_tensor_lmem_t *tl_buf2, bmk1880v2_tensor_lmem_t *tl_buf3,
|
||||
bmk1880v2_tensor_lmem_t *tl_buf4, bmk1880v2_tensor_lmem_t *tl_y0_buf,
|
||||
bmk1880v2_tensor_lmem_t *tl_slope_buf, bmk1880v2_tensor_lmem_t *tl_invert_buf,
|
||||
bmk1880v2_tensor_lmem_t *tl_pos_neg_buf,
|
||||
bmk1880v2_tensor_lmem_t *tl_table_answer,
|
||||
bmk1880v2_tensor_lmem_t *tl_table_answer_mantissa,
|
||||
bmk1880v2_tensor_lmem_t *tl_0_idx_table,
|
||||
bmk1880v2_tensor_lmem_t *tl_ofmap_bf16, fmt_t fmt);
|
||||
|
||||
void bf16_atan2_fast_degree_emit(bmk1880v2_context_t *ctx, bmk1880v2_tensor_lmem_t *y,
|
||||
bmk1880v2_tensor_lmem_t *x, bmk1880v2_tensor_lmem_t *tl_buf,
|
||||
bmk1880v2_tensor_lmem_t *tl_buf2, bmk1880v2_tensor_lmem_t *tl_buf3,
|
||||
bmk1880v2_tensor_lmem_t *tl_y0_buf,
|
||||
bmk1880v2_tensor_lmem_t *tl_invert_buf,
|
||||
bmk1880v2_tensor_lmem_t *tl_pos_neg_buf,
|
||||
bmk1880v2_tensor_lmem_t *tl_table_answer,
|
||||
bmk1880v2_tensor_lmem_t *tl_table_answer_mantissa,
|
||||
bmk1880v2_tensor_lmem_t *tl_ofmap_bf16, fmt_t fmt);
|
||||
|
||||
void bf16_atan2_merge_emit(bmk1880v2_context_t *ctx, bmk1880v2_tensor_lmem_t *y,
|
||||
bmk1880v2_tensor_lmem_t *x, bmk1880v2_tensor_lmem_t *tl_buf,
|
||||
bmk1880v2_tensor_lmem_t *tl_buf2, bmk1880v2_tensor_lmem_t *tl_buf3,
|
||||
bmk1880v2_tensor_lmem_t *tl_y0_buf,
|
||||
bmk1880v2_tensor_lmem_t *tl_invert_buf,
|
||||
bmk1880v2_tensor_lmem_t *tl_pos_neg_buf,
|
||||
bmk1880v2_tensor_lmem_t *tl_table_answer,
|
||||
bmk1880v2_tensor_lmem_t *tl_table_answer_mantissa,
|
||||
bmk1880v2_tensor_lmem_t *tl_ofmap_bf16, fmt_t fmt);
|
||||
|
||||
|
||||
uint64_t bf16_lut_tbl_bytesize(bmk1880v2_context_t *ctx, bmk1880v2_tensor_lmem_shape_t *table_shape,
|
||||
fmt_t fmt);
|
||||
|
||||
void bf16_atan_tbl(uint16_t *table_data_atan_y0, uint16_t *table_data_atan_slope, uint16_t *table_data_atan_invert,
|
||||
uint16_t *table_data_atan_pos_neg, bmk1880v2_tensor_lmem_shape_t *table_shape);
|
||||
|
||||
void bf16_atan_fast_degree_tbl(uint16_t *table_data_atan_y0, uint16_t *table_data_atan_invert,
|
||||
uint16_t *table_data_atan_pos_neg, bmk1880v2_tensor_lmem_shape_t *table_shape);
|
||||
|
||||
void bf16_gen_0_tbl(uint16_t *table_0, bmk1880v2_tensor_lmem_shape_t *table_shape);
|
||||
|
||||
int bf16_emit_0_idx(bmk1880v2_context_t *ctx, bmk1880v2_tensor_lmem_t *tl_ifmap,
|
||||
bmk1880v2_tensor_lmem_t *tl_buf, bmk1880v2_tensor_lmem_t *tbl_answer,
|
||||
bmk1880v2_tensor_lmem_t *tl_ofmap_bf16, fmt_t fmt);
|
||||
|
||||
int bf16_emit_neg_idx(bmk1880v2_context_t *ctx, bmk1880v2_tensor_lmem_t *tl_ifmap,
|
||||
bmk1880v2_tensor_lmem_t *tl_buf, bmk1880v2_tensor_lmem_t *tl_pos_neg_buf,
|
||||
bmk1880v2_tensor_lmem_t *tl_ofmap_bf16, fmt_t fmt);
|
||||
|
||||
int bf16_emit_pos_idx(bmk1880v2_context_t *ctx, bmk1880v2_tensor_lmem_t *tl_ifmap,
|
||||
bmk1880v2_tensor_lmem_t *tl_buf, bmk1880v2_tensor_lmem_t *tl_pos_neg_buf,
|
||||
bmk1880v2_tensor_lmem_t *tl_ofmap_bf16, fmt_t fmt);
|
||||
|
||||
int bf16_emit_0_1_revert_input(bmk1880v2_context_t *ctx, bmk1880v2_tensor_lmem_t *tl_ifmap,
|
||||
bmk1880v2_tensor_lmem_t *tl_buf,
|
||||
bmk1880v2_tensor_lmem_t *tl_ofmap_bf16, fmt_t fmt);
|
||||
|
||||
void bf16_atan2_emit(bmk1880v2_context_t *ctx, bmk1880v2_tensor_lmem_t *y,
|
||||
bmk1880v2_tensor_lmem_t *x, bmk1880v2_tensor_lmem_t *tl_buf,
|
||||
bmk1880v2_tensor_lmem_t *tl_buf2, bmk1880v2_tensor_lmem_t *tl_buf3,
|
||||
bmk1880v2_tensor_lmem_t *tl_buf4, bmk1880v2_tensor_lmem_t *tl_buf5,
|
||||
bmk1880v2_tensor_lmem_t *tl_buf6, bmk1880v2_tensor_lmem_t *tl_y0_buf,
|
||||
bmk1880v2_tensor_lmem_t *tl_slope_buf, bmk1880v2_tensor_lmem_t *tl_invert_buf,
|
||||
bmk1880v2_tensor_lmem_t *tl_pos_neg_buf,
|
||||
bmk1880v2_tensor_lmem_t *tl_table_answer,
|
||||
bmk1880v2_tensor_lmem_t *tl_table_answer_mantissa,
|
||||
bmk1880v2_tensor_lmem_t *tl_sqrt_table_answer,
|
||||
bmk1880v2_tensor_lmem_t *tl_sqrt_table_answer_mantissa,
|
||||
bmk1880v2_tensor_lmem_t *tl_0_idx_table,
|
||||
bmk1880v2_tensor_lmem_t *tl_ofmap_bf16, fmt_t fmt);
|
||||
|
||||
// nn function
|
||||
int bf16_emit_pythagoras(bmk1880v2_context_t *ctx, bmk1880v2_tensor_lmem_t *y,
|
||||
bmk1880v2_tensor_lmem_t *x, bmk1880v2_tensor_lmem_t *tl_buf,
|
||||
bmk1880v2_tensor_lmem_t *tl_buf2,
|
||||
bmk1880v2_tensor_lmem_t *tl_sqrt_table_answer,
|
||||
bmk1880v2_tensor_lmem_t *tl_sqrt_table_answer_mantissa,
|
||||
bmk1880v2_tensor_lmem_t *tl_ofmap_bf16, fmt_t fmt);
|
||||
|
||||
int bf16_emit_max_const(bmk1880v2_context_t *ctx, bmk1880v2_tensor_lmem_t *tl_ifmap,
|
||||
bmk1880v2_tensor_lmem_t *tl_ofmap_bf16, fmt_t fmt, float b);
|
||||
|
||||
int bf16_emit_min_const(bmk1880v2_context_t *ctx, bmk1880v2_tensor_lmem_t *tl_ifmap,
|
||||
bmk1880v2_tensor_lmem_t *tl_ofmap_bf16, fmt_t fmt, float b);
|
||||
|
||||
int bf16_emit_0_1_revert(bmk1880v2_context_t *ctx, bmk1880v2_tensor_lmem_t *tl_ifmap,
|
||||
bmk1880v2_tensor_lmem_t *tl_buf, bmk1880v2_tensor_lmem_t *tbl_answer,
|
||||
bmk1880v2_tensor_lmem_t *tl_ofmap_bf16, fmt_t fmt);
|
||||
|
||||
int bf16_emit_mul(bmk1880v2_context_t *ctx, bmk1880v2_tensor_lmem_t *tl_ifmap,
|
||||
bmk1880v2_tensor_lmem_t *tl_ifmap2, bmk1880v2_tensor_lmem_t *tl_ofmap_bf16,
|
||||
fmt_t fmt);
|
||||
|
||||
int bf16_emit_add(bmk1880v2_context_t *ctx, bmk1880v2_tensor_lmem_t *tl_ifmap,
|
||||
bmk1880v2_tensor_lmem_t *tl_ifmap2, bmk1880v2_tensor_lmem_t *tl_ofmap_bf16,
|
||||
fmt_t fmt);
|
||||
|
||||
int bf16_emit_add_const(bmk1880v2_context_t *ctx, bmk1880v2_tensor_lmem_t *tl_ifmap,
|
||||
bmk1880v2_tensor_lmem_t *tl_ofmap_bf16, fmt_t fmt, float b);
|
||||
|
||||
int bf16_emit_mul_const(bmk1880v2_context_t *ctx, bmk1880v2_tensor_lmem_t *tl_ifmap,
|
||||
bmk1880v2_tensor_lmem_t *tl_ofmap_bf16, fmt_t fmt, float b);
|
||||
|
||||
// mask please refer \BF16_MASK_TYPE for supported case
|
||||
int bf16_emit_mask_gt0(bmk1880v2_context_t *ctx, bmk1880v2_tensor_lmem_t *tl_ifmap,
|
||||
bmk1880v2_tensor_lmem_t *tl_buf, bmk1880v2_tensor_lmem_t *tl_buf2,
|
||||
bmk1880v2_tensor_lmem_t *tl_buf3, bmk1880v2_tensor_lmem_t *tl_pos_neg_buf,
|
||||
bmk1880v2_tensor_lmem_t *tl_0_idx_buf,
|
||||
bmk1880v2_tensor_lmem_t *tl_ofmap_bf16, fmt_t fmt);
|
||||
|
||||
int bf16_emit_mask_ge0(bmk1880v2_context_t *ctx, bmk1880v2_tensor_lmem_t *tl_ifmap,
|
||||
bmk1880v2_tensor_lmem_t *tl_buf, bmk1880v2_tensor_lmem_t *tl_pos_neg_table,
|
||||
bmk1880v2_tensor_lmem_t *tl_ofmap_bf16, fmt_t fmt);
|
||||
|
||||
int bf16_emit_mask_le0(bmk1880v2_context_t *ctx, bmk1880v2_tensor_lmem_t *tl_ifmap,
|
||||
bmk1880v2_tensor_lmem_t *tl_buf, bmk1880v2_tensor_lmem_t *tl_pos_neg_table,
|
||||
bmk1880v2_tensor_lmem_t *tl_ofmap_bf16, fmt_t fmt);
|
||||
|
||||
int bf16_emit_mask_eq0(bmk1880v2_context_t *ctx, bmk1880v2_tensor_lmem_t *tl_ifmap,
|
||||
bmk1880v2_tensor_lmem_t *tl_buf, bmk1880v2_tensor_lmem_t *tl_0_idx_table,
|
||||
bmk1880v2_tensor_lmem_t *tl_ofmap_bf16, fmt_t fmt);
|
||||
enum BF16_MASK_TYPE {
|
||||
BF16_MASK_TYPE_GT_0 = 0, // remain > 0
|
||||
BF16_MASK_TYPE_GE_0, // remain >= 0
|
||||
BF16_MASK_TYPE_EQ_0, // remain = 0
|
||||
BF16_MASK_TYPE_LT_0, // remain < 0
|
||||
BF16_MASK_TYPE_LE_0, // remain <= 0
|
||||
BF16_MASK_MAX
|
||||
};
|
||||
|
||||
int bf16_emit_mask(bmk1880v2_context_t *ctx, bmk1880v2_tensor_lmem_t *tl_ifmap,
|
||||
bmk1880v2_tensor_lmem_t *tl_buf, bmk1880v2_tensor_lmem_t *tl_buf2,
|
||||
bmk1880v2_tensor_lmem_t *tl_buf3, bmk1880v2_tensor_lmem_t *tl_pos_neg_table,
|
||||
bmk1880v2_tensor_lmem_t *tl_0_idx_table, bmk1880v2_tensor_lmem_t *tl_ofmap_bf16,
|
||||
fmt_t fmt, enum BF16_MASK_TYPE mask);
|
||||
|
||||
int bf16_emit_mask_lt0(bmk1880v2_context_t *ctx, bmk1880v2_tensor_lmem_t *tl_ifmap,
|
||||
bmk1880v2_tensor_lmem_t *tl_buf, bmk1880v2_tensor_lmem_t *tl_pos_neg_table,
|
||||
bmk1880v2_tensor_lmem_t *tl_ofmap_bf16, fmt_t fmt);
|
||||
|
||||
int _bf16_atan_emit(bmk1880v2_context_t *ctx, bmk1880v2_tensor_lmem_t *tl_ifmap,
|
||||
bmk1880v2_tensor_lmem_t *tl_buf, bmk1880v2_tensor_lmem_t *tl_buf2,
|
||||
bmk1880v2_tensor_lmem_t *tl_buf3, bmk1880v2_tensor_lmem_t *tl_y0_buf,
|
||||
bmk1880v2_tensor_lmem_t *tl_slope_buf, bmk1880v2_tensor_lmem_t *tl_invert_buf,
|
||||
bmk1880v2_tensor_lmem_t *tl_pos_neg_buf,
|
||||
bmk1880v2_tensor_lmem_t *tl_table_answer,
|
||||
bmk1880v2_tensor_lmem_t *tl_table_answer_mantissa,
|
||||
bmk1880v2_tensor_lmem_t *tl_ofmap_bf16, fmt_t fmt, float b);
|
||||
|
||||
uint32_t *bm1880v2_reshape_channel_bias(uint8_t *bias, int ni, int ci, int hi, int wi, int old_bias_c,
|
||||
fmt_t fmt);
|
||||
|
||||
int bm1880v2_reshape_channel_same(bmk1880v2_context_t *bk_ctx, int ic, int ih, int iw, int kh,
|
||||
int kw, int pad_right, int pad_left, int stride_h, int stride_w,
|
||||
bmk1880v2_tensor_lmem_shape_t *tl_load_shape,
|
||||
bmk1880v2_tensor_lmem_stride_t *new_tl_ifmap_stride,
|
||||
bmk1880v2_tensor_tgmem_shape_t *new_tg_ifmap_shape,
|
||||
bmk1880v2_tensor_tgmem_stride_t *new_tg_ifmap_stride,
|
||||
bmk1880v2_tensor_lmem_shape_t *new_tl_weight_shape,
|
||||
bmk1880v2_tensor_lmem_shape_t *new_tl_bias_shape,
|
||||
bmk1880v2_tensor_lmem_shape_t *new_tl_ofmap_shape, fmt_t fmt,
|
||||
int eu_align);
|
||||
|
||||
uint8_t *bm1880v2_reshape_channel_weight(uint8_t *weight, int ni, int ci, int hi, int wi, int old_weight_c,
|
||||
fmt_t fmt);
|
||||
|
||||
|
||||
int bm1880v2_reshape_channel_same_pad(
|
||||
bmk1880v2_context_t *bk_ctx,
|
||||
int ic, int ih, int iw, int kh, int kw,
|
||||
int pad_right, int pad_left, int stride_h, int stride_w,
|
||||
bmk1880v2_tensor_lmem_shape_t* tl_load_shape,
|
||||
bmk1880v2_tensor_lmem_stride_t* new_tl_ifmap_stride,
|
||||
bmk1880v2_tensor_tgmem_shape_t* new_tg_ifmap_shape,
|
||||
bmk1880v2_tensor_tgmem_stride_t* new_tg_ifmap_stride,
|
||||
bmk1880v2_tensor_lmem_shape_t* new_tl_weight_shape,
|
||||
bmk1880v2_tensor_lmem_shape_t* new_tl_bias_shape,
|
||||
bmk1880v2_tensor_lmem_shape_t* new_tl_ofmap_shape,
|
||||
fmt_t fmt, int eu_align);
|
||||
|
||||
int bf16_emit_sigmoid(bmk1880v2_context_t *ctx,
|
||||
bmk1880v2_tensor_lmem_t* tl_ifmap,
|
||||
bmk1880v2_tensor_lmem_t* tl_buf,
|
||||
bmk1880v2_tensor_lmem_t *tl_table_answer,
|
||||
bmk1880v2_tensor_lmem_t *tl_table_answer_slope,
|
||||
bmk1880v2_tensor_lmem_t* tl_ofmap_bf16,
|
||||
float scale);
|
||||
|
||||
void bf16_sigmoid_tbl(uint16_t *sigmoid_table_data, uint16_t* sigmoid_table_data_slope,
|
||||
bmk1880v2_tensor_lmem_shape_t* table_shape,
|
||||
int range_start, int range_end);
|
||||
|
||||
float bf16_sigmoid_scale(int range_start, int range_end);
|
||||
|
||||
void bf16_emit_mask_ge0_lt0(
|
||||
bmk1880v2_context_t *ctx,
|
||||
bmk1880v2_tensor_lmem_t* y,
|
||||
bmk1880v2_tensor_lmem_t* index_i8,
|
||||
bmk1880v2_tensor_lmem_t* tl_buf3,
|
||||
fmt_t fmt
|
||||
);
|
||||
|
||||
void bf16_emit_mask_eq_0(
|
||||
bmk1880v2_context_t *ctx,
|
||||
bmk1880v2_tensor_lmem_t* y,
|
||||
bmk1880v2_tensor_lmem_t* tl_buf,
|
||||
bmk1880v2_tensor_lmem_t* index_i8,
|
||||
bmk1880v2_tensor_lmem_t* tl_buf3,
|
||||
fmt_t fmt
|
||||
);
|
||||
|
||||
int bf16_lut_exp_mantissa(bmk1880v2_context_t *ctx, bmk1880v2_tensor_lmem_t *tl_ifmap,
|
||||
bmk1880v2_tensor_lmem_t *tl_buf,
|
||||
bmk1880v2_tensor_lmem_t *tbl_answer,
|
||||
bmk1880v2_tensor_lmem_t *tbl_answer_mantissa,
|
||||
bmk1880v2_tensor_lmem_t *tl_ofmap_bf16);
|
||||
|
||||
int bf16_s2s_fp32_bf16(bmk1880v2_context_t *ctx, uint64_t gaddr_fp32,
|
||||
bmk1880v2_tensor_tgmem_shape_t fp32_shape, uint64_t gaddr_bf16,
|
||||
bmk1880v2_tensor_tgmem_shape_t bf16_shape, fmt_t fmt);
|
||||
|
||||
/**
|
||||
* \gaddr_nc_image for temp gaddr, it could be the same as \gaddr_image
|
||||
* \re_order_gaddr_svm means we re-ordered weight by \unit_size and oc/ic transpose
|
||||
* \svm_shape as alias as weight of conv, record actually shape likes (oc, ic, kh, kw),
|
||||
* the passible shape is <oc, \unit_size, 15, 7>
|
||||
* \unit_size as vecotr size, it should be 36 in HOG
|
||||
*/
|
||||
int bf16_hists_svm(bmk1880v2_context_t *ctx, uint64_t gaddr_image, uint64_t gaddr_nc_image,
|
||||
bmk1880v2_tensor_tgmem_shape_t image_shape, uint64_t re_order_gaddr_svm,
|
||||
bmk1880v2_tensor_tgmem_shape_t svm_shape, // (oc, ic, kh, kw)
|
||||
uint64_t gaddr_output, int unit_size, fmt_t fmt);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __BMKERNEL_1880v2_NON_ATOMIC_H__ */
|
||||
|
||||
115
cvikernel/include/bmkernel/bm_kernel.h
Normal file
115
cvikernel/include/bmkernel/bm_kernel.h
Normal file
@ -0,0 +1,115 @@
|
||||
#ifndef __BM_KERNEL_H__
|
||||
#define __BM_KERNEL_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <math.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <cvikernel/cvikernel.h>
|
||||
|
||||
typedef uint8_t u8;
|
||||
typedef uint16_t u16;
|
||||
typedef uint32_t u32;
|
||||
typedef uint64_t u64;
|
||||
|
||||
typedef int8_t s8;
|
||||
typedef int16_t s16;
|
||||
typedef int32_t s32;
|
||||
typedef int64_t s64;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef int bmerr_t;
|
||||
#define BM_SUCCESS 0 // The operation was successful
|
||||
#define BM_ERR_AGAIN 1 // Not ready yet
|
||||
#define BM_ERR_FAILURE 2 // General failure
|
||||
#define BM_ERR_TIMEOUT 3 // Timeout
|
||||
#define BM_ERR_UNINITIALIZED 4 // Uninitialzed
|
||||
#define BM_ERR_INVALID_ARGUMENT 5 // Arguments invalid
|
||||
#define BM_ERR_NOMEM 6 // Not enough memory
|
||||
#define BM_ERR_DATA 7 // Data error
|
||||
#define BM_ERR_BUSY 8 // Busy
|
||||
#define BM_ERR_NOT_SUPPORTED 9 // Not supported yet
|
||||
|
||||
#define CVI_TPU_TIU 0 // Tensor Instruction Unit
|
||||
#define CVI_TPU_CPU 1 // CPU, Reserved for common cpu op
|
||||
#define CVI_TPU_TDMA 2 // TPU DMA
|
||||
#define CVI_TPU_ENGINE_NUM 3 // Number of Engines
|
||||
|
||||
typedef cvk_fmt_t fmt_t;
|
||||
#define FMT_F32 CVK_FMT_F32
|
||||
#define FMT_F16 CVK_FMT_F16
|
||||
#define FMT_I32 CVK_FMT_I32
|
||||
#define FMT_I16 CVK_FMT_I16
|
||||
#define FMT_I8 CVK_FMT_I8
|
||||
#define FMT_I4 CVK_FMT_I4
|
||||
#define FMT_I2 CVK_FMT_I2
|
||||
#define FMT_I1 CVK_FMT_I1
|
||||
#define FMT_U32 CVK_FMT_U32
|
||||
#define FMT_U16 CVK_FMT_U16
|
||||
#define FMT_U8 CVK_FMT_U8
|
||||
#define FMT_BF16 CVK_FMT_BF16
|
||||
#define FMT_INVALID CVK_FMT_INVALID
|
||||
|
||||
typedef enum _Cmdbuf_Head_Magic {
|
||||
CMDBUF_HDR_MAGIC_1880v2 = 0xA5,
|
||||
CMDBUF_HDR_MAGIC_1822 = 0xA6,
|
||||
CMDBUF_HDR_MAGIC_181X = 0xA7,
|
||||
CMDBUF_HDR_MAGIC_180X = 0xA8,
|
||||
} Cmdbuf_Head_Magic;
|
||||
|
||||
#define BM_CMB_HDR_FLAG_NEURON (0x1)
|
||||
#define BM_CMB_HDR_FLAG_WEIGHT (0x2)
|
||||
|
||||
typedef struct __cmd_hdr_s {
|
||||
uint8_t magic; // 0xA5
|
||||
uint8_t len; // lens in bytes
|
||||
uint8_t engine_id: 4; // TPU, GDMA, CDMA
|
||||
uint8_t __deprecated: 4;
|
||||
uint8_t flags; // CMD_ID, sync flags, etc. TBD
|
||||
uint32_t mask; // bit mask for which register need to write
|
||||
uint8_t cmd[0];
|
||||
} __attribute__((packed)) cmd_hdr_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t chip_version;
|
||||
uint32_t cmdbuf_size;
|
||||
uint8_t *cmdbuf;
|
||||
} bmk_info_t;
|
||||
|
||||
cvk_chip_info_t bmk1880v2_chip_info(void);
|
||||
cvk_chip_info_t bmk1822_chip_info(void);
|
||||
|
||||
static inline int ceiling_func(int numerator, int denominator)
|
||||
{
|
||||
return (numerator + denominator - 1) / denominator;
|
||||
}
|
||||
|
||||
static inline int ceiling_func_shift(int numerator, int shift)
|
||||
{
|
||||
return (numerator + (1 << shift) - 1) >> shift;
|
||||
}
|
||||
|
||||
static inline uint64_t align_up(uint64_t x, uint64_t n)
|
||||
{
|
||||
return (x + n - 1) / n * n;
|
||||
}
|
||||
|
||||
// len max number is 255, sometimes cmd larger than 255
|
||||
static inline uint32_t cmd_hdr_len(cmd_hdr_t * hdr) {
|
||||
if (hdr->len == 0) {
|
||||
return hdr->mask;
|
||||
}
|
||||
return hdr->len;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __BM_KERNEL_H__ */
|
||||
223
cvikernel/include/bmkernel/bm_kernel_legacy.h
Normal file
223
cvikernel/include/bmkernel/bm_kernel_legacy.h
Normal file
@ -0,0 +1,223 @@
|
||||
#ifndef __BM_KERNEL_LEGACY_H__
|
||||
#define __BM_KERNEL_LEGACY_H__
|
||||
|
||||
#include <bmkernel/bm_kernel.h>
|
||||
|
||||
typedef uint32_t laddr_t;
|
||||
typedef uint64_t gaddr_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define LADDR_INVALID (0xFFFFFFFF)
|
||||
#define GADDR_INVALID (0x000000FFFFFFFFFFULL)
|
||||
|
||||
#define FMT_U8_to_F32 0xFF
|
||||
|
||||
#define ENGINE_BD 0 // Broadcast Engine
|
||||
#define ENGINE_CPU 1 // CPU, Reserved
|
||||
#define ENGINE_GDMA 2 // GDMA Engine
|
||||
#define ENGINE_CDMA 3 // CDMA Engine
|
||||
#define ENGINE_END 4 // Invalid
|
||||
|
||||
typedef struct __dma_hdr_t {
|
||||
uint16_t dmabuf_magic_m;
|
||||
uint16_t dmabuf_magic_s;
|
||||
uint32_t dmabuf_size;
|
||||
uint32_t cpu_desc_count;
|
||||
uint32_t bd_desc_count; //16bytes
|
||||
uint32_t tdma_desc_count;
|
||||
uint32_t tpu_clk_rate;
|
||||
uint32_t pmubuf_size;
|
||||
uint32_t pmubuf_offset; //32bytes
|
||||
uint32_t arraybase_0_L;
|
||||
uint32_t arraybase_0_H;
|
||||
uint32_t arraybase_1_L;
|
||||
uint32_t arraybase_1_H; //48bytes
|
||||
uint32_t arraybase_2_L;
|
||||
uint32_t arraybase_2_H;
|
||||
uint32_t arraybase_3_L;
|
||||
uint32_t arraybase_3_H; //64bytes
|
||||
|
||||
uint32_t arraybase_4_L;
|
||||
uint32_t arraybase_4_H;
|
||||
uint32_t arraybase_5_L;
|
||||
uint32_t arraybase_5_H;
|
||||
uint32_t arraybase_6_L;
|
||||
uint32_t arraybase_6_H;
|
||||
uint32_t arraybase_7_L;
|
||||
uint32_t arraybase_7_H;
|
||||
uint32_t reserve[8]; //128bytes, 128bytes align
|
||||
} dma_hdr_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t version;
|
||||
uint32_t npu_num;
|
||||
uint32_t eu_num;
|
||||
uint32_t lmem_size;
|
||||
uint32_t lmem_banks;
|
||||
uint32_t lmem_bank_size;
|
||||
} bmk_chip_info_t;
|
||||
|
||||
#define FLOAT_SIZE 4
|
||||
#define INT8_SIZE 1
|
||||
#define BF16_SIZE 2
|
||||
|
||||
#define UNUSED(x) (void)(x)
|
||||
|
||||
#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))
|
||||
#define ALIGN(x,a) __ALIGN_MASK(x,(__typeof__(x))(a)-1)
|
||||
#define ALIGN_DOWN(x, a) ((x) / (a) * (a))
|
||||
|
||||
#define math_min(x, y) ((x) < (y) ? (x) : (y))
|
||||
#define math_max(x, y) ((x) > (y) ? (x) : (y))
|
||||
|
||||
static inline int get_num_shift(uint64_t num)
|
||||
{
|
||||
int n = 0;
|
||||
while (!(num & 1)) {
|
||||
n++;
|
||||
num >>= 1;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
uint32_t dim;
|
||||
uint32_t n;
|
||||
uint32_t c;
|
||||
union {
|
||||
uint32_t h;
|
||||
uint32_t row;
|
||||
};
|
||||
union {
|
||||
uint32_t w;
|
||||
uint32_t col;
|
||||
};
|
||||
} shape_t;
|
||||
|
||||
shape_t shape_t4(int n, int c, int h, int w);
|
||||
shape_t shape_t3(int d3, int d2, int d1);
|
||||
shape_t shape_t2(int row, int col);
|
||||
shape_t shape_t1(int len);
|
||||
|
||||
uint8_t shape_equal(shape_t s1, shape_t s2);
|
||||
|
||||
typedef struct {
|
||||
uint32_t n;
|
||||
uint32_t c;
|
||||
union {
|
||||
uint32_t h;
|
||||
uint32_t row;
|
||||
};
|
||||
union {
|
||||
uint32_t w;
|
||||
uint32_t col;
|
||||
};
|
||||
} stride_t;
|
||||
|
||||
static inline stride_t stride_st4(int n, int c, int h, int w)
|
||||
{
|
||||
stride_t st;
|
||||
st.n = n;
|
||||
st.c = c;
|
||||
st.h = h;
|
||||
st.w = w;
|
||||
return st;
|
||||
}
|
||||
|
||||
typedef uint32_t ctrl_t;
|
||||
#define CTRL_NULL 0
|
||||
#define CTRL_AL (1 << 0) // alloc aligned with EU_NUM
|
||||
#define CTRL_RA (1 << 2) // result add
|
||||
#define CTRL_BN (1 << 3) // B_N_is_1 broadcast to A
|
||||
#define CTRL_TP (1 << 5) // transpose
|
||||
#define CTRL_ADDR_ALIGN (1 << 7)
|
||||
#define CTRL_RELU (1 << 8)
|
||||
#define CTRL_KFLIP (1 << 9) // kernel flip
|
||||
#define CTRL_WEIGHT (1 << 10) // mark weight address in GDMA
|
||||
#define CTRL_NEURON (1 << 11) // mark neuron address in GDMA
|
||||
#define CTRL_WINOGRAD (1 << 12) // GDMA reshap winograd kernel
|
||||
#define CTRL_WINOGRAD_SCALE_FACTOR (1 << 28) // GDMA reshap winograd kernel
|
||||
|
||||
typedef uint32_t tl_type;
|
||||
#define TL_TYPE_TENSOR 0
|
||||
#define TL_TYPE_TENSOR_PREALLOC 1
|
||||
#define TL_TYPE_CONSTANT 2
|
||||
#define TL_TYPE_SLICE 3
|
||||
#define TL_TYPE_CLONE 4
|
||||
|
||||
typedef union {
|
||||
uint32_t reg_val;
|
||||
float fp32_val;
|
||||
} const_fp32_t;
|
||||
|
||||
typedef union {
|
||||
laddr_t laddr;
|
||||
const_fp32_t const_fp32;
|
||||
} opd_t;
|
||||
|
||||
typedef struct {
|
||||
tl_type type;
|
||||
opd_t operand;
|
||||
shape_t shape;
|
||||
stride_t *stride;
|
||||
uint8_t aligned;
|
||||
fmt_t fmt;
|
||||
uint32_t bank_id;
|
||||
int reserved_size;
|
||||
} tensor_lmem;
|
||||
|
||||
static inline laddr_t tl_address(tensor_lmem *tlp)
|
||||
{
|
||||
if (tlp->type == TL_TYPE_CONSTANT) {
|
||||
return LADDR_INVALID;
|
||||
}
|
||||
return tlp->operand.laddr;
|
||||
}
|
||||
|
||||
void tl_reshape(tensor_lmem * tlp, shape_t shape);
|
||||
|
||||
typedef struct {
|
||||
uint64_t addr;
|
||||
shape_t shape;
|
||||
stride_t stride;
|
||||
} tensor_gmem;
|
||||
|
||||
static inline int tg_is_matrix(tensor_gmem *t)
|
||||
{
|
||||
return t->shape.dim == 2;
|
||||
}
|
||||
|
||||
static inline int tg_matrix_row(tensor_gmem *t)
|
||||
{
|
||||
return t->shape.row;
|
||||
}
|
||||
|
||||
static inline int tg_matrix_col(tensor_gmem *t)
|
||||
{
|
||||
return t->shape.col;
|
||||
}
|
||||
|
||||
static inline int tl_is_const(tensor_lmem *tlp)
|
||||
{
|
||||
return tlp->type == TL_TYPE_CONSTANT;
|
||||
}
|
||||
|
||||
static inline int tl_is_prealloc(tensor_lmem *tlp)
|
||||
{
|
||||
return tlp->type == TL_TYPE_TENSOR_PREALLOC;
|
||||
}
|
||||
|
||||
static inline int tl_is_matrix(tensor_lmem *tlp)
|
||||
{
|
||||
int dim = tlp->shape.dim;
|
||||
return dim == 1 || dim == 2;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __BM_KERNEL_LEGACY_H__ */
|
||||
72
cvikernel/include/bmkernel/bm_regcpu.h
Normal file
72
cvikernel/include/bmkernel/bm_regcpu.h
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright Bitmain Technologies Inc.
|
||||
*
|
||||
* Written by:
|
||||
* Wanwei CAI <wanwei.cai@bitmain.com>
|
||||
* Created Time: 2017-06-29 15:33
|
||||
*/
|
||||
|
||||
#ifndef _BM_REG_CPU_H
|
||||
#define _BM_REG_CPU_H
|
||||
|
||||
#include <bmkernel/bm_kernel.h>
|
||||
|
||||
#define CPU_ENGINE_DESCRIPTOR_NUM 56
|
||||
#define CPU_ENGINE_DESCRIPTOR_DMA_NUM CPU_ENGINE_DESCRIPTOR_NUM
|
||||
#define CPU_ENGINE_BYTES (CPU_ENGINE_DESCRIPTOR_NUM*sizeof(uint32_t))
|
||||
#define CPU_ENGINE_STR_LIMIT_BYTE (CPU_ENGINE_DESCRIPTOR_NUM - 7) * sizeof(uint32_t)
|
||||
|
||||
#define CPU_CMD_ACCPI0 0
|
||||
#define CPU_CMD_ACCPI1 1
|
||||
#define CPU_CMD_ACCPI2 2
|
||||
#define CPU_CMD_ACCPI3 3
|
||||
#define CPU_CMD_ACCPI4 4
|
||||
/* CPU_CMD_ACCPI5 ~ CPU_CMD_ACCPI63
|
||||
defined here if needed */
|
||||
|
||||
#define CPU_ACCPI0_OP_BIT 0
|
||||
#define CPU_ACCPI1_BD_CMDID_BIT 0
|
||||
#define CPU_ACCPI1_CPU_CMDID_BIT 16
|
||||
#define CPU_ACCPI2_GDMA_CMDID_BIT 0
|
||||
#define CPU_ACCPI2_CDMA_CMDID_BIT 16
|
||||
#define CPU_ACCPI3_NEXT_BD_ADDR_BIT 0
|
||||
#define CPU_ACCPI4_NEXT_GDMA_ADDR_BIT 0
|
||||
#define CPU_ACCPI5_NEXT_CDMA_ADDR_BIT 0
|
||||
|
||||
typedef enum {
|
||||
CPU_OP_SYNC = 2,
|
||||
CPU_OP_INST = 3,
|
||||
CPU_OP_END
|
||||
} CPU_OP;
|
||||
|
||||
// CPU common structure
|
||||
typedef struct {
|
||||
uint32_t regs[CPU_ENGINE_DESCRIPTOR_NUM];
|
||||
} bmk_cpu_desc_t;
|
||||
|
||||
// CPU_OP_SYNC structure
|
||||
typedef struct {
|
||||
uint32_t op_type; // CPU_CMD_ACCPI0
|
||||
uint32_t num_bd; // CPU_CMD_ACCPI1
|
||||
uint32_t num_gdma; // CPU_CMD_ACCPI2
|
||||
uint32_t offset_bd; // CPU_CMD_ACCPI3
|
||||
uint32_t offset_gdma; // CPU_CMD_ACCPI4
|
||||
uint32_t reserved[2]; // CPU_CMD_ACCPI5-CPU_CMD_ACCPI6
|
||||
char str[CPU_ENGINE_STR_LIMIT_BYTE];
|
||||
} __attribute__((packed)) bmk_cpu_sync_desc_t;
|
||||
|
||||
// CPU_OP_INST structure
|
||||
#define CPU_INST_HEADER_COUNT 12
|
||||
typedef struct {
|
||||
uint32_t op_type; // CPU_CMD_ACCPI0
|
||||
uint32_t num_bd; // CPU_CMD_ACCPI1
|
||||
uint32_t num_gdma; // CPU_CMD_ACCPI2
|
||||
uint32_t offset_bd; // CPU_CMD_ACCPI3
|
||||
uint32_t offset_gdma; // CPU_CMD_ACCPI4
|
||||
uint32_t reserved[2]; // CPU_CMD_ACCPI5-CPU_CMD_ACCPI6
|
||||
char lib_name[4*sizeof(uint32_t)]; // CPU_CMD_ACCPI7~CPU_CMD_ACCPI10
|
||||
uint32_t param_size; //CPU_CMD_ACCPI11
|
||||
uint8_t param[0];
|
||||
} __attribute__((packed)) bmk_cpu_inst_desc_t;
|
||||
|
||||
#endif
|
||||
37
cvikernel/include/bmkernel/reg_bdcast.h
Normal file
37
cvikernel/include/bmkernel/reg_bdcast.h
Normal file
@ -0,0 +1,37 @@
|
||||
#ifndef REG_BDCAST_H
|
||||
#define REG_BDCAST_H
|
||||
|
||||
#define BD_ENGINE_DESCRIPTOR_NUM 28
|
||||
#define BD_REG_BYTES (BD_ENGINE_DESCRIPTOR_NUM * 4)
|
||||
#define BDC_ENGINE_CMD_ALIGNED_BIT 8
|
||||
|
||||
#define BD_CMD_BASE_ADDR (TIU_ENGINE_BASE_ADDR + 0)
|
||||
#define BD_CTRL_BASE_ADDR (TIU_ENGINE_BASE_ADDR + 0x100)
|
||||
#define BD_ENGINE_MAIN_CTRL (TIU_ENGINE_BASE_ADDR + 0)
|
||||
#define BD_ENGINE_DESC_ADDR (TIU_ENGINE_BASE_ADDR + 0x4)
|
||||
|
||||
//
|
||||
// BD operations for BIRD
|
||||
//
|
||||
#define DCR_TYPE_CONV_FIX8B 0
|
||||
#define DCR_TYPE_DEPTHWISE_POOL_FIX8B 1
|
||||
#define DCR_TYPE_FC_FIX8B 2
|
||||
#define DCR_TYPE_TENSOR_ARITH_FIX8B 3
|
||||
#define DCR_TYPE_FC_TYPE_2_FIX8B 4
|
||||
|
||||
// BD control bits base on BD_CTRL_BASE_ADDR
|
||||
#define BD_TPU_EN 0 // TPU Enable bit
|
||||
#define BD_LANE_NUM 22 // Lane number bit[29:22]
|
||||
#define BD_DES_ADDR_VLD 30 // enable descriptor mode
|
||||
#define BD_INTR_ENABLE 31 // TIU interrupt global enable
|
||||
|
||||
typedef enum _TIU_LANNUM {
|
||||
TIU_LANNUM_2 = 0x1,
|
||||
TIU_LANNUM_4 = 0x2,
|
||||
TIU_LANNUM_8 = 0x3,
|
||||
TIU_LANNUM_16 = 0x4,
|
||||
TIU_LANNUM_32 = 0x5,
|
||||
TIU_LANNUM_64 = 0x6,
|
||||
} TIU_LANNUM;
|
||||
|
||||
#endif /* REG_BDCAST_H */
|
||||
98
cvikernel/include/bmkernel/reg_tdma.h
Normal file
98
cvikernel/include/bmkernel/reg_tdma.h
Normal file
@ -0,0 +1,98 @@
|
||||
#ifndef REG_GDMA_H
|
||||
#define REG_GDMA_H
|
||||
|
||||
#define TDMA_DESC_REG_BYTES (0x40)
|
||||
#define TDMA_ENGINE_DESCRIPTOR_NUM (TDMA_DESC_REG_BYTES >> 2)
|
||||
#define TDMA_NUM_BASE_REGS (0x8)
|
||||
|
||||
//backward compatible?
|
||||
#define GDMA_TYPE_f32 0
|
||||
#define GDMA_TYPE_f16 1
|
||||
#define GDMA_TYPE_i32 2
|
||||
#define GDMA_TYPE_i16 3
|
||||
#define GDMA_TYPE_i8 4
|
||||
#define GDMA_TYPE_i4 5
|
||||
#define GDMA_TYPE_i2 6
|
||||
#define GDMA_TYPE_i1 7
|
||||
#define LAST_GDMA_TYPE_i1 8
|
||||
|
||||
|
||||
//tdma descriptor define
|
||||
#define TDMA_DESCRIPTOR_ALIGNED_BIT 6
|
||||
|
||||
#define TDMA_CMD_ACCP0 0
|
||||
#define TDMA_CMD_ACCP1 4
|
||||
#define TDMA_CMD_ACCP2 8
|
||||
#define TDMA_CMD_ACCP3 12
|
||||
#define TDMA_CMD_ACCP4 16
|
||||
#define TDMA_CMD_ACCP5 20
|
||||
#define TDMA_CMD_ACCP6 24
|
||||
#define TDMA_CMD_ACCP7 28
|
||||
#define TDMA_CMD_ACCP8 32
|
||||
#define TDMA_CMD_ACCP9 36
|
||||
#define TDMA_CMD_ACCP10 40
|
||||
#define TDMA_CMD_ACCP11 44
|
||||
#define TDMA_CMD_ACCP12 48
|
||||
#define TDMA_CMD_ACCP13 52
|
||||
#define TDMA_CMD_ACCP14 56
|
||||
|
||||
#define TDMA_ACCPI0_CMD_VALID_BIT 0
|
||||
#define TDMA_ACCPI0_EOD_BIT 2
|
||||
#define TDMA_ACCPI0_INTERRUPT_BIT 3
|
||||
#define TDMA_ACCPI0_BARRIER_ENABLE_BIT 4
|
||||
|
||||
|
||||
//tdma control define
|
||||
#define TDMA_CTRL (TDMA_ENGINE_BASE_ADDR + 0x0)
|
||||
#define TDMA_DES_BASE (TDMA_ENGINE_BASE_ADDR + 0x4)
|
||||
#define TDMA_INT_MASK (TDMA_ENGINE_BASE_ADDR + 0x8)
|
||||
#define TDMA_SYNC_STATUS (TDMA_ENGINE_BASE_ADDR + 0xC)
|
||||
#define TDMA_ARRAYBASE0_L (TDMA_ENGINE_BASE_ADDR + 0x70)
|
||||
#define TDMA_ARRAYBASE1_L (TDMA_ENGINE_BASE_ADDR + 0x74)
|
||||
#define TDMA_ARRAYBASE2_L (TDMA_ENGINE_BASE_ADDR + 0x78)
|
||||
#define TDMA_ARRAYBASE3_L (TDMA_ENGINE_BASE_ADDR + 0x7C)
|
||||
#define TDMA_ARRAYBASE4_L (TDMA_ENGINE_BASE_ADDR + 0x80)
|
||||
#define TDMA_ARRAYBASE5_L (TDMA_ENGINE_BASE_ADDR + 0x84)
|
||||
#define TDMA_ARRAYBASE6_L (TDMA_ENGINE_BASE_ADDR + 0x88)
|
||||
#define TDMA_ARRAYBASE7_L (TDMA_ENGINE_BASE_ADDR + 0x8C)
|
||||
#define TDMA_ARRAYBASE0_H (TDMA_ENGINE_BASE_ADDR + 0x90)
|
||||
#define TDMA_ARRAYBASE1_H (TDMA_ENGINE_BASE_ADDR + 0x94)
|
||||
#define TDMA_DEBUG_MODE (TDMA_ENGINE_BASE_ADDR + 0xA0)
|
||||
|
||||
|
||||
|
||||
#define TDMA_CTRL_ENABLE_BIT 0
|
||||
#define TDMA_CTRL_MODESEL_BIT 1
|
||||
#define TDMA_CTRL_RESET_SYNCID_BIT 2
|
||||
#define TDMA_CTRL_FORCE_1ARRAY 5
|
||||
#define TDMA_CTRL_FORCE_2ARRAY 6
|
||||
#define TDMA_CTRL_BURSTLEN_BIT 8
|
||||
#define TDMA_CTRL_64BYTE_ALIGN_EN 10
|
||||
#define TDMA_CTRL_DESNUM_BIT 16
|
||||
|
||||
|
||||
|
||||
|
||||
//This function only supports the following condition
|
||||
//localmem2tensor or tensor2localmem
|
||||
//The source and dst shares the the same format
|
||||
//Data is 32 bit
|
||||
//no stride
|
||||
//We use it in the forward_cpu backward_cpu
|
||||
static inline int get_index_data_format(int size)
|
||||
{
|
||||
if (size == 1) {
|
||||
return GDMA_TYPE_i1;
|
||||
} else if (size <= 16) {
|
||||
return GDMA_TYPE_i4;
|
||||
} else if (size <= 256){
|
||||
return GDMA_TYPE_i8;
|
||||
} else {
|
||||
return GDMA_TYPE_i16;
|
||||
}
|
||||
}
|
||||
#define LRN_LEFT_SHIFT 0
|
||||
#define LRN_RIGHT_SHIFT 1
|
||||
|
||||
#endif /* REG_GDMA_H */
|
||||
|
||||
20
cvikernel/include/bmkernel/reg_tiu.h
Normal file
20
cvikernel/include/bmkernel/reg_tiu.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef REG_TIU_H
|
||||
#define REG_TIU_H
|
||||
|
||||
#define TIU_DESC_REG_BYTES (0x70)
|
||||
#define TIU_ENGINE_DESCRIPTOR_NUM (TIU_DESC_REG_BYTES >> 2)
|
||||
|
||||
// TIU operation data type
|
||||
#define DCR_TYPE_CONV_FIX8B 0
|
||||
#define DCR_TYPE_DEPTHWISE_POOL_FIX8B 1
|
||||
#define DCR_TYPE_FC_FIX8B 2
|
||||
#define DCR_TYPE_TENSOR_ARITH_FIX8B 3
|
||||
#define NR_DCR_TYPES 4
|
||||
|
||||
// BD control bits base on BD_CTRL_BASE_ADDR
|
||||
#define BD_TPU_EN 0 // TPU Enable bit
|
||||
#define BD_LANE_NUM 22 // Lane number bit[29:22]
|
||||
#define BD_DES_ADDR_VLD 30 // enable descriptor mode
|
||||
#define BD_INTR_ENABLE 31 // TIU interrupt global enable
|
||||
|
||||
#endif /* REG_TIU_H */
|
||||
310
cvikernel/include/cvikernel/cv180x/cv180x_tdma_reg.h
Normal file
310
cvikernel/include/cvikernel/cv180x/cv180x_tdma_reg.h
Normal file
@ -0,0 +1,310 @@
|
||||
#ifndef CV180X_TDMA_REG_H
|
||||
#define CV180X_TDMA_REG_H
|
||||
|
||||
/*
|
||||
* This file is generated by tools. Do not edit it manually.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define TDMA_DESC_REG_BYTES (0x40)
|
||||
#define TDMA_ENGINE_DESCRIPTOR_NUM (TDMA_DESC_REG_BYTES >> 2)
|
||||
#define TDMA_NUM_BASE_REGS (0x8)
|
||||
|
||||
typedef unsigned long long ullong;
|
||||
|
||||
typedef struct {
|
||||
uint32_t vld;
|
||||
uint32_t compress_en;
|
||||
uint32_t eod;
|
||||
uint32_t intp_en;
|
||||
uint32_t bar_en;
|
||||
uint32_t check_bf16_value;
|
||||
uint32_t trans_dir;
|
||||
uint32_t rsv00;
|
||||
uint32_t trans_fmt;
|
||||
uint32_t transpose_md;
|
||||
uint32_t rsv01;
|
||||
uint32_t intra_cmd_paral;
|
||||
uint32_t outstanding_en;
|
||||
uint32_t cmd_id;
|
||||
uint32_t spec_func;
|
||||
uint32_t dst_fmt;
|
||||
uint32_t src_fmt;
|
||||
uint32_t cmprs_fmt;
|
||||
uint32_t sys_dtype;
|
||||
uint32_t rsv2_1;
|
||||
uint32_t int8_sign;
|
||||
uint32_t compress_zero_guard;
|
||||
uint32_t int8_rnd_mode;
|
||||
uint32_t wait_id_tpu;
|
||||
uint32_t wait_id_other_tdma;
|
||||
uint32_t wait_id_sdma;
|
||||
uint32_t const_val;
|
||||
uint32_t src_base_reg_sel;
|
||||
uint32_t mv_lut_idx;
|
||||
uint32_t dst_base_reg_sel;
|
||||
uint32_t mv_lut_base;
|
||||
uint32_t rsv4_5;
|
||||
uint32_t dst_h_stride;
|
||||
uint32_t dst_c_stride_low;
|
||||
uint32_t dst_n_stride;
|
||||
uint32_t src_h_stride;
|
||||
uint32_t src_c_stride_low;
|
||||
uint32_t src_n_stride;
|
||||
uint32_t dst_c;
|
||||
uint32_t src_c;
|
||||
uint32_t dst_w;
|
||||
uint32_t dst_h;
|
||||
uint32_t src_w;
|
||||
uint32_t src_h;
|
||||
uint32_t dst_base_addr_low;
|
||||
uint32_t src_base_addr_low;
|
||||
uint32_t src_n;
|
||||
uint32_t dst_base_addr_high;
|
||||
uint32_t src_base_addr_high;
|
||||
uint32_t src_c_stride_high;
|
||||
uint32_t dst_c_stride_high;
|
||||
uint32_t compress_bias0;
|
||||
uint32_t compress_bias1;
|
||||
uint32_t layer_ID;
|
||||
} tdma_reg_t;
|
||||
|
||||
static inline void parse_tdma_reg(tdma_reg_t *r, const uint32_t *p)
|
||||
{
|
||||
r->vld = p[0] & 1;
|
||||
r->compress_en = (p[0] >> 1) & 1;
|
||||
r->eod = (p[0] >> 2) & 1;
|
||||
r->intp_en = (p[0] >> 3) & 1;
|
||||
r->bar_en = (p[0] >> 4) & 1;
|
||||
r->check_bf16_value = (p[0] >> 5) & 1;
|
||||
r->trans_dir = (p[0] >> 6) & ((1u << 2) - 1);
|
||||
r->rsv00 = (p[0] >> 8) & ((1u << 2) - 1);
|
||||
r->trans_fmt = (p[0] >> 10) & 1;
|
||||
r->transpose_md = (p[0] >> 11) & ((1u << 2) - 1);
|
||||
r->rsv01 = (p[0] >> 13) & 1;
|
||||
r->intra_cmd_paral = (p[0] >> 14) & 1;
|
||||
r->outstanding_en = (p[0] >> 15) & 1;
|
||||
r->cmd_id = (p[0] >> 16) & ((1u << 16) - 1);
|
||||
r->spec_func = p[1] & ((1u << 3) - 1);
|
||||
r->dst_fmt = (p[1] >> 3) & ((1u << 2) - 1);
|
||||
r->src_fmt = (p[1] >> 5) & ((1u << 2) - 1);
|
||||
r->cmprs_fmt = (p[1] >> 7) & 1;
|
||||
r->sys_dtype = (p[1] >> 8) & 1;
|
||||
r->rsv2_1 = (p[1] >> 9) & ((1u << 4) - 1);
|
||||
r->int8_sign = (p[1] >> 13) & 1;
|
||||
r->compress_zero_guard = (p[1] >> 14) & 1;
|
||||
r->int8_rnd_mode = (p[1] >> 15) & 1;
|
||||
r->wait_id_tpu = (p[1] >> 16) & ((1u << 16) - 1);
|
||||
r->wait_id_other_tdma = p[2] & ((1u << 16) - 1);
|
||||
r->wait_id_sdma = (p[2] >> 16) & ((1u << 16) - 1);
|
||||
r->const_val = p[3] & ((1u << 16) - 1);
|
||||
r->src_base_reg_sel = (p[3] >> 16) & ((1u << 3) - 1);
|
||||
r->mv_lut_idx = (p[3] >> 19) & 1;
|
||||
r->dst_base_reg_sel = (p[3] >> 20) & ((1u << 3) - 1);
|
||||
r->mv_lut_base = (p[3] >> 23) & 1;
|
||||
r->rsv4_5 = (p[3] >> 24) & ((1u << 8) - 1);
|
||||
r->dst_h_stride = p[4] & ((1u << 16) - 1);
|
||||
r->dst_c_stride_low = (p[4] >> 16) & ((1u << 16) - 1);
|
||||
r->dst_n_stride = p[5];
|
||||
r->src_h_stride = p[6] & ((1u << 16) - 1);
|
||||
r->src_c_stride_low = (p[6] >> 16) & ((1u << 16) - 1);
|
||||
r->src_n_stride = p[7];
|
||||
r->dst_c = p[8] & ((1u << 16) - 1);
|
||||
r->src_c = (p[8] >> 16) & ((1u << 16) - 1);
|
||||
r->dst_w = p[9] & ((1u << 16) - 1);
|
||||
r->dst_h = (p[9] >> 16) & ((1u << 16) - 1);
|
||||
r->src_w = p[10] & ((1u << 16) - 1);
|
||||
r->src_h = (p[10] >> 16) & ((1u << 16) - 1);
|
||||
r->dst_base_addr_low = p[11];
|
||||
r->src_base_addr_low = p[12];
|
||||
r->src_n = p[13] & ((1u << 16) - 1);
|
||||
r->dst_base_addr_high = (p[13] >> 16) & ((1u << 8) - 1);
|
||||
r->src_base_addr_high = (p[13] >> 24) & ((1u << 8) - 1);
|
||||
r->src_c_stride_high = p[14] & ((1u << 16) - 1);
|
||||
r->dst_c_stride_high = (p[14] >> 16) & ((1u << 16) - 1);
|
||||
r->compress_bias0 = p[15] & ((1u << 8) - 1);
|
||||
r->compress_bias1 = (p[15] >> 8) & ((1u << 8) - 1);
|
||||
r->layer_ID = (p[15] >> 16) & ((1u << 16) - 1);
|
||||
}
|
||||
|
||||
static inline void emit_tdma_reg(const tdma_reg_t *r, uint32_t *_p)
|
||||
{
|
||||
volatile uint32_t *p = (typeof(p))_p;
|
||||
p[15] = (r->compress_bias0 & ((1u << 8) - 1)) |
|
||||
((r->compress_bias1 & ((1u << 8) - 1)) << 8) |
|
||||
((r->layer_ID & ((1u << 16) - 1)) << 16);
|
||||
p[14] = (r->src_c_stride_high & ((1u << 16) - 1)) |
|
||||
((r->dst_c_stride_high & ((1u << 16) - 1)) << 16);
|
||||
p[13] = (r->src_n & ((1u << 16) - 1)) |
|
||||
((r->dst_base_addr_high & ((1u << 8) - 1)) << 16) |
|
||||
((r->src_base_addr_high & ((1u << 8) - 1)) << 24);
|
||||
p[12] = (r->src_base_addr_low & (((uint64_t)1 << 32) - 1));
|
||||
p[11] = (r->dst_base_addr_low & (((uint64_t)1 << 32) - 1));
|
||||
p[10] = (r->src_w & ((1u << 16) - 1)) |
|
||||
((r->src_h & ((1u << 16) - 1)) << 16);
|
||||
p[9] = (r->dst_w & ((1u << 16) - 1)) |
|
||||
((r->dst_h & ((1u << 16) - 1)) << 16);
|
||||
p[8] = (r->dst_c & ((1u << 16) - 1)) |
|
||||
((r->src_c & ((1u << 16) - 1)) << 16);
|
||||
p[7] = (r->src_n_stride & (((uint64_t)1 << 32) - 1));
|
||||
p[6] = (r->src_h_stride & ((1u << 16) - 1)) |
|
||||
((r->src_c_stride_low & ((1u << 16) - 1)) << 16);
|
||||
p[5] = (r->dst_n_stride & (((uint64_t)1 << 32) - 1));
|
||||
p[4] = (r->dst_h_stride & ((1u << 16) - 1)) |
|
||||
((r->dst_c_stride_low & ((1u << 16) - 1)) << 16);
|
||||
p[3] = (r->const_val & ((1u << 16) - 1)) |
|
||||
((r->src_base_reg_sel & ((1u << 3) - 1)) << 16) |
|
||||
((r->mv_lut_idx & 1) << 19) |
|
||||
((r->dst_base_reg_sel & ((1u << 3) - 1)) << 20) |
|
||||
((r->mv_lut_base & 1) << 23) |
|
||||
((r->rsv4_5 & ((1u << 8) - 1)) << 24);
|
||||
p[2] = (r->wait_id_other_tdma & ((1u << 16) - 1)) |
|
||||
((r->wait_id_sdma & ((1u << 16) - 1)) << 16);
|
||||
p[1] = (r->spec_func & ((1u << 3) - 1)) |
|
||||
((r->dst_fmt & ((1u << 2) - 1)) << 3) |
|
||||
((r->src_fmt & ((1u << 2) - 1)) << 5) |
|
||||
((r->cmprs_fmt & 1) << 7) |
|
||||
((r->sys_dtype & 1) << 8) |
|
||||
((r->rsv2_1 & ((1u << 4) - 1)) << 9) |
|
||||
((r->int8_sign & 1) << 13) |
|
||||
((r->compress_zero_guard & 1) << 14) |
|
||||
((r->int8_rnd_mode & 1) << 15) |
|
||||
((r->wait_id_tpu & ((1u << 16) - 1)) << 16);
|
||||
p[0] = (r->vld & 1) |
|
||||
((r->compress_en & 1) << 1) |
|
||||
((r->eod & 1) << 2) |
|
||||
((r->intp_en & 1) << 3) |
|
||||
((r->bar_en & 1) << 4) |
|
||||
((r->check_bf16_value & 1) << 5) |
|
||||
((r->trans_dir & ((1u << 2) - 1)) << 6) |
|
||||
((r->rsv00 & ((1u << 2) - 1)) << 8) |
|
||||
((r->trans_fmt & 1) << 10) |
|
||||
((r->transpose_md & ((1u << 2) - 1)) << 11) |
|
||||
((r->rsv01 & 1) << 13) |
|
||||
((r->intra_cmd_paral & 1) << 14) |
|
||||
((r->outstanding_en & 1) << 15) |
|
||||
((r->cmd_id & ((1u << 16) - 1)) << 16);
|
||||
}
|
||||
|
||||
static inline void reset_tdma_reg(tdma_reg_t *r)
|
||||
{
|
||||
r->vld = 0x0;
|
||||
r->compress_en = 0x0;
|
||||
r->eod = 0x0;
|
||||
r->intp_en = 0x0;
|
||||
r->bar_en = 0x0;
|
||||
r->check_bf16_value = 0x0;
|
||||
r->trans_dir = 0x0;
|
||||
r->rsv00 = 0x0;
|
||||
r->trans_fmt = 0x0;
|
||||
r->transpose_md = 0x0;
|
||||
r->rsv01 = 0x0;
|
||||
r->intra_cmd_paral = 0x0;
|
||||
r->outstanding_en = 0x0;
|
||||
r->cmd_id = 0x0;
|
||||
r->spec_func = 0x0;
|
||||
r->dst_fmt = 0x1;
|
||||
r->src_fmt = 0x1;
|
||||
r->cmprs_fmt = 0x0;
|
||||
r->sys_dtype = 0x0;
|
||||
r->rsv2_1 = 0x0;
|
||||
r->int8_sign = 0x0;
|
||||
r->compress_zero_guard = 0x0;
|
||||
r->int8_rnd_mode = 0x0;
|
||||
r->wait_id_tpu = 0x0;
|
||||
r->wait_id_other_tdma = 0x0;
|
||||
r->wait_id_sdma = 0x0;
|
||||
r->const_val = 0x0;
|
||||
r->src_base_reg_sel = 0x0;
|
||||
r->mv_lut_idx = 0x0;
|
||||
r->dst_base_reg_sel = 0x0;
|
||||
r->mv_lut_base = 0x0;
|
||||
r->rsv4_5 = 0x0;
|
||||
r->dst_h_stride = 0x1;
|
||||
r->dst_c_stride_low = 0x1;
|
||||
r->dst_n_stride = 0x1;
|
||||
r->src_h_stride = 0x1;
|
||||
r->src_c_stride_low = 0x1;
|
||||
r->src_n_stride = 0x1;
|
||||
r->dst_c = 0x1;
|
||||
r->src_c = 0x1;
|
||||
r->dst_w = 0x1;
|
||||
r->dst_h = 0x1;
|
||||
r->src_w = 0x1;
|
||||
r->src_h = 0x1;
|
||||
r->dst_base_addr_low = 0x0;
|
||||
r->src_base_addr_low = 0x0;
|
||||
r->src_n = 0x1;
|
||||
r->dst_base_addr_high = 0x0;
|
||||
r->src_base_addr_high = 0x0;
|
||||
r->src_c_stride_high = 0x0;
|
||||
r->dst_c_stride_high = 0x0;
|
||||
r->compress_bias0 = 0x0;
|
||||
r->compress_bias1 = 0x0;
|
||||
r->layer_ID = 0x0;
|
||||
}
|
||||
|
||||
static inline void trace_tdma_reg(tdma_reg_t *r, const char *tag)
|
||||
{
|
||||
#define trace_one_reg(name) \
|
||||
printf(" %s: 0x%llx\n", #name, (ullong)r->name)
|
||||
|
||||
printf("--- %s ---\n", tag);
|
||||
trace_one_reg(vld);
|
||||
trace_one_reg(compress_en);
|
||||
trace_one_reg(eod);
|
||||
trace_one_reg(intp_en);
|
||||
trace_one_reg(bar_en);
|
||||
trace_one_reg(check_bf16_value);
|
||||
trace_one_reg(trans_dir);
|
||||
trace_one_reg(rsv00);
|
||||
trace_one_reg(trans_fmt);
|
||||
trace_one_reg(transpose_md);
|
||||
trace_one_reg(rsv01);
|
||||
trace_one_reg(intra_cmd_paral);
|
||||
trace_one_reg(outstanding_en);
|
||||
trace_one_reg(cmd_id);
|
||||
trace_one_reg(spec_func);
|
||||
trace_one_reg(dst_fmt);
|
||||
trace_one_reg(src_fmt);
|
||||
trace_one_reg(cmprs_fmt);
|
||||
trace_one_reg(sys_dtype);
|
||||
trace_one_reg(rsv2_1);
|
||||
trace_one_reg(int8_sign);
|
||||
trace_one_reg(compress_zero_guard);
|
||||
trace_one_reg(int8_rnd_mode);
|
||||
trace_one_reg(wait_id_tpu);
|
||||
trace_one_reg(wait_id_other_tdma);
|
||||
trace_one_reg(wait_id_sdma);
|
||||
trace_one_reg(const_val);
|
||||
trace_one_reg(src_base_reg_sel);
|
||||
trace_one_reg(mv_lut_idx);
|
||||
trace_one_reg(dst_base_reg_sel);
|
||||
trace_one_reg(mv_lut_base);
|
||||
trace_one_reg(rsv4_5);
|
||||
trace_one_reg(dst_h_stride);
|
||||
trace_one_reg(dst_c_stride_low);
|
||||
trace_one_reg(dst_n_stride);
|
||||
trace_one_reg(src_h_stride);
|
||||
trace_one_reg(src_c_stride_low);
|
||||
trace_one_reg(src_n_stride);
|
||||
trace_one_reg(dst_c);
|
||||
trace_one_reg(src_c);
|
||||
trace_one_reg(dst_w);
|
||||
trace_one_reg(dst_h);
|
||||
trace_one_reg(src_w);
|
||||
trace_one_reg(src_h);
|
||||
trace_one_reg(dst_base_addr_low);
|
||||
trace_one_reg(src_base_addr_low);
|
||||
trace_one_reg(src_n);
|
||||
trace_one_reg(dst_base_addr_high);
|
||||
trace_one_reg(src_base_addr_high);
|
||||
trace_one_reg(src_c_stride_high);
|
||||
trace_one_reg(dst_c_stride_high);
|
||||
trace_one_reg(compress_bias0);
|
||||
trace_one_reg(compress_bias1);
|
||||
trace_one_reg(layer_ID);
|
||||
}
|
||||
#endif /* CV180X_TDMA_REG_H */
|
||||
622
cvikernel/include/cvikernel/cv180x/cv180x_tiu_reg.h
Normal file
622
cvikernel/include/cvikernel/cv180x/cv180x_tiu_reg.h
Normal file
@ -0,0 +1,622 @@
|
||||
#ifndef CV180X_TIU_REG_H
|
||||
#define CV180X_TIU_REG_H
|
||||
|
||||
/*
|
||||
* This file is generated by tools. Do not edit it manually.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define TIU_DESC_REG_BYTES (0x70)
|
||||
#define TIU_ENGINE_DESCRIPTOR_NUM (TIU_DESC_REG_BYTES >> 2)
|
||||
|
||||
// TIU operation data type
|
||||
#define DCR_TYPE_CONV_FIX8B 0
|
||||
#define DCR_TYPE_DEPTHWISE_POOL_FIX8B 1
|
||||
#define DCR_TYPE_FC_FIX8B 2
|
||||
#define DCR_TYPE_TENSOR_ARITH_FIX8B 3
|
||||
#define NR_DCR_TYPES 4
|
||||
|
||||
#define TENSOR_MUL_FIX8B 0
|
||||
#define TENSOR_MAC_FIX8B 1
|
||||
#define TENSOR_ADD_FIX8B 2
|
||||
#define TENSOR_SUB_FIX8B 3
|
||||
#define TENSOR_MAX_FIX8B 4
|
||||
#define TENSOR_MIN_FIX8B 5
|
||||
#define TENSOR_SHIFT_FIX8B 6
|
||||
#define TENSOR_AND_FIX8B 7
|
||||
#define TENSOR_OR_FIX8B 8
|
||||
#define TENSOR_XOR_FIX8B 9
|
||||
#define TENSOR_COPY_FIX8B 10
|
||||
#define TENSOR_GE_FIX8B 11
|
||||
|
||||
typedef unsigned long long ullong;
|
||||
|
||||
typedef struct {
|
||||
uint32_t cmd_en;
|
||||
uint32_t cmd_end;
|
||||
uint32_t cmd_id_en;
|
||||
uint32_t cmd_keep;
|
||||
uint32_t cmd_intr_en;
|
||||
uint32_t tsk_typ;
|
||||
uint32_t tsk_eu_typ;
|
||||
uint32_t tsk_opd_num;
|
||||
uint32_t opt_res_shift;
|
||||
uint32_t opt_left_shift;
|
||||
uint32_t opt_shift_typ;
|
||||
uint32_t opt_rshift_typ;
|
||||
uint32_t dummy1;
|
||||
uint32_t opd_typ;
|
||||
uint32_t opt_chl_quan;
|
||||
uint32_t cmd_id_tpu;
|
||||
uint32_t cmd_id_gdma;
|
||||
uint32_t quan_m;
|
||||
uint32_t opt_res0_sign;
|
||||
uint32_t opt_opd0_sign;
|
||||
uint32_t opt_opd1_sign;
|
||||
uint32_t opt_opd2_sign;
|
||||
uint32_t opt_res0_seg;
|
||||
uint32_t opt_opd0_seg;
|
||||
uint32_t opt_opd1_seg;
|
||||
uint32_t opt_opd2_seg;
|
||||
uint32_t ps32_md;
|
||||
uint32_t double_conv;
|
||||
uint32_t opt_left_tran;
|
||||
uint32_t fp_round_typ;
|
||||
uint32_t opt_relu_typ;
|
||||
uint32_t opt_relu_value;
|
||||
uint32_t cmd_pre_exe_typ;
|
||||
uint32_t opt_res_add;
|
||||
uint32_t rsvd0;
|
||||
uint32_t conv_opd0_x_ins0;
|
||||
uint32_t conv_opd0_y_ins0;
|
||||
uint32_t conv_opd0_x_ins0_last;
|
||||
uint32_t conv_opd0_y_ins0_last;
|
||||
uint32_t conv_opd1_x_ins0;
|
||||
uint32_t conv_opd1_y_ins0;
|
||||
uint32_t dummy0;
|
||||
uint32_t opd0_ins_val;
|
||||
uint32_t conv_opd0_up_pad;
|
||||
uint32_t conv_opd0_dn_pad;
|
||||
uint32_t conv_opd0_lf_pad;
|
||||
uint32_t conv_opd0_rt_pad;
|
||||
uint32_t res0_n;
|
||||
uint32_t res0_c;
|
||||
uint32_t res0_h;
|
||||
uint32_t res0_w;
|
||||
uint32_t conv_op_x_str;
|
||||
uint32_t conv_op_y_str;
|
||||
uint32_t cmd_pre_exe;
|
||||
uint32_t rsvd1;
|
||||
uint32_t res0_addr;
|
||||
uint32_t opd0_addr;
|
||||
uint32_t opd1_addr;
|
||||
uint32_t opd2_addr;
|
||||
uint32_t opt_opd0_const;
|
||||
uint32_t opt_opd1_const;
|
||||
uint32_t opt_opd2_const;
|
||||
uint32_t short_nchwstr_same;
|
||||
uint32_t short_res0_str;
|
||||
uint32_t short_opd0_str;
|
||||
uint32_t short_opd1_str;
|
||||
uint32_t short_opd2_str;
|
||||
uint32_t dummy2;
|
||||
uint32_t opd0_n;
|
||||
uint32_t opd0_c;
|
||||
uint32_t dummy3;
|
||||
uint32_t rsvd2;
|
||||
uint32_t opd0_h;
|
||||
uint32_t opd0_w;
|
||||
uint32_t opd1_n;
|
||||
uint32_t opd1_c;
|
||||
uint32_t opd1_h;
|
||||
uint32_t opd1_w;
|
||||
uint32_t opd2_n;
|
||||
uint32_t opd2_c;
|
||||
uint32_t opd2_h;
|
||||
uint32_t opd2_w;
|
||||
uint32_t dummy4;
|
||||
uint32_t rsvd3;
|
||||
uint32_t layer_info;
|
||||
uint32_t res0_n_str;
|
||||
uint32_t res0_c_str;
|
||||
uint32_t res0_h_str;
|
||||
uint32_t res0_w_str;
|
||||
uint32_t res0_b_str;
|
||||
uint32_t opd0_n_str;
|
||||
uint32_t dummy5;
|
||||
uint32_t rsvd4;
|
||||
uint32_t opd0_c_str;
|
||||
uint32_t opd0_h_str;
|
||||
uint32_t opd0_w_str;
|
||||
uint32_t opd0_b_str;
|
||||
uint32_t opd1_n_str;
|
||||
uint32_t opd1_c_str;
|
||||
uint32_t opd1_h_str;
|
||||
uint32_t dummy6;
|
||||
uint32_t rsvd5;
|
||||
uint32_t opd1_w_str;
|
||||
uint32_t opd1_b_str;
|
||||
uint32_t opd2_n_str;
|
||||
uint32_t opd2_c_str;
|
||||
uint32_t opd2_h_str;
|
||||
uint32_t opd2_w_str;
|
||||
uint32_t opd2_b_str;
|
||||
uint32_t dummy7;
|
||||
uint32_t rsvd6;
|
||||
} tiu_reg_t;
|
||||
|
||||
static inline void parse_tiu_reg(tiu_reg_t *r, const uint32_t *p)
|
||||
{
|
||||
r->cmd_en = p[0] & 1;
|
||||
r->cmd_end = (p[0] >> 1) & 1;
|
||||
r->cmd_id_en = (p[0] >> 2) & 1;
|
||||
r->cmd_keep = (p[0] >> 3) & 1;
|
||||
r->cmd_intr_en = (p[0] >> 4) & 1;
|
||||
r->tsk_typ = (p[0] >> 5) & ((1u << 4) - 1);
|
||||
r->tsk_eu_typ = (p[0] >> 9) & ((1u << 5) - 1);
|
||||
r->tsk_opd_num = (p[0] >> 14) & ((1u << 2) - 1);
|
||||
r->opt_res_shift = (p[0] >> 16) & ((1u << 6) - 1);
|
||||
r->opt_left_shift = (p[0] >> 22) & ((1u << 5) - 1);
|
||||
r->opt_shift_typ = (p[0] >> 27) & 1;
|
||||
r->opt_rshift_typ = (p[0] >> 28) & 1;
|
||||
r->dummy1 = (p[0] >> 29) & 1;
|
||||
r->opd_typ = (p[0] >> 30) & 1;
|
||||
r->opt_chl_quan = (p[0] >> 31) & 1;
|
||||
r->cmd_id_tpu = p[1] & ((1u << 16) - 1);
|
||||
r->cmd_id_gdma = (p[1] >> 16) & ((1u << 16) - 1);
|
||||
r->quan_m = p[2];
|
||||
r->opt_res0_sign = p[3] & 1;
|
||||
r->opt_opd0_sign = (p[3] >> 1) & 1;
|
||||
r->opt_opd1_sign = (p[3] >> 2) & 1;
|
||||
r->opt_opd2_sign = (p[3] >> 3) & 1;
|
||||
r->opt_res0_seg = (p[3] >> 4) & ((1u << 2) - 1);
|
||||
r->opt_opd0_seg = (p[3] >> 6) & ((1u << 2) - 1);
|
||||
r->opt_opd1_seg = (p[3] >> 8) & ((1u << 2) - 1);
|
||||
r->opt_opd2_seg = (p[3] >> 10) & 1;
|
||||
r->ps32_md = (p[3] >> 11) & ((1u << 2) - 1);
|
||||
r->double_conv = (p[3] >> 13) & 1;
|
||||
r->opt_left_tran = (p[3] >> 14) & 1;
|
||||
r->fp_round_typ = (p[3] >> 15) & 1;
|
||||
r->opt_relu_typ = (p[3] >> 16) & ((1u << 2) - 1);
|
||||
r->opt_relu_value = (p[3] >> 18) & ((1u << 8) - 1);
|
||||
r->cmd_pre_exe_typ = (p[3] >> 26) & 1;
|
||||
r->opt_res_add = (p[3] >> 27) & 1;
|
||||
r->rsvd0 = (p[3] >> 28) & ((1u << 4) - 1);
|
||||
r->conv_opd0_x_ins0 = p[4] & ((1u << 4) - 1);
|
||||
r->conv_opd0_y_ins0 = (p[4] >> 4) & ((1u << 4) - 1);
|
||||
r->conv_opd0_x_ins0_last = (p[4] >> 8) & ((1u << 4) - 1);
|
||||
r->conv_opd0_y_ins0_last = (p[4] >> 12) & ((1u << 4) - 1);
|
||||
r->conv_opd1_x_ins0 = (p[4] >> 16) & ((1u << 4) - 1);
|
||||
r->conv_opd1_y_ins0 = (p[4] >> 20) & ((1u << 4) - 1);
|
||||
r->dummy0 = (p[4] >> 24) & ((1u << 8) - 1);
|
||||
r->opd0_ins_val = p[5] & ((1u << 16) - 1);
|
||||
r->conv_opd0_up_pad = (p[5] >> 16) & ((1u << 4) - 1);
|
||||
r->conv_opd0_dn_pad = (p[5] >> 20) & ((1u << 4) - 1);
|
||||
r->conv_opd0_lf_pad = (p[5] >> 24) & ((1u << 4) - 1);
|
||||
r->conv_opd0_rt_pad = (p[5] >> 28) & ((1u << 4) - 1);
|
||||
r->res0_n = p[6] & ((1u << 12) - 1);
|
||||
r->res0_c = (p[6] >> 12) & ((1u << 12) - 1);
|
||||
r->res0_h = (p[6] >> 24) & ((1u << 8) - 1);
|
||||
r->res0_h |= (uint64_t)(p[7] & ((1u << 4) - 1)) << 8;
|
||||
r->res0_w = (p[7] >> 4) & ((1u << 12) - 1);
|
||||
r->conv_op_x_str = (p[7] >> 16) & ((1u << 5) - 1);
|
||||
r->conv_op_y_str = (p[7] >> 21) & ((1u << 5) - 1);
|
||||
r->cmd_pre_exe = (p[7] >> 26) & ((1u << 2) - 1);
|
||||
r->rsvd1 = (p[7] >> 28) & ((1u << 4) - 1);
|
||||
r->res0_addr = p[8] & ((1u << 24) - 1);
|
||||
r->opd0_addr = (p[8] >> 24) & ((1u << 8) - 1);
|
||||
r->opd0_addr |= (uint64_t)(p[9] & ((1u << 16) - 1)) << 8;
|
||||
r->opd1_addr = (p[9] >> 16) & ((1u << 16) - 1);
|
||||
r->opd2_addr = p[10] & ((1u << 16) - 1);
|
||||
r->opt_opd0_const = (p[10] >> 16) & 1;
|
||||
r->opt_opd1_const = (p[10] >> 17) & 1;
|
||||
r->opt_opd2_const = (p[10] >> 18) & 1;
|
||||
r->short_nchwstr_same = (p[10] >> 19) & 1;
|
||||
r->short_res0_str = (p[10] >> 20) & ((1u << 2) - 1);
|
||||
r->short_opd0_str = (p[10] >> 22) & ((1u << 2) - 1);
|
||||
r->short_opd1_str = (p[10] >> 24) & ((1u << 2) - 1);
|
||||
r->short_opd2_str = (p[10] >> 26) & ((1u << 2) - 1);
|
||||
r->dummy2 = (p[10] >> 28) & ((1u << 4) - 1);
|
||||
r->opd0_n = p[11] & ((1u << 12) - 1);
|
||||
r->opd0_c = (p[11] >> 12) & ((1u << 12) - 1);
|
||||
r->dummy3 = (p[11] >> 24) & ((1u << 4) - 1);
|
||||
r->rsvd2 = (p[11] >> 28) & ((1u << 4) - 1);
|
||||
r->opd0_h = p[12] & ((1u << 12) - 1);
|
||||
r->opd0_w = (p[12] >> 12) & ((1u << 12) - 1);
|
||||
r->opd1_n = (p[12] >> 24) & ((1u << 8) - 1);
|
||||
r->opd1_n |= (uint64_t)(p[13] & ((1u << 4) - 1)) << 8;
|
||||
r->opd1_c = (p[13] >> 4) & ((1u << 12) - 1);
|
||||
r->opd1_h = (p[13] >> 16) & ((1u << 12) - 1);
|
||||
r->opd1_w = (p[13] >> 28) & ((1u << 4) - 1);
|
||||
r->opd1_w |= (uint64_t)(p[14] & ((1u << 8) - 1)) << 4;
|
||||
r->opd2_n = (p[14] >> 8) & ((1u << 12) - 1);
|
||||
r->opd2_c = (p[14] >> 20) & ((1u << 12) - 1);
|
||||
r->opd2_h = p[15] & ((1u << 12) - 1);
|
||||
r->opd2_w = (p[15] >> 12) & ((1u << 12) - 1);
|
||||
r->dummy4 = (p[15] >> 24) & ((1u << 4) - 1);
|
||||
r->rsvd3 = (p[15] >> 28) & ((1u << 4) - 1);
|
||||
r->layer_info = p[16] & ((1u << 16) - 1);
|
||||
r->res0_n_str = (p[16] >> 16) & ((1u << 16) - 1);
|
||||
r->res0_c_str = p[17] & ((1u << 16) - 1);
|
||||
r->res0_h_str = (p[17] >> 16) & ((1u << 16) - 1);
|
||||
r->res0_w_str = p[18] & ((1u << 16) - 1);
|
||||
r->res0_b_str = (p[18] >> 16) & ((1u << 16) - 1);
|
||||
r->opd0_n_str = p[19] & ((1u << 16) - 1);
|
||||
r->dummy5 = (p[19] >> 16) & ((1u << 12) - 1);
|
||||
r->rsvd4 = (p[19] >> 28) & ((1u << 4) - 1);
|
||||
r->opd0_c_str = p[20] & ((1u << 16) - 1);
|
||||
r->opd0_h_str = (p[20] >> 16) & ((1u << 16) - 1);
|
||||
r->opd0_w_str = p[21] & ((1u << 16) - 1);
|
||||
r->opd0_b_str = (p[21] >> 16) & ((1u << 16) - 1);
|
||||
r->opd1_n_str = p[22] & ((1u << 16) - 1);
|
||||
r->opd1_c_str = (p[22] >> 16) & ((1u << 16) - 1);
|
||||
r->opd1_h_str = p[23] & ((1u << 16) - 1);
|
||||
r->dummy6 = (p[23] >> 16) & ((1u << 12) - 1);
|
||||
r->rsvd5 = (p[23] >> 28) & ((1u << 4) - 1);
|
||||
r->opd1_w_str = p[24] & ((1u << 16) - 1);
|
||||
r->opd1_b_str = (p[24] >> 16) & ((1u << 16) - 1);
|
||||
r->opd2_n_str = p[25] & ((1u << 16) - 1);
|
||||
r->opd2_c_str = (p[25] >> 16) & ((1u << 16) - 1);
|
||||
r->opd2_h_str = p[26] & ((1u << 16) - 1);
|
||||
r->opd2_w_str = (p[26] >> 16) & ((1u << 16) - 1);
|
||||
r->opd2_b_str = p[27] & ((1u << 16) - 1);
|
||||
r->dummy7 = (p[27] >> 16) & ((1u << 12) - 1);
|
||||
r->rsvd6 = (p[27] >> 28) & ((1u << 4) - 1);
|
||||
}
|
||||
|
||||
static inline void emit_tiu_reg(const tiu_reg_t *r, uint32_t *_p)
|
||||
{
|
||||
volatile uint32_t *p = (typeof(p))_p;
|
||||
p[27] = (r->opd2_b_str & ((1u << 16) - 1)) |
|
||||
((r->dummy7 & ((1u << 12) - 1)) << 16) |
|
||||
((r->rsvd6 & ((1u << 4) - 1)) << 28);
|
||||
p[26] = (r->opd2_h_str & ((1u << 16) - 1)) |
|
||||
((r->opd2_w_str & ((1u << 16) - 1)) << 16);
|
||||
p[25] = (r->opd2_n_str & ((1u << 16) - 1)) |
|
||||
((r->opd2_c_str & ((1u << 16) - 1)) << 16);
|
||||
p[24] = (r->opd1_w_str & ((1u << 16) - 1)) |
|
||||
((r->opd1_b_str & ((1u << 16) - 1)) << 16);
|
||||
p[23] = (r->opd1_h_str & ((1u << 16) - 1)) |
|
||||
((r->dummy6 & ((1u << 12) - 1)) << 16) |
|
||||
((r->rsvd5 & ((1u << 4) - 1)) << 28);
|
||||
p[22] = (r->opd1_n_str & ((1u << 16) - 1)) |
|
||||
((r->opd1_c_str & ((1u << 16) - 1)) << 16);
|
||||
p[21] = (r->opd0_w_str & ((1u << 16) - 1)) |
|
||||
((r->opd0_b_str & ((1u << 16) - 1)) << 16);
|
||||
p[20] = (r->opd0_c_str & ((1u << 16) - 1)) |
|
||||
((r->opd0_h_str & ((1u << 16) - 1)) << 16);
|
||||
p[19] = (r->opd0_n_str & ((1u << 16) - 1)) |
|
||||
((r->dummy5 & ((1u << 12) - 1)) << 16) |
|
||||
((r->rsvd4 & ((1u << 4) - 1)) << 28);
|
||||
p[18] = (r->res0_w_str & ((1u << 16) - 1)) |
|
||||
((r->res0_b_str & ((1u << 16) - 1)) << 16);
|
||||
p[17] = (r->res0_c_str & ((1u << 16) - 1)) |
|
||||
((r->res0_h_str & ((1u << 16) - 1)) << 16);
|
||||
p[16] = (r->layer_info & ((1u << 16) - 1)) |
|
||||
((r->res0_n_str & ((1u << 16) - 1)) << 16);
|
||||
p[15] = (r->opd2_h & ((1u << 12) - 1)) |
|
||||
((r->opd2_w & ((1u << 12) - 1)) << 12) |
|
||||
((r->dummy4 & ((1u << 4) - 1)) << 24) |
|
||||
((r->rsvd3 & ((1u << 4) - 1)) << 28);
|
||||
p[14] = ((r->opd1_w >> 4) & ((1u << 8) - 1)) |
|
||||
((r->opd2_n & ((1u << 12) - 1)) << 8) |
|
||||
((r->opd2_c & ((1u << 12) - 1)) << 20);
|
||||
p[13] = ((r->opd1_n >> 8) & ((1u << 4) - 1)) |
|
||||
((r->opd1_c & ((1u << 12) - 1)) << 4) |
|
||||
((r->opd1_h & ((1u << 12) - 1)) << 16) |
|
||||
((r->opd1_w & ((1u << 4) - 1)) << 28);
|
||||
p[12] = (r->opd0_h & ((1u << 12) - 1)) |
|
||||
((r->opd0_w & ((1u << 12) - 1)) << 12) |
|
||||
((r->opd1_n & ((1u << 8) - 1)) << 24);
|
||||
p[11] = (r->opd0_n & ((1u << 12) - 1)) |
|
||||
((r->opd0_c & ((1u << 12) - 1)) << 12) |
|
||||
((r->dummy3 & ((1u << 4) - 1)) << 24) |
|
||||
((r->rsvd2 & ((1u << 4) - 1)) << 28);
|
||||
p[10] = (r->opd2_addr & ((1u << 16) - 1)) |
|
||||
((r->opt_opd0_const & 1) << 16) |
|
||||
((r->opt_opd1_const & 1) << 17) |
|
||||
((r->opt_opd2_const & 1) << 18) |
|
||||
((r->short_nchwstr_same & 1) << 19) |
|
||||
((r->short_res0_str & ((1u << 2) - 1)) << 20) |
|
||||
((r->short_opd0_str & ((1u << 2) - 1)) << 22) |
|
||||
((r->short_opd1_str & ((1u << 2) - 1)) << 24) |
|
||||
((r->short_opd2_str & ((1u << 2) - 1)) << 26) |
|
||||
((r->dummy2 & ((1u << 4) - 1)) << 28);
|
||||
p[9] = ((r->opd0_addr >> 8) & ((1u << 16) - 1)) |
|
||||
((r->opd1_addr & ((1u << 16) - 1)) << 16);
|
||||
p[8] = (r->res0_addr & ((1u << 24) - 1)) |
|
||||
((r->opd0_addr & ((1u << 8) - 1)) << 24);
|
||||
p[7] = ((r->res0_h >> 8) & ((1u << 4) - 1)) |
|
||||
((r->res0_w & ((1u << 12) - 1)) << 4) |
|
||||
((r->conv_op_x_str & ((1u << 5) - 1)) << 16) |
|
||||
((r->conv_op_y_str & ((1u << 5) - 1)) << 21) |
|
||||
((r->cmd_pre_exe & ((1u << 2) - 1)) << 26) |
|
||||
((r->rsvd1 & ((1u << 4) - 1)) << 28);
|
||||
p[6] = (r->res0_n & ((1u << 12) - 1)) |
|
||||
((r->res0_c & ((1u << 12) - 1)) << 12) |
|
||||
((r->res0_h & ((1u << 8) - 1)) << 24);
|
||||
p[5] = (r->opd0_ins_val & ((1u << 16) - 1)) |
|
||||
((r->conv_opd0_up_pad & ((1u << 4) - 1)) << 16) |
|
||||
((r->conv_opd0_dn_pad & ((1u << 4) - 1)) << 20) |
|
||||
((r->conv_opd0_lf_pad & ((1u << 4) - 1)) << 24) |
|
||||
((r->conv_opd0_rt_pad & ((1u << 4) - 1)) << 28);
|
||||
p[4] = (r->conv_opd0_x_ins0 & ((1u << 4) - 1)) |
|
||||
((r->conv_opd0_y_ins0 & ((1u << 4) - 1)) << 4) |
|
||||
((r->conv_opd0_x_ins0_last & ((1u << 4) - 1)) << 8) |
|
||||
((r->conv_opd0_y_ins0_last & ((1u << 4) - 1)) << 12) |
|
||||
((r->conv_opd1_x_ins0 & ((1u << 4) - 1)) << 16) |
|
||||
((r->conv_opd1_y_ins0 & ((1u << 4) - 1)) << 20) |
|
||||
((r->dummy0 & ((1u << 8) - 1)) << 24);
|
||||
p[3] = (r->opt_res0_sign & 1) |
|
||||
((r->opt_opd0_sign & 1) << 1) |
|
||||
((r->opt_opd1_sign & 1) << 2) |
|
||||
((r->opt_opd2_sign & 1) << 3) |
|
||||
((r->opt_res0_seg & ((1u << 2) - 1)) << 4) |
|
||||
((r->opt_opd0_seg & ((1u << 2) - 1)) << 6) |
|
||||
((r->opt_opd1_seg & ((1u << 2) - 1)) << 8) |
|
||||
((r->opt_opd2_seg & 1) << 10) |
|
||||
((r->ps32_md & ((1u << 2) - 1)) << 11) |
|
||||
((r->double_conv & 1) << 13) |
|
||||
((r->opt_left_tran & 1) << 14) |
|
||||
((r->fp_round_typ & 1) << 15) |
|
||||
((r->opt_relu_typ & ((1u << 2) - 1)) << 16) |
|
||||
((r->opt_relu_value & ((1u << 8) - 1)) << 18) |
|
||||
((r->cmd_pre_exe_typ & 1) << 26) |
|
||||
((r->opt_res_add & 1) << 27) |
|
||||
((r->rsvd0 & ((1u << 4) - 1)) << 28);
|
||||
p[2] = (r->quan_m & (((uint64_t)1 << 32) - 1));
|
||||
p[1] = (r->cmd_id_tpu & ((1u << 16) - 1)) |
|
||||
((r->cmd_id_gdma & ((1u << 16) - 1)) << 16);
|
||||
p[0] = (r->cmd_en & 1) |
|
||||
((r->cmd_end & 1) << 1) |
|
||||
((r->cmd_id_en & 1) << 2) |
|
||||
((r->cmd_keep & 1) << 3) |
|
||||
((r->cmd_intr_en & 1) << 4) |
|
||||
((r->tsk_typ & ((1u << 4) - 1)) << 5) |
|
||||
((r->tsk_eu_typ & ((1u << 5) - 1)) << 9) |
|
||||
((r->tsk_opd_num & ((1u << 2) - 1)) << 14) |
|
||||
((r->opt_res_shift & ((1u << 6) - 1)) << 16) |
|
||||
((r->opt_left_shift & ((1u << 5) - 1)) << 22) |
|
||||
((r->opt_shift_typ & 1) << 27) |
|
||||
((r->opt_rshift_typ & 1) << 28) |
|
||||
((r->dummy1 & 1) << 29) |
|
||||
((r->opd_typ & 1) << 30) |
|
||||
((r->opt_chl_quan & 1) << 31);
|
||||
}
|
||||
|
||||
static inline void reset_tiu_reg(tiu_reg_t *r)
|
||||
{
|
||||
r->cmd_en = 0x0;
|
||||
r->cmd_end = 0x0;
|
||||
r->cmd_id_en = 0x0;
|
||||
r->cmd_keep = 0x0;
|
||||
r->cmd_intr_en = 0x0;
|
||||
r->tsk_typ = 0x0;
|
||||
r->tsk_eu_typ = 0x0;
|
||||
r->tsk_opd_num = 0x3;
|
||||
r->opt_res_shift = 0xa;
|
||||
r->opt_left_shift = 0x2;
|
||||
r->opt_shift_typ = 0x1;
|
||||
r->opt_rshift_typ = 0x1;
|
||||
r->dummy1 = 0x0;
|
||||
r->opd_typ = 0x0;
|
||||
r->opt_chl_quan = 0x0;
|
||||
r->cmd_id_tpu = 0x0;
|
||||
r->cmd_id_gdma = 0x0;
|
||||
r->quan_m = 0x0;
|
||||
r->opt_res0_sign = 0x0;
|
||||
r->opt_opd0_sign = 0x0;
|
||||
r->opt_opd1_sign = 0x1;
|
||||
r->opt_opd2_sign = 0x1;
|
||||
r->opt_res0_seg = 0x1;
|
||||
r->opt_opd0_seg = 0x1;
|
||||
r->opt_opd1_seg = 0x1;
|
||||
r->opt_opd2_seg = 0x0;
|
||||
r->ps32_md = 0x0;
|
||||
r->double_conv = 0x0;
|
||||
r->opt_left_tran = 0x0;
|
||||
r->fp_round_typ = 0x0;
|
||||
r->opt_relu_typ = 0x0;
|
||||
r->opt_relu_value = 0x0;
|
||||
r->cmd_pre_exe_typ = 0x0;
|
||||
r->opt_res_add = 0x0;
|
||||
r->rsvd0 = 0x0;
|
||||
r->conv_opd0_x_ins0 = 0x0;
|
||||
r->conv_opd0_y_ins0 = 0x0;
|
||||
r->conv_opd0_x_ins0_last = 0x0;
|
||||
r->conv_opd0_y_ins0_last = 0x0;
|
||||
r->conv_opd1_x_ins0 = 0x0;
|
||||
r->conv_opd1_y_ins0 = 0x0;
|
||||
r->dummy0 = 0x0;
|
||||
r->opd0_ins_val = 0x0;
|
||||
r->conv_opd0_up_pad = 0x0;
|
||||
r->conv_opd0_dn_pad = 0x0;
|
||||
r->conv_opd0_lf_pad = 0x0;
|
||||
r->conv_opd0_rt_pad = 0x0;
|
||||
r->res0_n = 0x1;
|
||||
r->res0_c = 0x1;
|
||||
r->res0_h = 0x1;
|
||||
r->res0_w = 0x10;
|
||||
r->conv_op_x_str = 0x1;
|
||||
r->conv_op_y_str = 0x1;
|
||||
r->cmd_pre_exe = 0x0;
|
||||
r->rsvd1 = 0x1;
|
||||
r->res0_addr = 0x0;
|
||||
r->opd0_addr = 0x0;
|
||||
r->opd1_addr = 0x0;
|
||||
r->opd2_addr = 0x0;
|
||||
r->opt_opd0_const = 0x0;
|
||||
r->opt_opd1_const = 0x0;
|
||||
r->opt_opd2_const = 0x0;
|
||||
r->short_nchwstr_same = 0x0;
|
||||
r->short_res0_str = 0x0;
|
||||
r->short_opd0_str = 0x0;
|
||||
r->short_opd1_str = 0x0;
|
||||
r->short_opd2_str = 0x0;
|
||||
r->dummy2 = 0x0;
|
||||
r->opd0_n = 0x1;
|
||||
r->opd0_c = 0x1;
|
||||
r->dummy3 = 0x0;
|
||||
r->rsvd2 = 0x2;
|
||||
r->opd0_h = 0x1;
|
||||
r->opd0_w = 0x10;
|
||||
r->opd1_n = 0x1;
|
||||
r->opd1_c = 0x1;
|
||||
r->opd1_h = 0x1;
|
||||
r->opd1_w = 0x10;
|
||||
r->opd2_n = 0x1;
|
||||
r->opd2_c = 0x1;
|
||||
r->opd2_h = 0x1;
|
||||
r->opd2_w = 0x10;
|
||||
r->dummy4 = 0x0;
|
||||
r->rsvd3 = 0x3;
|
||||
r->layer_info = 0x0;
|
||||
r->res0_n_str = 0x10;
|
||||
r->res0_c_str = 0x10;
|
||||
r->res0_h_str = 0x0;
|
||||
r->res0_w_str = 0x1;
|
||||
r->res0_b_str = 0x10;
|
||||
r->opd0_n_str = 0x10;
|
||||
r->dummy5 = 0x0;
|
||||
r->rsvd4 = 0x4;
|
||||
r->opd0_c_str = 0x10;
|
||||
r->opd0_h_str = 0x0;
|
||||
r->opd0_w_str = 0x1;
|
||||
r->opd0_b_str = 0x10;
|
||||
r->opd1_n_str = 0x10;
|
||||
r->opd1_c_str = 0x10;
|
||||
r->opd1_h_str = 0x0;
|
||||
r->dummy6 = 0x0;
|
||||
r->rsvd5 = 0x5;
|
||||
r->opd1_w_str = 0x1;
|
||||
r->opd1_b_str = 0x10;
|
||||
r->opd2_n_str = 0x10;
|
||||
r->opd2_c_str = 0x10;
|
||||
r->opd2_h_str = 0x0;
|
||||
r->opd2_w_str = 0x1;
|
||||
r->opd2_b_str = 0x10;
|
||||
r->dummy7 = 0x0;
|
||||
r->rsvd6 = 0x6;
|
||||
}
|
||||
|
||||
static inline void trace_tiu_reg(tiu_reg_t *r, const char *tag)
|
||||
{
|
||||
#define trace_one_reg(name) \
|
||||
printf(" %s: 0x%llx\n", #name, (ullong)r->name)
|
||||
|
||||
printf("--- %s ---\n", tag);
|
||||
trace_one_reg(cmd_en);
|
||||
trace_one_reg(cmd_end);
|
||||
trace_one_reg(cmd_id_en);
|
||||
trace_one_reg(cmd_keep);
|
||||
trace_one_reg(cmd_intr_en);
|
||||
trace_one_reg(tsk_typ);
|
||||
trace_one_reg(tsk_eu_typ);
|
||||
trace_one_reg(tsk_opd_num);
|
||||
trace_one_reg(opt_res_shift);
|
||||
trace_one_reg(opt_left_shift);
|
||||
trace_one_reg(opt_shift_typ);
|
||||
trace_one_reg(opt_rshift_typ);
|
||||
trace_one_reg(dummy1);
|
||||
trace_one_reg(opd_typ);
|
||||
trace_one_reg(opt_chl_quan);
|
||||
trace_one_reg(cmd_id_tpu);
|
||||
trace_one_reg(cmd_id_gdma);
|
||||
trace_one_reg(quan_m);
|
||||
trace_one_reg(opt_res0_sign);
|
||||
trace_one_reg(opt_opd0_sign);
|
||||
trace_one_reg(opt_opd1_sign);
|
||||
trace_one_reg(opt_opd2_sign);
|
||||
trace_one_reg(opt_res0_seg);
|
||||
trace_one_reg(opt_opd0_seg);
|
||||
trace_one_reg(opt_opd1_seg);
|
||||
trace_one_reg(opt_opd2_seg);
|
||||
trace_one_reg(ps32_md);
|
||||
trace_one_reg(double_conv);
|
||||
trace_one_reg(opt_left_tran);
|
||||
trace_one_reg(fp_round_typ);
|
||||
trace_one_reg(opt_relu_typ);
|
||||
trace_one_reg(opt_relu_value);
|
||||
trace_one_reg(cmd_pre_exe_typ);
|
||||
trace_one_reg(opt_res_add);
|
||||
trace_one_reg(rsvd0);
|
||||
trace_one_reg(conv_opd0_x_ins0);
|
||||
trace_one_reg(conv_opd0_y_ins0);
|
||||
trace_one_reg(conv_opd0_x_ins0_last);
|
||||
trace_one_reg(conv_opd0_y_ins0_last);
|
||||
trace_one_reg(conv_opd1_x_ins0);
|
||||
trace_one_reg(conv_opd1_y_ins0);
|
||||
trace_one_reg(dummy0);
|
||||
trace_one_reg(opd0_ins_val);
|
||||
trace_one_reg(conv_opd0_up_pad);
|
||||
trace_one_reg(conv_opd0_dn_pad);
|
||||
trace_one_reg(conv_opd0_lf_pad);
|
||||
trace_one_reg(conv_opd0_rt_pad);
|
||||
trace_one_reg(res0_n);
|
||||
trace_one_reg(res0_c);
|
||||
trace_one_reg(res0_h);
|
||||
trace_one_reg(res0_w);
|
||||
trace_one_reg(conv_op_x_str);
|
||||
trace_one_reg(conv_op_y_str);
|
||||
trace_one_reg(cmd_pre_exe);
|
||||
trace_one_reg(rsvd1);
|
||||
trace_one_reg(res0_addr);
|
||||
trace_one_reg(opd0_addr);
|
||||
trace_one_reg(opd1_addr);
|
||||
trace_one_reg(opd2_addr);
|
||||
trace_one_reg(opt_opd0_const);
|
||||
trace_one_reg(opt_opd1_const);
|
||||
trace_one_reg(opt_opd2_const);
|
||||
trace_one_reg(short_nchwstr_same);
|
||||
trace_one_reg(short_res0_str);
|
||||
trace_one_reg(short_opd0_str);
|
||||
trace_one_reg(short_opd1_str);
|
||||
trace_one_reg(short_opd2_str);
|
||||
trace_one_reg(dummy2);
|
||||
trace_one_reg(opd0_n);
|
||||
trace_one_reg(opd0_c);
|
||||
trace_one_reg(dummy3);
|
||||
trace_one_reg(rsvd2);
|
||||
trace_one_reg(opd0_h);
|
||||
trace_one_reg(opd0_w);
|
||||
trace_one_reg(opd1_n);
|
||||
trace_one_reg(opd1_c);
|
||||
trace_one_reg(opd1_h);
|
||||
trace_one_reg(opd1_w);
|
||||
trace_one_reg(opd2_n);
|
||||
trace_one_reg(opd2_c);
|
||||
trace_one_reg(opd2_h);
|
||||
trace_one_reg(opd2_w);
|
||||
trace_one_reg(dummy4);
|
||||
trace_one_reg(rsvd3);
|
||||
trace_one_reg(layer_info);
|
||||
trace_one_reg(res0_n_str);
|
||||
trace_one_reg(res0_c_str);
|
||||
trace_one_reg(res0_h_str);
|
||||
trace_one_reg(res0_w_str);
|
||||
trace_one_reg(res0_b_str);
|
||||
trace_one_reg(opd0_n_str);
|
||||
trace_one_reg(dummy5);
|
||||
trace_one_reg(rsvd4);
|
||||
trace_one_reg(opd0_c_str);
|
||||
trace_one_reg(opd0_h_str);
|
||||
trace_one_reg(opd0_w_str);
|
||||
trace_one_reg(opd0_b_str);
|
||||
trace_one_reg(opd1_n_str);
|
||||
trace_one_reg(opd1_c_str);
|
||||
trace_one_reg(opd1_h_str);
|
||||
trace_one_reg(dummy6);
|
||||
trace_one_reg(rsvd5);
|
||||
trace_one_reg(opd1_w_str);
|
||||
trace_one_reg(opd1_b_str);
|
||||
trace_one_reg(opd2_n_str);
|
||||
trace_one_reg(opd2_c_str);
|
||||
trace_one_reg(opd2_h_str);
|
||||
trace_one_reg(opd2_w_str);
|
||||
trace_one_reg(opd2_b_str);
|
||||
trace_one_reg(dummy7);
|
||||
trace_one_reg(rsvd6);
|
||||
}
|
||||
#endif /* CV180X_TIU_REG_H */
|
||||
38
cvikernel/include/cvikernel/cv180x/cv180x_tpu_cfg.h
Normal file
38
cvikernel/include/cvikernel/cv180x/cv180x_tpu_cfg.h
Normal file
@ -0,0 +1,38 @@
|
||||
#ifndef __CV180X_TPU_CFG__
|
||||
#define __CV180X_TPU_CFG__
|
||||
|
||||
#define CV180X_VER 182203
|
||||
#define CV180X_HW_NPU_SHIFT 1
|
||||
#define CV180X_HW_EU_SHIFT 4
|
||||
#define CV180X_HW_LMEM_SHIFT 15
|
||||
#define CV180X_HW_LMEM_BANKS 8
|
||||
#define CV180X_HW_LMEM_BANK_SIZE 0x1000
|
||||
#define CV180X_HW_NODE_CHIP_SHIFT 0
|
||||
#define CV180X_HW_NPU_NUM (1 << CV180X_HW_NPU_SHIFT)
|
||||
#define CV180X_HW_EU_NUM (1 << CV180X_HW_EU_SHIFT)
|
||||
#define CV180X_HW_LMEM_SIZE (1 << CV180X_HW_LMEM_SHIFT)
|
||||
#define CV180X_HW_LMEM_START_ADDR 0x0C000000
|
||||
#define CV180X_HW_NODE_CHIP_NUM (1 << CV180X_HW_NODE_CHIP_SHIFT)
|
||||
|
||||
#if (CV180X_HW_LMEM_SIZE != (CV180X_HW_LMEM_BANK_SIZE * CV180X_HW_LMEM_BANKS))
|
||||
#error "Set wrong TPU configuration."
|
||||
#endif
|
||||
|
||||
#define CV180X_GLOBAL_MEM_START_ADDR 0x0
|
||||
#define CV180X_GLOBAL_MEM_SIZE 0x100000000 //
|
||||
|
||||
#define CV180X_GLOBAL_TIU_CMDBUF_ADDR 0x00000000
|
||||
#define CV180X_GLOBAL_TDMA_CMDBUF_ADDR 0x00800000
|
||||
#define CV180X_GLOBAL_TIU_CMDBUF_RESERVED_SIZE 0x00800000 // 8MB
|
||||
#define CV180X_GLOBAL_TDMA_CMDBUF_RESERVED_SIZE 0x00800000 // 8MB
|
||||
#define CV180X_GLOBAL_POOL_RESERVED_SIZE (CV180X_GLOBAL_MEM_SIZE - CV180X_GLOBAL_TIU_CMDBUF_RESERVED_SIZE - CV180X_GLOBAL_TDMA_CMDBUF_RESERVED_SIZE)
|
||||
|
||||
#define CV180X_UART_CTLR_BASE_ADDR 0x04140000
|
||||
|
||||
#define CV180X_TDMA_ENGINE_BASE_ADDR 0x0C100000
|
||||
#define CV180X_TDMA_ENGINE_END_ADDR (CV180X_TDMA_ENGINE_BASE_ADDR + 0x1000)
|
||||
|
||||
#define CV180X_TIU_ENGINE_BASE_ADDR 0x0C101000 //"NPS Register" in memory map?
|
||||
#define CV180X_TIU_ENGINE_END_ADDR (CV180X_TIU_ENGINE_BASE_ADDR + 0x1000)
|
||||
|
||||
#endif
|
||||
310
cvikernel/include/cvikernel/cv181x/cv181x_tdma_reg.h
Normal file
310
cvikernel/include/cvikernel/cv181x/cv181x_tdma_reg.h
Normal file
@ -0,0 +1,310 @@
|
||||
#ifndef CV181X_TDMA_REG_H
|
||||
#define CV181X_TDMA_REG_H
|
||||
|
||||
/*
|
||||
* This file is generated by tools. Do not edit it manually.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define TDMA_DESC_REG_BYTES (0x40)
|
||||
#define TDMA_ENGINE_DESCRIPTOR_NUM (TDMA_DESC_REG_BYTES >> 2)
|
||||
#define TDMA_NUM_BASE_REGS (0x8)
|
||||
|
||||
typedef unsigned long long ullong;
|
||||
|
||||
typedef struct {
|
||||
uint32_t vld;
|
||||
uint32_t compress_en;
|
||||
uint32_t eod;
|
||||
uint32_t intp_en;
|
||||
uint32_t bar_en;
|
||||
uint32_t check_bf16_value;
|
||||
uint32_t trans_dir;
|
||||
uint32_t rsv00;
|
||||
uint32_t trans_fmt;
|
||||
uint32_t transpose_md;
|
||||
uint32_t rsv01;
|
||||
uint32_t intra_cmd_paral;
|
||||
uint32_t outstanding_en;
|
||||
uint32_t cmd_id;
|
||||
uint32_t spec_func;
|
||||
uint32_t dst_fmt;
|
||||
uint32_t src_fmt;
|
||||
uint32_t cmprs_fmt;
|
||||
uint32_t sys_dtype;
|
||||
uint32_t rsv2_1;
|
||||
uint32_t int8_sign;
|
||||
uint32_t compress_zero_guard;
|
||||
uint32_t int8_rnd_mode;
|
||||
uint32_t wait_id_tpu;
|
||||
uint32_t wait_id_other_tdma;
|
||||
uint32_t wait_id_sdma;
|
||||
uint32_t const_val;
|
||||
uint32_t src_base_reg_sel;
|
||||
uint32_t mv_lut_idx;
|
||||
uint32_t dst_base_reg_sel;
|
||||
uint32_t mv_lut_base;
|
||||
uint32_t rsv4_5;
|
||||
uint32_t dst_h_stride;
|
||||
uint32_t dst_c_stride_low;
|
||||
uint32_t dst_n_stride;
|
||||
uint32_t src_h_stride;
|
||||
uint32_t src_c_stride_low;
|
||||
uint32_t src_n_stride;
|
||||
uint32_t dst_c;
|
||||
uint32_t src_c;
|
||||
uint32_t dst_w;
|
||||
uint32_t dst_h;
|
||||
uint32_t src_w;
|
||||
uint32_t src_h;
|
||||
uint32_t dst_base_addr_low;
|
||||
uint32_t src_base_addr_low;
|
||||
uint32_t src_n;
|
||||
uint32_t dst_base_addr_high;
|
||||
uint32_t src_base_addr_high;
|
||||
uint32_t src_c_stride_high;
|
||||
uint32_t dst_c_stride_high;
|
||||
uint32_t compress_bias0;
|
||||
uint32_t compress_bias1;
|
||||
uint32_t layer_ID;
|
||||
} tdma_reg_t;
|
||||
|
||||
static inline void parse_tdma_reg(tdma_reg_t *r, const uint32_t *p)
|
||||
{
|
||||
r->vld = p[0] & 1;
|
||||
r->compress_en = (p[0] >> 1) & 1;
|
||||
r->eod = (p[0] >> 2) & 1;
|
||||
r->intp_en = (p[0] >> 3) & 1;
|
||||
r->bar_en = (p[0] >> 4) & 1;
|
||||
r->check_bf16_value = (p[0] >> 5) & 1;
|
||||
r->trans_dir = (p[0] >> 6) & ((1u << 2) - 1);
|
||||
r->rsv00 = (p[0] >> 8) & ((1u << 2) - 1);
|
||||
r->trans_fmt = (p[0] >> 10) & 1;
|
||||
r->transpose_md = (p[0] >> 11) & ((1u << 2) - 1);
|
||||
r->rsv01 = (p[0] >> 13) & 1;
|
||||
r->intra_cmd_paral = (p[0] >> 14) & 1;
|
||||
r->outstanding_en = (p[0] >> 15) & 1;
|
||||
r->cmd_id = (p[0] >> 16) & ((1u << 16) - 1);
|
||||
r->spec_func = p[1] & ((1u << 3) - 1);
|
||||
r->dst_fmt = (p[1] >> 3) & ((1u << 2) - 1);
|
||||
r->src_fmt = (p[1] >> 5) & ((1u << 2) - 1);
|
||||
r->cmprs_fmt = (p[1] >> 7) & 1;
|
||||
r->sys_dtype = (p[1] >> 8) & 1;
|
||||
r->rsv2_1 = (p[1] >> 9) & ((1u << 4) - 1);
|
||||
r->int8_sign = (p[1] >> 13) & 1;
|
||||
r->compress_zero_guard = (p[1] >> 14) & 1;
|
||||
r->int8_rnd_mode = (p[1] >> 15) & 1;
|
||||
r->wait_id_tpu = (p[1] >> 16) & ((1u << 16) - 1);
|
||||
r->wait_id_other_tdma = p[2] & ((1u << 16) - 1);
|
||||
r->wait_id_sdma = (p[2] >> 16) & ((1u << 16) - 1);
|
||||
r->const_val = p[3] & ((1u << 16) - 1);
|
||||
r->src_base_reg_sel = (p[3] >> 16) & ((1u << 3) - 1);
|
||||
r->mv_lut_idx = (p[3] >> 19) & 1;
|
||||
r->dst_base_reg_sel = (p[3] >> 20) & ((1u << 3) - 1);
|
||||
r->mv_lut_base = (p[3] >> 23) & 1;
|
||||
r->rsv4_5 = (p[3] >> 24) & ((1u << 8) - 1);
|
||||
r->dst_h_stride = p[4] & ((1u << 16) - 1);
|
||||
r->dst_c_stride_low = (p[4] >> 16) & ((1u << 16) - 1);
|
||||
r->dst_n_stride = p[5];
|
||||
r->src_h_stride = p[6] & ((1u << 16) - 1);
|
||||
r->src_c_stride_low = (p[6] >> 16) & ((1u << 16) - 1);
|
||||
r->src_n_stride = p[7];
|
||||
r->dst_c = p[8] & ((1u << 16) - 1);
|
||||
r->src_c = (p[8] >> 16) & ((1u << 16) - 1);
|
||||
r->dst_w = p[9] & ((1u << 16) - 1);
|
||||
r->dst_h = (p[9] >> 16) & ((1u << 16) - 1);
|
||||
r->src_w = p[10] & ((1u << 16) - 1);
|
||||
r->src_h = (p[10] >> 16) & ((1u << 16) - 1);
|
||||
r->dst_base_addr_low = p[11];
|
||||
r->src_base_addr_low = p[12];
|
||||
r->src_n = p[13] & ((1u << 16) - 1);
|
||||
r->dst_base_addr_high = (p[13] >> 16) & ((1u << 8) - 1);
|
||||
r->src_base_addr_high = (p[13] >> 24) & ((1u << 8) - 1);
|
||||
r->src_c_stride_high = p[14] & ((1u << 16) - 1);
|
||||
r->dst_c_stride_high = (p[14] >> 16) & ((1u << 16) - 1);
|
||||
r->compress_bias0 = p[15] & ((1u << 8) - 1);
|
||||
r->compress_bias1 = (p[15] >> 8) & ((1u << 8) - 1);
|
||||
r->layer_ID = (p[15] >> 16) & ((1u << 16) - 1);
|
||||
}
|
||||
|
||||
static inline void emit_tdma_reg(const tdma_reg_t *r, uint32_t *_p)
|
||||
{
|
||||
volatile uint32_t *p = (typeof(p))_p;
|
||||
p[15] = (r->compress_bias0 & ((1u << 8) - 1)) |
|
||||
((r->compress_bias1 & ((1u << 8) - 1)) << 8) |
|
||||
((r->layer_ID & ((1u << 16) - 1)) << 16);
|
||||
p[14] = (r->src_c_stride_high & ((1u << 16) - 1)) |
|
||||
((r->dst_c_stride_high & ((1u << 16) - 1)) << 16);
|
||||
p[13] = (r->src_n & ((1u << 16) - 1)) |
|
||||
((r->dst_base_addr_high & ((1u << 8) - 1)) << 16) |
|
||||
((r->src_base_addr_high & ((1u << 8) - 1)) << 24);
|
||||
p[12] = (r->src_base_addr_low & (((uint64_t)1 << 32) - 1));
|
||||
p[11] = (r->dst_base_addr_low & (((uint64_t)1 << 32) - 1));
|
||||
p[10] = (r->src_w & ((1u << 16) - 1)) |
|
||||
((r->src_h & ((1u << 16) - 1)) << 16);
|
||||
p[9] = (r->dst_w & ((1u << 16) - 1)) |
|
||||
((r->dst_h & ((1u << 16) - 1)) << 16);
|
||||
p[8] = (r->dst_c & ((1u << 16) - 1)) |
|
||||
((r->src_c & ((1u << 16) - 1)) << 16);
|
||||
p[7] = (r->src_n_stride & (((uint64_t)1 << 32) - 1));
|
||||
p[6] = (r->src_h_stride & ((1u << 16) - 1)) |
|
||||
((r->src_c_stride_low & ((1u << 16) - 1)) << 16);
|
||||
p[5] = (r->dst_n_stride & (((uint64_t)1 << 32) - 1));
|
||||
p[4] = (r->dst_h_stride & ((1u << 16) - 1)) |
|
||||
((r->dst_c_stride_low & ((1u << 16) - 1)) << 16);
|
||||
p[3] = (r->const_val & ((1u << 16) - 1)) |
|
||||
((r->src_base_reg_sel & ((1u << 3) - 1)) << 16) |
|
||||
((r->mv_lut_idx & 1) << 19) |
|
||||
((r->dst_base_reg_sel & ((1u << 3) - 1)) << 20) |
|
||||
((r->mv_lut_base & 1) << 23) |
|
||||
((r->rsv4_5 & ((1u << 8) - 1)) << 24);
|
||||
p[2] = (r->wait_id_other_tdma & ((1u << 16) - 1)) |
|
||||
((r->wait_id_sdma & ((1u << 16) - 1)) << 16);
|
||||
p[1] = (r->spec_func & ((1u << 3) - 1)) |
|
||||
((r->dst_fmt & ((1u << 2) - 1)) << 3) |
|
||||
((r->src_fmt & ((1u << 2) - 1)) << 5) |
|
||||
((r->cmprs_fmt & 1) << 7) |
|
||||
((r->sys_dtype & 1) << 8) |
|
||||
((r->rsv2_1 & ((1u << 4) - 1)) << 9) |
|
||||
((r->int8_sign & 1) << 13) |
|
||||
((r->compress_zero_guard & 1) << 14) |
|
||||
((r->int8_rnd_mode & 1) << 15) |
|
||||
((r->wait_id_tpu & ((1u << 16) - 1)) << 16);
|
||||
p[0] = (r->vld & 1) |
|
||||
((r->compress_en & 1) << 1) |
|
||||
((r->eod & 1) << 2) |
|
||||
((r->intp_en & 1) << 3) |
|
||||
((r->bar_en & 1) << 4) |
|
||||
((r->check_bf16_value & 1) << 5) |
|
||||
((r->trans_dir & ((1u << 2) - 1)) << 6) |
|
||||
((r->rsv00 & ((1u << 2) - 1)) << 8) |
|
||||
((r->trans_fmt & 1) << 10) |
|
||||
((r->transpose_md & ((1u << 2) - 1)) << 11) |
|
||||
((r->rsv01 & 1) << 13) |
|
||||
((r->intra_cmd_paral & 1) << 14) |
|
||||
((r->outstanding_en & 1) << 15) |
|
||||
((r->cmd_id & ((1u << 16) - 1)) << 16);
|
||||
}
|
||||
|
||||
static inline void reset_tdma_reg(tdma_reg_t *r)
|
||||
{
|
||||
r->vld = 0x0;
|
||||
r->compress_en = 0x0;
|
||||
r->eod = 0x0;
|
||||
r->intp_en = 0x0;
|
||||
r->bar_en = 0x0;
|
||||
r->check_bf16_value = 0x0;
|
||||
r->trans_dir = 0x0;
|
||||
r->rsv00 = 0x0;
|
||||
r->trans_fmt = 0x0;
|
||||
r->transpose_md = 0x0;
|
||||
r->rsv01 = 0x0;
|
||||
r->intra_cmd_paral = 0x0;
|
||||
r->outstanding_en = 0x0;
|
||||
r->cmd_id = 0x0;
|
||||
r->spec_func = 0x0;
|
||||
r->dst_fmt = 0x1;
|
||||
r->src_fmt = 0x1;
|
||||
r->cmprs_fmt = 0x0;
|
||||
r->sys_dtype = 0x0;
|
||||
r->rsv2_1 = 0x0;
|
||||
r->int8_sign = 0x0;
|
||||
r->compress_zero_guard = 0x0;
|
||||
r->int8_rnd_mode = 0x0;
|
||||
r->wait_id_tpu = 0x0;
|
||||
r->wait_id_other_tdma = 0x0;
|
||||
r->wait_id_sdma = 0x0;
|
||||
r->const_val = 0x0;
|
||||
r->src_base_reg_sel = 0x0;
|
||||
r->mv_lut_idx = 0x0;
|
||||
r->dst_base_reg_sel = 0x0;
|
||||
r->mv_lut_base = 0x0;
|
||||
r->rsv4_5 = 0x0;
|
||||
r->dst_h_stride = 0x1;
|
||||
r->dst_c_stride_low = 0x1;
|
||||
r->dst_n_stride = 0x1;
|
||||
r->src_h_stride = 0x1;
|
||||
r->src_c_stride_low = 0x1;
|
||||
r->src_n_stride = 0x1;
|
||||
r->dst_c = 0x1;
|
||||
r->src_c = 0x1;
|
||||
r->dst_w = 0x1;
|
||||
r->dst_h = 0x1;
|
||||
r->src_w = 0x1;
|
||||
r->src_h = 0x1;
|
||||
r->dst_base_addr_low = 0x0;
|
||||
r->src_base_addr_low = 0x0;
|
||||
r->src_n = 0x1;
|
||||
r->dst_base_addr_high = 0x0;
|
||||
r->src_base_addr_high = 0x0;
|
||||
r->src_c_stride_high = 0x0;
|
||||
r->dst_c_stride_high = 0x0;
|
||||
r->compress_bias0 = 0x0;
|
||||
r->compress_bias1 = 0x0;
|
||||
r->layer_ID = 0x0;
|
||||
}
|
||||
|
||||
static inline void trace_tdma_reg(tdma_reg_t *r, const char *tag)
|
||||
{
|
||||
#define trace_one_reg(name) \
|
||||
printf(" %s: 0x%llx\n", #name, (ullong)r->name)
|
||||
|
||||
printf("--- %s ---\n", tag);
|
||||
trace_one_reg(vld);
|
||||
trace_one_reg(compress_en);
|
||||
trace_one_reg(eod);
|
||||
trace_one_reg(intp_en);
|
||||
trace_one_reg(bar_en);
|
||||
trace_one_reg(check_bf16_value);
|
||||
trace_one_reg(trans_dir);
|
||||
trace_one_reg(rsv00);
|
||||
trace_one_reg(trans_fmt);
|
||||
trace_one_reg(transpose_md);
|
||||
trace_one_reg(rsv01);
|
||||
trace_one_reg(intra_cmd_paral);
|
||||
trace_one_reg(outstanding_en);
|
||||
trace_one_reg(cmd_id);
|
||||
trace_one_reg(spec_func);
|
||||
trace_one_reg(dst_fmt);
|
||||
trace_one_reg(src_fmt);
|
||||
trace_one_reg(cmprs_fmt);
|
||||
trace_one_reg(sys_dtype);
|
||||
trace_one_reg(rsv2_1);
|
||||
trace_one_reg(int8_sign);
|
||||
trace_one_reg(compress_zero_guard);
|
||||
trace_one_reg(int8_rnd_mode);
|
||||
trace_one_reg(wait_id_tpu);
|
||||
trace_one_reg(wait_id_other_tdma);
|
||||
trace_one_reg(wait_id_sdma);
|
||||
trace_one_reg(const_val);
|
||||
trace_one_reg(src_base_reg_sel);
|
||||
trace_one_reg(mv_lut_idx);
|
||||
trace_one_reg(dst_base_reg_sel);
|
||||
trace_one_reg(mv_lut_base);
|
||||
trace_one_reg(rsv4_5);
|
||||
trace_one_reg(dst_h_stride);
|
||||
trace_one_reg(dst_c_stride_low);
|
||||
trace_one_reg(dst_n_stride);
|
||||
trace_one_reg(src_h_stride);
|
||||
trace_one_reg(src_c_stride_low);
|
||||
trace_one_reg(src_n_stride);
|
||||
trace_one_reg(dst_c);
|
||||
trace_one_reg(src_c);
|
||||
trace_one_reg(dst_w);
|
||||
trace_one_reg(dst_h);
|
||||
trace_one_reg(src_w);
|
||||
trace_one_reg(src_h);
|
||||
trace_one_reg(dst_base_addr_low);
|
||||
trace_one_reg(src_base_addr_low);
|
||||
trace_one_reg(src_n);
|
||||
trace_one_reg(dst_base_addr_high);
|
||||
trace_one_reg(src_base_addr_high);
|
||||
trace_one_reg(src_c_stride_high);
|
||||
trace_one_reg(dst_c_stride_high);
|
||||
trace_one_reg(compress_bias0);
|
||||
trace_one_reg(compress_bias1);
|
||||
trace_one_reg(layer_ID);
|
||||
}
|
||||
#endif /* CV181X_TDMA_REG_H */
|
||||
622
cvikernel/include/cvikernel/cv181x/cv181x_tiu_reg.h
Normal file
622
cvikernel/include/cvikernel/cv181x/cv181x_tiu_reg.h
Normal file
@ -0,0 +1,622 @@
|
||||
#ifndef CV181X_TIU_REG_H
|
||||
#define CV181X_TIU_REG_H
|
||||
|
||||
/*
|
||||
* This file is generated by tools. Do not edit it manually.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define TIU_DESC_REG_BYTES (0x70)
|
||||
#define TIU_ENGINE_DESCRIPTOR_NUM (TIU_DESC_REG_BYTES >> 2)
|
||||
|
||||
// TIU operation data type
|
||||
#define DCR_TYPE_CONV_FIX8B 0
|
||||
#define DCR_TYPE_DEPTHWISE_POOL_FIX8B 1
|
||||
#define DCR_TYPE_FC_FIX8B 2
|
||||
#define DCR_TYPE_TENSOR_ARITH_FIX8B 3
|
||||
#define NR_DCR_TYPES 4
|
||||
|
||||
#define TENSOR_MUL_FIX8B 0
|
||||
#define TENSOR_MAC_FIX8B 1
|
||||
#define TENSOR_ADD_FIX8B 2
|
||||
#define TENSOR_SUB_FIX8B 3
|
||||
#define TENSOR_MAX_FIX8B 4
|
||||
#define TENSOR_MIN_FIX8B 5
|
||||
#define TENSOR_SHIFT_FIX8B 6
|
||||
#define TENSOR_AND_FIX8B 7
|
||||
#define TENSOR_OR_FIX8B 8
|
||||
#define TENSOR_XOR_FIX8B 9
|
||||
#define TENSOR_COPY_FIX8B 10
|
||||
#define TENSOR_GE_FIX8B 11
|
||||
|
||||
typedef unsigned long long ullong;
|
||||
|
||||
typedef struct {
|
||||
uint32_t cmd_en;
|
||||
uint32_t cmd_end;
|
||||
uint32_t cmd_id_en;
|
||||
uint32_t cmd_keep;
|
||||
uint32_t cmd_intr_en;
|
||||
uint32_t tsk_typ;
|
||||
uint32_t tsk_eu_typ;
|
||||
uint32_t tsk_opd_num;
|
||||
uint32_t opt_res_shift;
|
||||
uint32_t opt_left_shift;
|
||||
uint32_t opt_shift_typ;
|
||||
uint32_t opt_rshift_typ;
|
||||
uint32_t dummy1;
|
||||
uint32_t opd_typ;
|
||||
uint32_t opt_chl_quan;
|
||||
uint32_t cmd_id_tpu;
|
||||
uint32_t cmd_id_gdma;
|
||||
uint32_t quan_m;
|
||||
uint32_t opt_res0_sign;
|
||||
uint32_t opt_opd0_sign;
|
||||
uint32_t opt_opd1_sign;
|
||||
uint32_t opt_opd2_sign;
|
||||
uint32_t opt_res0_seg;
|
||||
uint32_t opt_opd0_seg;
|
||||
uint32_t opt_opd1_seg;
|
||||
uint32_t opt_opd2_seg;
|
||||
uint32_t ps32_md;
|
||||
uint32_t double_conv;
|
||||
uint32_t opt_left_tran;
|
||||
uint32_t fp_round_typ;
|
||||
uint32_t opt_relu_typ;
|
||||
uint32_t opt_relu_value;
|
||||
uint32_t cmd_pre_exe_typ;
|
||||
uint32_t opt_res_add;
|
||||
uint32_t rsvd0;
|
||||
uint32_t conv_opd0_x_ins0;
|
||||
uint32_t conv_opd0_y_ins0;
|
||||
uint32_t conv_opd0_x_ins0_last;
|
||||
uint32_t conv_opd0_y_ins0_last;
|
||||
uint32_t conv_opd1_x_ins0;
|
||||
uint32_t conv_opd1_y_ins0;
|
||||
uint32_t dummy0;
|
||||
uint32_t opd0_ins_val;
|
||||
uint32_t conv_opd0_up_pad;
|
||||
uint32_t conv_opd0_dn_pad;
|
||||
uint32_t conv_opd0_lf_pad;
|
||||
uint32_t conv_opd0_rt_pad;
|
||||
uint32_t res0_n;
|
||||
uint32_t res0_c;
|
||||
uint32_t res0_h;
|
||||
uint32_t res0_w;
|
||||
uint32_t conv_op_x_str;
|
||||
uint32_t conv_op_y_str;
|
||||
uint32_t cmd_pre_exe;
|
||||
uint32_t rsvd1;
|
||||
uint32_t res0_addr;
|
||||
uint32_t opd0_addr;
|
||||
uint32_t opd1_addr;
|
||||
uint32_t opd2_addr;
|
||||
uint32_t opt_opd0_const;
|
||||
uint32_t opt_opd1_const;
|
||||
uint32_t opt_opd2_const;
|
||||
uint32_t short_nchwstr_same;
|
||||
uint32_t short_res0_str;
|
||||
uint32_t short_opd0_str;
|
||||
uint32_t short_opd1_str;
|
||||
uint32_t short_opd2_str;
|
||||
uint32_t dummy2;
|
||||
uint32_t opd0_n;
|
||||
uint32_t opd0_c;
|
||||
uint32_t dummy3;
|
||||
uint32_t rsvd2;
|
||||
uint32_t opd0_h;
|
||||
uint32_t opd0_w;
|
||||
uint32_t opd1_n;
|
||||
uint32_t opd1_c;
|
||||
uint32_t opd1_h;
|
||||
uint32_t opd1_w;
|
||||
uint32_t opd2_n;
|
||||
uint32_t opd2_c;
|
||||
uint32_t opd2_h;
|
||||
uint32_t opd2_w;
|
||||
uint32_t dummy4;
|
||||
uint32_t rsvd3;
|
||||
uint32_t layer_info;
|
||||
uint32_t res0_n_str;
|
||||
uint32_t res0_c_str;
|
||||
uint32_t res0_h_str;
|
||||
uint32_t res0_w_str;
|
||||
uint32_t res0_b_str;
|
||||
uint32_t opd0_n_str;
|
||||
uint32_t dummy5;
|
||||
uint32_t rsvd4;
|
||||
uint32_t opd0_c_str;
|
||||
uint32_t opd0_h_str;
|
||||
uint32_t opd0_w_str;
|
||||
uint32_t opd0_b_str;
|
||||
uint32_t opd1_n_str;
|
||||
uint32_t opd1_c_str;
|
||||
uint32_t opd1_h_str;
|
||||
uint32_t dummy6;
|
||||
uint32_t rsvd5;
|
||||
uint32_t opd1_w_str;
|
||||
uint32_t opd1_b_str;
|
||||
uint32_t opd2_n_str;
|
||||
uint32_t opd2_c_str;
|
||||
uint32_t opd2_h_str;
|
||||
uint32_t opd2_w_str;
|
||||
uint32_t opd2_b_str;
|
||||
uint32_t dummy7;
|
||||
uint32_t rsvd6;
|
||||
} tiu_reg_t;
|
||||
|
||||
static inline void parse_tiu_reg(tiu_reg_t *r, const uint32_t *p)
|
||||
{
|
||||
r->cmd_en = p[0] & 1;
|
||||
r->cmd_end = (p[0] >> 1) & 1;
|
||||
r->cmd_id_en = (p[0] >> 2) & 1;
|
||||
r->cmd_keep = (p[0] >> 3) & 1;
|
||||
r->cmd_intr_en = (p[0] >> 4) & 1;
|
||||
r->tsk_typ = (p[0] >> 5) & ((1u << 4) - 1);
|
||||
r->tsk_eu_typ = (p[0] >> 9) & ((1u << 5) - 1);
|
||||
r->tsk_opd_num = (p[0] >> 14) & ((1u << 2) - 1);
|
||||
r->opt_res_shift = (p[0] >> 16) & ((1u << 6) - 1);
|
||||
r->opt_left_shift = (p[0] >> 22) & ((1u << 5) - 1);
|
||||
r->opt_shift_typ = (p[0] >> 27) & 1;
|
||||
r->opt_rshift_typ = (p[0] >> 28) & 1;
|
||||
r->dummy1 = (p[0] >> 29) & 1;
|
||||
r->opd_typ = (p[0] >> 30) & 1;
|
||||
r->opt_chl_quan = (p[0] >> 31) & 1;
|
||||
r->cmd_id_tpu = p[1] & ((1u << 16) - 1);
|
||||
r->cmd_id_gdma = (p[1] >> 16) & ((1u << 16) - 1);
|
||||
r->quan_m = p[2];
|
||||
r->opt_res0_sign = p[3] & 1;
|
||||
r->opt_opd0_sign = (p[3] >> 1) & 1;
|
||||
r->opt_opd1_sign = (p[3] >> 2) & 1;
|
||||
r->opt_opd2_sign = (p[3] >> 3) & 1;
|
||||
r->opt_res0_seg = (p[3] >> 4) & ((1u << 2) - 1);
|
||||
r->opt_opd0_seg = (p[3] >> 6) & ((1u << 2) - 1);
|
||||
r->opt_opd1_seg = (p[3] >> 8) & ((1u << 2) - 1);
|
||||
r->opt_opd2_seg = (p[3] >> 10) & 1;
|
||||
r->ps32_md = (p[3] >> 11) & ((1u << 2) - 1);
|
||||
r->double_conv = (p[3] >> 13) & 1;
|
||||
r->opt_left_tran = (p[3] >> 14) & 1;
|
||||
r->fp_round_typ = (p[3] >> 15) & 1;
|
||||
r->opt_relu_typ = (p[3] >> 16) & ((1u << 2) - 1);
|
||||
r->opt_relu_value = (p[3] >> 18) & ((1u << 8) - 1);
|
||||
r->cmd_pre_exe_typ = (p[3] >> 26) & 1;
|
||||
r->opt_res_add = (p[3] >> 27) & 1;
|
||||
r->rsvd0 = (p[3] >> 28) & ((1u << 4) - 1);
|
||||
r->conv_opd0_x_ins0 = p[4] & ((1u << 4) - 1);
|
||||
r->conv_opd0_y_ins0 = (p[4] >> 4) & ((1u << 4) - 1);
|
||||
r->conv_opd0_x_ins0_last = (p[4] >> 8) & ((1u << 4) - 1);
|
||||
r->conv_opd0_y_ins0_last = (p[4] >> 12) & ((1u << 4) - 1);
|
||||
r->conv_opd1_x_ins0 = (p[4] >> 16) & ((1u << 4) - 1);
|
||||
r->conv_opd1_y_ins0 = (p[4] >> 20) & ((1u << 4) - 1);
|
||||
r->dummy0 = (p[4] >> 24) & ((1u << 8) - 1);
|
||||
r->opd0_ins_val = p[5] & ((1u << 16) - 1);
|
||||
r->conv_opd0_up_pad = (p[5] >> 16) & ((1u << 4) - 1);
|
||||
r->conv_opd0_dn_pad = (p[5] >> 20) & ((1u << 4) - 1);
|
||||
r->conv_opd0_lf_pad = (p[5] >> 24) & ((1u << 4) - 1);
|
||||
r->conv_opd0_rt_pad = (p[5] >> 28) & ((1u << 4) - 1);
|
||||
r->res0_n = p[6] & ((1u << 12) - 1);
|
||||
r->res0_c = (p[6] >> 12) & ((1u << 12) - 1);
|
||||
r->res0_h = (p[6] >> 24) & ((1u << 8) - 1);
|
||||
r->res0_h |= (uint64_t)(p[7] & ((1u << 4) - 1)) << 8;
|
||||
r->res0_w = (p[7] >> 4) & ((1u << 12) - 1);
|
||||
r->conv_op_x_str = (p[7] >> 16) & ((1u << 5) - 1);
|
||||
r->conv_op_y_str = (p[7] >> 21) & ((1u << 5) - 1);
|
||||
r->cmd_pre_exe = (p[7] >> 26) & ((1u << 2) - 1);
|
||||
r->rsvd1 = (p[7] >> 28) & ((1u << 4) - 1);
|
||||
r->res0_addr = p[8] & ((1u << 24) - 1);
|
||||
r->opd0_addr = (p[8] >> 24) & ((1u << 8) - 1);
|
||||
r->opd0_addr |= (uint64_t)(p[9] & ((1u << 16) - 1)) << 8;
|
||||
r->opd1_addr = (p[9] >> 16) & ((1u << 16) - 1);
|
||||
r->opd2_addr = p[10] & ((1u << 16) - 1);
|
||||
r->opt_opd0_const = (p[10] >> 16) & 1;
|
||||
r->opt_opd1_const = (p[10] >> 17) & 1;
|
||||
r->opt_opd2_const = (p[10] >> 18) & 1;
|
||||
r->short_nchwstr_same = (p[10] >> 19) & 1;
|
||||
r->short_res0_str = (p[10] >> 20) & ((1u << 2) - 1);
|
||||
r->short_opd0_str = (p[10] >> 22) & ((1u << 2) - 1);
|
||||
r->short_opd1_str = (p[10] >> 24) & ((1u << 2) - 1);
|
||||
r->short_opd2_str = (p[10] >> 26) & ((1u << 2) - 1);
|
||||
r->dummy2 = (p[10] >> 28) & ((1u << 4) - 1);
|
||||
r->opd0_n = p[11] & ((1u << 12) - 1);
|
||||
r->opd0_c = (p[11] >> 12) & ((1u << 12) - 1);
|
||||
r->dummy3 = (p[11] >> 24) & ((1u << 4) - 1);
|
||||
r->rsvd2 = (p[11] >> 28) & ((1u << 4) - 1);
|
||||
r->opd0_h = p[12] & ((1u << 12) - 1);
|
||||
r->opd0_w = (p[12] >> 12) & ((1u << 12) - 1);
|
||||
r->opd1_n = (p[12] >> 24) & ((1u << 8) - 1);
|
||||
r->opd1_n |= (uint64_t)(p[13] & ((1u << 4) - 1)) << 8;
|
||||
r->opd1_c = (p[13] >> 4) & ((1u << 12) - 1);
|
||||
r->opd1_h = (p[13] >> 16) & ((1u << 12) - 1);
|
||||
r->opd1_w = (p[13] >> 28) & ((1u << 4) - 1);
|
||||
r->opd1_w |= (uint64_t)(p[14] & ((1u << 8) - 1)) << 4;
|
||||
r->opd2_n = (p[14] >> 8) & ((1u << 12) - 1);
|
||||
r->opd2_c = (p[14] >> 20) & ((1u << 12) - 1);
|
||||
r->opd2_h = p[15] & ((1u << 12) - 1);
|
||||
r->opd2_w = (p[15] >> 12) & ((1u << 12) - 1);
|
||||
r->dummy4 = (p[15] >> 24) & ((1u << 4) - 1);
|
||||
r->rsvd3 = (p[15] >> 28) & ((1u << 4) - 1);
|
||||
r->layer_info = p[16] & ((1u << 16) - 1);
|
||||
r->res0_n_str = (p[16] >> 16) & ((1u << 16) - 1);
|
||||
r->res0_c_str = p[17] & ((1u << 16) - 1);
|
||||
r->res0_h_str = (p[17] >> 16) & ((1u << 16) - 1);
|
||||
r->res0_w_str = p[18] & ((1u << 16) - 1);
|
||||
r->res0_b_str = (p[18] >> 16) & ((1u << 16) - 1);
|
||||
r->opd0_n_str = p[19] & ((1u << 16) - 1);
|
||||
r->dummy5 = (p[19] >> 16) & ((1u << 12) - 1);
|
||||
r->rsvd4 = (p[19] >> 28) & ((1u << 4) - 1);
|
||||
r->opd0_c_str = p[20] & ((1u << 16) - 1);
|
||||
r->opd0_h_str = (p[20] >> 16) & ((1u << 16) - 1);
|
||||
r->opd0_w_str = p[21] & ((1u << 16) - 1);
|
||||
r->opd0_b_str = (p[21] >> 16) & ((1u << 16) - 1);
|
||||
r->opd1_n_str = p[22] & ((1u << 16) - 1);
|
||||
r->opd1_c_str = (p[22] >> 16) & ((1u << 16) - 1);
|
||||
r->opd1_h_str = p[23] & ((1u << 16) - 1);
|
||||
r->dummy6 = (p[23] >> 16) & ((1u << 12) - 1);
|
||||
r->rsvd5 = (p[23] >> 28) & ((1u << 4) - 1);
|
||||
r->opd1_w_str = p[24] & ((1u << 16) - 1);
|
||||
r->opd1_b_str = (p[24] >> 16) & ((1u << 16) - 1);
|
||||
r->opd2_n_str = p[25] & ((1u << 16) - 1);
|
||||
r->opd2_c_str = (p[25] >> 16) & ((1u << 16) - 1);
|
||||
r->opd2_h_str = p[26] & ((1u << 16) - 1);
|
||||
r->opd2_w_str = (p[26] >> 16) & ((1u << 16) - 1);
|
||||
r->opd2_b_str = p[27] & ((1u << 16) - 1);
|
||||
r->dummy7 = (p[27] >> 16) & ((1u << 12) - 1);
|
||||
r->rsvd6 = (p[27] >> 28) & ((1u << 4) - 1);
|
||||
}
|
||||
|
||||
static inline void emit_tiu_reg(const tiu_reg_t *r, uint32_t *_p)
|
||||
{
|
||||
volatile uint32_t *p = (typeof(p))_p;
|
||||
p[27] = (r->opd2_b_str & ((1u << 16) - 1)) |
|
||||
((r->dummy7 & ((1u << 12) - 1)) << 16) |
|
||||
((r->rsvd6 & ((1u << 4) - 1)) << 28);
|
||||
p[26] = (r->opd2_h_str & ((1u << 16) - 1)) |
|
||||
((r->opd2_w_str & ((1u << 16) - 1)) << 16);
|
||||
p[25] = (r->opd2_n_str & ((1u << 16) - 1)) |
|
||||
((r->opd2_c_str & ((1u << 16) - 1)) << 16);
|
||||
p[24] = (r->opd1_w_str & ((1u << 16) - 1)) |
|
||||
((r->opd1_b_str & ((1u << 16) - 1)) << 16);
|
||||
p[23] = (r->opd1_h_str & ((1u << 16) - 1)) |
|
||||
((r->dummy6 & ((1u << 12) - 1)) << 16) |
|
||||
((r->rsvd5 & ((1u << 4) - 1)) << 28);
|
||||
p[22] = (r->opd1_n_str & ((1u << 16) - 1)) |
|
||||
((r->opd1_c_str & ((1u << 16) - 1)) << 16);
|
||||
p[21] = (r->opd0_w_str & ((1u << 16) - 1)) |
|
||||
((r->opd0_b_str & ((1u << 16) - 1)) << 16);
|
||||
p[20] = (r->opd0_c_str & ((1u << 16) - 1)) |
|
||||
((r->opd0_h_str & ((1u << 16) - 1)) << 16);
|
||||
p[19] = (r->opd0_n_str & ((1u << 16) - 1)) |
|
||||
((r->dummy5 & ((1u << 12) - 1)) << 16) |
|
||||
((r->rsvd4 & ((1u << 4) - 1)) << 28);
|
||||
p[18] = (r->res0_w_str & ((1u << 16) - 1)) |
|
||||
((r->res0_b_str & ((1u << 16) - 1)) << 16);
|
||||
p[17] = (r->res0_c_str & ((1u << 16) - 1)) |
|
||||
((r->res0_h_str & ((1u << 16) - 1)) << 16);
|
||||
p[16] = (r->layer_info & ((1u << 16) - 1)) |
|
||||
((r->res0_n_str & ((1u << 16) - 1)) << 16);
|
||||
p[15] = (r->opd2_h & ((1u << 12) - 1)) |
|
||||
((r->opd2_w & ((1u << 12) - 1)) << 12) |
|
||||
((r->dummy4 & ((1u << 4) - 1)) << 24) |
|
||||
((r->rsvd3 & ((1u << 4) - 1)) << 28);
|
||||
p[14] = ((r->opd1_w >> 4) & ((1u << 8) - 1)) |
|
||||
((r->opd2_n & ((1u << 12) - 1)) << 8) |
|
||||
((r->opd2_c & ((1u << 12) - 1)) << 20);
|
||||
p[13] = ((r->opd1_n >> 8) & ((1u << 4) - 1)) |
|
||||
((r->opd1_c & ((1u << 12) - 1)) << 4) |
|
||||
((r->opd1_h & ((1u << 12) - 1)) << 16) |
|
||||
((r->opd1_w & ((1u << 4) - 1)) << 28);
|
||||
p[12] = (r->opd0_h & ((1u << 12) - 1)) |
|
||||
((r->opd0_w & ((1u << 12) - 1)) << 12) |
|
||||
((r->opd1_n & ((1u << 8) - 1)) << 24);
|
||||
p[11] = (r->opd0_n & ((1u << 12) - 1)) |
|
||||
((r->opd0_c & ((1u << 12) - 1)) << 12) |
|
||||
((r->dummy3 & ((1u << 4) - 1)) << 24) |
|
||||
((r->rsvd2 & ((1u << 4) - 1)) << 28);
|
||||
p[10] = (r->opd2_addr & ((1u << 16) - 1)) |
|
||||
((r->opt_opd0_const & 1) << 16) |
|
||||
((r->opt_opd1_const & 1) << 17) |
|
||||
((r->opt_opd2_const & 1) << 18) |
|
||||
((r->short_nchwstr_same & 1) << 19) |
|
||||
((r->short_res0_str & ((1u << 2) - 1)) << 20) |
|
||||
((r->short_opd0_str & ((1u << 2) - 1)) << 22) |
|
||||
((r->short_opd1_str & ((1u << 2) - 1)) << 24) |
|
||||
((r->short_opd2_str & ((1u << 2) - 1)) << 26) |
|
||||
((r->dummy2 & ((1u << 4) - 1)) << 28);
|
||||
p[9] = ((r->opd0_addr >> 8) & ((1u << 16) - 1)) |
|
||||
((r->opd1_addr & ((1u << 16) - 1)) << 16);
|
||||
p[8] = (r->res0_addr & ((1u << 24) - 1)) |
|
||||
((r->opd0_addr & ((1u << 8) - 1)) << 24);
|
||||
p[7] = ((r->res0_h >> 8) & ((1u << 4) - 1)) |
|
||||
((r->res0_w & ((1u << 12) - 1)) << 4) |
|
||||
((r->conv_op_x_str & ((1u << 5) - 1)) << 16) |
|
||||
((r->conv_op_y_str & ((1u << 5) - 1)) << 21) |
|
||||
((r->cmd_pre_exe & ((1u << 2) - 1)) << 26) |
|
||||
((r->rsvd1 & ((1u << 4) - 1)) << 28);
|
||||
p[6] = (r->res0_n & ((1u << 12) - 1)) |
|
||||
((r->res0_c & ((1u << 12) - 1)) << 12) |
|
||||
((r->res0_h & ((1u << 8) - 1)) << 24);
|
||||
p[5] = (r->opd0_ins_val & ((1u << 16) - 1)) |
|
||||
((r->conv_opd0_up_pad & ((1u << 4) - 1)) << 16) |
|
||||
((r->conv_opd0_dn_pad & ((1u << 4) - 1)) << 20) |
|
||||
((r->conv_opd0_lf_pad & ((1u << 4) - 1)) << 24) |
|
||||
((r->conv_opd0_rt_pad & ((1u << 4) - 1)) << 28);
|
||||
p[4] = (r->conv_opd0_x_ins0 & ((1u << 4) - 1)) |
|
||||
((r->conv_opd0_y_ins0 & ((1u << 4) - 1)) << 4) |
|
||||
((r->conv_opd0_x_ins0_last & ((1u << 4) - 1)) << 8) |
|
||||
((r->conv_opd0_y_ins0_last & ((1u << 4) - 1)) << 12) |
|
||||
((r->conv_opd1_x_ins0 & ((1u << 4) - 1)) << 16) |
|
||||
((r->conv_opd1_y_ins0 & ((1u << 4) - 1)) << 20) |
|
||||
((r->dummy0 & ((1u << 8) - 1)) << 24);
|
||||
p[3] = (r->opt_res0_sign & 1) |
|
||||
((r->opt_opd0_sign & 1) << 1) |
|
||||
((r->opt_opd1_sign & 1) << 2) |
|
||||
((r->opt_opd2_sign & 1) << 3) |
|
||||
((r->opt_res0_seg & ((1u << 2) - 1)) << 4) |
|
||||
((r->opt_opd0_seg & ((1u << 2) - 1)) << 6) |
|
||||
((r->opt_opd1_seg & ((1u << 2) - 1)) << 8) |
|
||||
((r->opt_opd2_seg & 1) << 10) |
|
||||
((r->ps32_md & ((1u << 2) - 1)) << 11) |
|
||||
((r->double_conv & 1) << 13) |
|
||||
((r->opt_left_tran & 1) << 14) |
|
||||
((r->fp_round_typ & 1) << 15) |
|
||||
((r->opt_relu_typ & ((1u << 2) - 1)) << 16) |
|
||||
((r->opt_relu_value & ((1u << 8) - 1)) << 18) |
|
||||
((r->cmd_pre_exe_typ & 1) << 26) |
|
||||
((r->opt_res_add & 1) << 27) |
|
||||
((r->rsvd0 & ((1u << 4) - 1)) << 28);
|
||||
p[2] = (r->quan_m & (((uint64_t)1 << 32) - 1));
|
||||
p[1] = (r->cmd_id_tpu & ((1u << 16) - 1)) |
|
||||
((r->cmd_id_gdma & ((1u << 16) - 1)) << 16);
|
||||
p[0] = (r->cmd_en & 1) |
|
||||
((r->cmd_end & 1) << 1) |
|
||||
((r->cmd_id_en & 1) << 2) |
|
||||
((r->cmd_keep & 1) << 3) |
|
||||
((r->cmd_intr_en & 1) << 4) |
|
||||
((r->tsk_typ & ((1u << 4) - 1)) << 5) |
|
||||
((r->tsk_eu_typ & ((1u << 5) - 1)) << 9) |
|
||||
((r->tsk_opd_num & ((1u << 2) - 1)) << 14) |
|
||||
((r->opt_res_shift & ((1u << 6) - 1)) << 16) |
|
||||
((r->opt_left_shift & ((1u << 5) - 1)) << 22) |
|
||||
((r->opt_shift_typ & 1) << 27) |
|
||||
((r->opt_rshift_typ & 1) << 28) |
|
||||
((r->dummy1 & 1) << 29) |
|
||||
((r->opd_typ & 1) << 30) |
|
||||
((r->opt_chl_quan & 1) << 31);
|
||||
}
|
||||
|
||||
static inline void reset_tiu_reg(tiu_reg_t *r)
|
||||
{
|
||||
r->cmd_en = 0x0;
|
||||
r->cmd_end = 0x0;
|
||||
r->cmd_id_en = 0x0;
|
||||
r->cmd_keep = 0x0;
|
||||
r->cmd_intr_en = 0x0;
|
||||
r->tsk_typ = 0x0;
|
||||
r->tsk_eu_typ = 0x0;
|
||||
r->tsk_opd_num = 0x3;
|
||||
r->opt_res_shift = 0xa;
|
||||
r->opt_left_shift = 0x2;
|
||||
r->opt_shift_typ = 0x1;
|
||||
r->opt_rshift_typ = 0x1;
|
||||
r->dummy1 = 0x0;
|
||||
r->opd_typ = 0x0;
|
||||
r->opt_chl_quan = 0x0;
|
||||
r->cmd_id_tpu = 0x0;
|
||||
r->cmd_id_gdma = 0x0;
|
||||
r->quan_m = 0x0;
|
||||
r->opt_res0_sign = 0x0;
|
||||
r->opt_opd0_sign = 0x0;
|
||||
r->opt_opd1_sign = 0x1;
|
||||
r->opt_opd2_sign = 0x1;
|
||||
r->opt_res0_seg = 0x1;
|
||||
r->opt_opd0_seg = 0x1;
|
||||
r->opt_opd1_seg = 0x1;
|
||||
r->opt_opd2_seg = 0x0;
|
||||
r->ps32_md = 0x0;
|
||||
r->double_conv = 0x0;
|
||||
r->opt_left_tran = 0x0;
|
||||
r->fp_round_typ = 0x0;
|
||||
r->opt_relu_typ = 0x0;
|
||||
r->opt_relu_value = 0x0;
|
||||
r->cmd_pre_exe_typ = 0x0;
|
||||
r->opt_res_add = 0x0;
|
||||
r->rsvd0 = 0x0;
|
||||
r->conv_opd0_x_ins0 = 0x0;
|
||||
r->conv_opd0_y_ins0 = 0x0;
|
||||
r->conv_opd0_x_ins0_last = 0x0;
|
||||
r->conv_opd0_y_ins0_last = 0x0;
|
||||
r->conv_opd1_x_ins0 = 0x0;
|
||||
r->conv_opd1_y_ins0 = 0x0;
|
||||
r->dummy0 = 0x0;
|
||||
r->opd0_ins_val = 0x0;
|
||||
r->conv_opd0_up_pad = 0x0;
|
||||
r->conv_opd0_dn_pad = 0x0;
|
||||
r->conv_opd0_lf_pad = 0x0;
|
||||
r->conv_opd0_rt_pad = 0x0;
|
||||
r->res0_n = 0x1;
|
||||
r->res0_c = 0x1;
|
||||
r->res0_h = 0x1;
|
||||
r->res0_w = 0x10;
|
||||
r->conv_op_x_str = 0x1;
|
||||
r->conv_op_y_str = 0x1;
|
||||
r->cmd_pre_exe = 0x0;
|
||||
r->rsvd1 = 0x1;
|
||||
r->res0_addr = 0x0;
|
||||
r->opd0_addr = 0x0;
|
||||
r->opd1_addr = 0x0;
|
||||
r->opd2_addr = 0x0;
|
||||
r->opt_opd0_const = 0x0;
|
||||
r->opt_opd1_const = 0x0;
|
||||
r->opt_opd2_const = 0x0;
|
||||
r->short_nchwstr_same = 0x0;
|
||||
r->short_res0_str = 0x0;
|
||||
r->short_opd0_str = 0x0;
|
||||
r->short_opd1_str = 0x0;
|
||||
r->short_opd2_str = 0x0;
|
||||
r->dummy2 = 0x0;
|
||||
r->opd0_n = 0x1;
|
||||
r->opd0_c = 0x1;
|
||||
r->dummy3 = 0x0;
|
||||
r->rsvd2 = 0x2;
|
||||
r->opd0_h = 0x1;
|
||||
r->opd0_w = 0x10;
|
||||
r->opd1_n = 0x1;
|
||||
r->opd1_c = 0x1;
|
||||
r->opd1_h = 0x1;
|
||||
r->opd1_w = 0x10;
|
||||
r->opd2_n = 0x1;
|
||||
r->opd2_c = 0x1;
|
||||
r->opd2_h = 0x1;
|
||||
r->opd2_w = 0x10;
|
||||
r->dummy4 = 0x0;
|
||||
r->rsvd3 = 0x3;
|
||||
r->layer_info = 0x0;
|
||||
r->res0_n_str = 0x10;
|
||||
r->res0_c_str = 0x10;
|
||||
r->res0_h_str = 0x0;
|
||||
r->res0_w_str = 0x1;
|
||||
r->res0_b_str = 0x10;
|
||||
r->opd0_n_str = 0x10;
|
||||
r->dummy5 = 0x0;
|
||||
r->rsvd4 = 0x4;
|
||||
r->opd0_c_str = 0x10;
|
||||
r->opd0_h_str = 0x0;
|
||||
r->opd0_w_str = 0x1;
|
||||
r->opd0_b_str = 0x10;
|
||||
r->opd1_n_str = 0x10;
|
||||
r->opd1_c_str = 0x10;
|
||||
r->opd1_h_str = 0x0;
|
||||
r->dummy6 = 0x0;
|
||||
r->rsvd5 = 0x5;
|
||||
r->opd1_w_str = 0x1;
|
||||
r->opd1_b_str = 0x10;
|
||||
r->opd2_n_str = 0x10;
|
||||
r->opd2_c_str = 0x10;
|
||||
r->opd2_h_str = 0x0;
|
||||
r->opd2_w_str = 0x1;
|
||||
r->opd2_b_str = 0x10;
|
||||
r->dummy7 = 0x0;
|
||||
r->rsvd6 = 0x6;
|
||||
}
|
||||
|
||||
static inline void trace_tiu_reg(tiu_reg_t *r, const char *tag)
|
||||
{
|
||||
#define trace_one_reg(name) \
|
||||
printf(" %s: 0x%llx\n", #name, (ullong)r->name)
|
||||
|
||||
printf("--- %s ---\n", tag);
|
||||
trace_one_reg(cmd_en);
|
||||
trace_one_reg(cmd_end);
|
||||
trace_one_reg(cmd_id_en);
|
||||
trace_one_reg(cmd_keep);
|
||||
trace_one_reg(cmd_intr_en);
|
||||
trace_one_reg(tsk_typ);
|
||||
trace_one_reg(tsk_eu_typ);
|
||||
trace_one_reg(tsk_opd_num);
|
||||
trace_one_reg(opt_res_shift);
|
||||
trace_one_reg(opt_left_shift);
|
||||
trace_one_reg(opt_shift_typ);
|
||||
trace_one_reg(opt_rshift_typ);
|
||||
trace_one_reg(dummy1);
|
||||
trace_one_reg(opd_typ);
|
||||
trace_one_reg(opt_chl_quan);
|
||||
trace_one_reg(cmd_id_tpu);
|
||||
trace_one_reg(cmd_id_gdma);
|
||||
trace_one_reg(quan_m);
|
||||
trace_one_reg(opt_res0_sign);
|
||||
trace_one_reg(opt_opd0_sign);
|
||||
trace_one_reg(opt_opd1_sign);
|
||||
trace_one_reg(opt_opd2_sign);
|
||||
trace_one_reg(opt_res0_seg);
|
||||
trace_one_reg(opt_opd0_seg);
|
||||
trace_one_reg(opt_opd1_seg);
|
||||
trace_one_reg(opt_opd2_seg);
|
||||
trace_one_reg(ps32_md);
|
||||
trace_one_reg(double_conv);
|
||||
trace_one_reg(opt_left_tran);
|
||||
trace_one_reg(fp_round_typ);
|
||||
trace_one_reg(opt_relu_typ);
|
||||
trace_one_reg(opt_relu_value);
|
||||
trace_one_reg(cmd_pre_exe_typ);
|
||||
trace_one_reg(opt_res_add);
|
||||
trace_one_reg(rsvd0);
|
||||
trace_one_reg(conv_opd0_x_ins0);
|
||||
trace_one_reg(conv_opd0_y_ins0);
|
||||
trace_one_reg(conv_opd0_x_ins0_last);
|
||||
trace_one_reg(conv_opd0_y_ins0_last);
|
||||
trace_one_reg(conv_opd1_x_ins0);
|
||||
trace_one_reg(conv_opd1_y_ins0);
|
||||
trace_one_reg(dummy0);
|
||||
trace_one_reg(opd0_ins_val);
|
||||
trace_one_reg(conv_opd0_up_pad);
|
||||
trace_one_reg(conv_opd0_dn_pad);
|
||||
trace_one_reg(conv_opd0_lf_pad);
|
||||
trace_one_reg(conv_opd0_rt_pad);
|
||||
trace_one_reg(res0_n);
|
||||
trace_one_reg(res0_c);
|
||||
trace_one_reg(res0_h);
|
||||
trace_one_reg(res0_w);
|
||||
trace_one_reg(conv_op_x_str);
|
||||
trace_one_reg(conv_op_y_str);
|
||||
trace_one_reg(cmd_pre_exe);
|
||||
trace_one_reg(rsvd1);
|
||||
trace_one_reg(res0_addr);
|
||||
trace_one_reg(opd0_addr);
|
||||
trace_one_reg(opd1_addr);
|
||||
trace_one_reg(opd2_addr);
|
||||
trace_one_reg(opt_opd0_const);
|
||||
trace_one_reg(opt_opd1_const);
|
||||
trace_one_reg(opt_opd2_const);
|
||||
trace_one_reg(short_nchwstr_same);
|
||||
trace_one_reg(short_res0_str);
|
||||
trace_one_reg(short_opd0_str);
|
||||
trace_one_reg(short_opd1_str);
|
||||
trace_one_reg(short_opd2_str);
|
||||
trace_one_reg(dummy2);
|
||||
trace_one_reg(opd0_n);
|
||||
trace_one_reg(opd0_c);
|
||||
trace_one_reg(dummy3);
|
||||
trace_one_reg(rsvd2);
|
||||
trace_one_reg(opd0_h);
|
||||
trace_one_reg(opd0_w);
|
||||
trace_one_reg(opd1_n);
|
||||
trace_one_reg(opd1_c);
|
||||
trace_one_reg(opd1_h);
|
||||
trace_one_reg(opd1_w);
|
||||
trace_one_reg(opd2_n);
|
||||
trace_one_reg(opd2_c);
|
||||
trace_one_reg(opd2_h);
|
||||
trace_one_reg(opd2_w);
|
||||
trace_one_reg(dummy4);
|
||||
trace_one_reg(rsvd3);
|
||||
trace_one_reg(layer_info);
|
||||
trace_one_reg(res0_n_str);
|
||||
trace_one_reg(res0_c_str);
|
||||
trace_one_reg(res0_h_str);
|
||||
trace_one_reg(res0_w_str);
|
||||
trace_one_reg(res0_b_str);
|
||||
trace_one_reg(opd0_n_str);
|
||||
trace_one_reg(dummy5);
|
||||
trace_one_reg(rsvd4);
|
||||
trace_one_reg(opd0_c_str);
|
||||
trace_one_reg(opd0_h_str);
|
||||
trace_one_reg(opd0_w_str);
|
||||
trace_one_reg(opd0_b_str);
|
||||
trace_one_reg(opd1_n_str);
|
||||
trace_one_reg(opd1_c_str);
|
||||
trace_one_reg(opd1_h_str);
|
||||
trace_one_reg(dummy6);
|
||||
trace_one_reg(rsvd5);
|
||||
trace_one_reg(opd1_w_str);
|
||||
trace_one_reg(opd1_b_str);
|
||||
trace_one_reg(opd2_n_str);
|
||||
trace_one_reg(opd2_c_str);
|
||||
trace_one_reg(opd2_h_str);
|
||||
trace_one_reg(opd2_w_str);
|
||||
trace_one_reg(opd2_b_str);
|
||||
trace_one_reg(dummy7);
|
||||
trace_one_reg(rsvd6);
|
||||
}
|
||||
#endif /* CV181X_TIU_REG_H */
|
||||
38
cvikernel/include/cvikernel/cv181x/cv181x_tpu_cfg.h
Normal file
38
cvikernel/include/cvikernel/cv181x/cv181x_tpu_cfg.h
Normal file
@ -0,0 +1,38 @@
|
||||
#ifndef __CV181X_TPU_CFG__
|
||||
#define __CV181X_TPU_CFG__
|
||||
|
||||
#define CV181X_VER 182202
|
||||
#define CV181X_HW_NPU_SHIFT 3
|
||||
#define CV181X_HW_EU_SHIFT 4
|
||||
#define CV181X_HW_LMEM_SHIFT 15
|
||||
#define CV181X_HW_LMEM_BANKS 8
|
||||
#define CV181X_HW_LMEM_BANK_SIZE 0x1000
|
||||
#define CV181X_HW_NODE_CHIP_SHIFT 0
|
||||
#define CV181X_HW_NPU_NUM (1 << CV181X_HW_NPU_SHIFT)
|
||||
#define CV181X_HW_EU_NUM (1 << CV181X_HW_EU_SHIFT)
|
||||
#define CV181X_HW_LMEM_SIZE (1 << CV181X_HW_LMEM_SHIFT)
|
||||
#define CV181X_HW_LMEM_START_ADDR 0x0C000000
|
||||
#define CV181X_HW_NODE_CHIP_NUM (1 << CV181X_HW_NODE_CHIP_SHIFT)
|
||||
|
||||
#if (CV181X_HW_LMEM_SIZE != (CV181X_HW_LMEM_BANK_SIZE * CV181X_HW_LMEM_BANKS))
|
||||
#error "Set wrong TPU configuration."
|
||||
#endif
|
||||
|
||||
#define CV181X_GLOBAL_MEM_START_ADDR 0x0
|
||||
#define CV181X_GLOBAL_MEM_SIZE 0x100000000 //
|
||||
|
||||
#define CV181X_GLOBAL_TIU_CMDBUF_ADDR 0x00000000
|
||||
#define CV181X_GLOBAL_TDMA_CMDBUF_ADDR 0x00800000
|
||||
#define CV181X_GLOBAL_TIU_CMDBUF_RESERVED_SIZE 0x00800000 // 8MB
|
||||
#define CV181X_GLOBAL_TDMA_CMDBUF_RESERVED_SIZE 0x00800000 // 8MB
|
||||
#define CV181X_GLOBAL_POOL_RESERVED_SIZE (CV181X_GLOBAL_MEM_SIZE - CV181X_GLOBAL_TIU_CMDBUF_RESERVED_SIZE - CV181X_GLOBAL_TDMA_CMDBUF_RESERVED_SIZE)
|
||||
|
||||
#define CV181X_UART_CTLR_BASE_ADDR 0x04140000
|
||||
|
||||
#define CV181X_TDMA_ENGINE_BASE_ADDR 0x0C100000
|
||||
#define CV181X_TDMA_ENGINE_END_ADDR (CV181X_TDMA_ENGINE_BASE_ADDR + 0x1000)
|
||||
|
||||
#define CV181X_TIU_ENGINE_BASE_ADDR 0x0C101000 //"NPS Register" in memory map?
|
||||
#define CV181X_TIU_ENGINE_END_ADDR (CV181X_TIU_ENGINE_BASE_ADDR + 0x1000)
|
||||
|
||||
#endif
|
||||
1171
cvikernel/include/cvikernel/cvikernel.h
Normal file
1171
cvikernel/include/cvikernel/cvikernel.h
Normal file
File diff suppressed because it is too large
Load Diff
333
cvikernel/include/cvikernel/cvk_fp_convert.h
Normal file
333
cvikernel/include/cvikernel/cvk_fp_convert.h
Normal file
@ -0,0 +1,333 @@
|
||||
#ifndef CVK_FP_CONVERT_H
|
||||
#define CVK_FP_CONVERT_H
|
||||
|
||||
#if __arm__
|
||||
#define __DISABLE_FENV__
|
||||
#endif
|
||||
|
||||
#ifndef __DISABLE_FENV__
|
||||
#include <fenv.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static inline uint8_t cvk_convert_bf16_u8(uint16_t data);
|
||||
static inline uint8_t cvk_convert_bf16_u8_rnd(uint16_t data, int int8_rnd_md);
|
||||
static inline int8_t cvk_convert_bf16_s8_rnd(uint16_t data, int int8_rnd_md);
|
||||
static inline int8_t cvk_convert_bf16_s8(uint16_t data);
|
||||
static inline uint16_t cvk_convert_int8_bf16(uint8_t data, uint8_t sign);
|
||||
static inline uint32_t cvk_convert_fp32_u32(float fp32);
|
||||
static inline uint32_t cvk_convert_fp32_hex(float val);
|
||||
static inline float cvk_convert_hex_fp32(uint32_t hval);
|
||||
|
||||
static inline float cvk_convert_bf16_fp32(uint16_t bf16);
|
||||
static inline uint16_t cvk_convert_fp32_bf16(float fp32);
|
||||
|
||||
static inline void cvk_f32_integer(void *if32, void *o_integer, int integer_size, int accumulate, int int8_signed, int int8_rnd_md);
|
||||
//static inline void f32_integer(void *if32, void *o_integer,
|
||||
// 0 for 32 bit , 1 for 16 bit , 2 for 8 bit
|
||||
// int integer_size, int accumulate = 0, int int8_signed = 1, int int8_rnd_md = 0);
|
||||
|
||||
union convert_type_float {
|
||||
float fval;
|
||||
uint16_t bf16[2];
|
||||
uint32_t ival;
|
||||
};
|
||||
|
||||
typedef union convert_type_float convert_int_float;
|
||||
static const uint16_t NAN_VALUE = 0x7FC0;
|
||||
|
||||
//static int round_mode = 0;
|
||||
static uint8_t cvk_float_isnan(const float x) {
|
||||
//return isnan(x);
|
||||
return x != x;
|
||||
}
|
||||
|
||||
static inline int cvk_set_store_feround()
|
||||
{
|
||||
#ifndef __DISABLE_FENV__
|
||||
int round_mode = fegetround();
|
||||
fesetround(FE_TOWARDZERO);
|
||||
return round_mode;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void cvk_restore_feround(int round_mode)
|
||||
{
|
||||
#ifndef __DISABLE_FENV__
|
||||
fesetround(round_mode);
|
||||
#else
|
||||
(void)round_mode;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline uint8_t cvk_convert_bf16_u8_rnd(uint16_t data, int int8_rnd_md)
|
||||
{
|
||||
/* convert bf16 to float32*/
|
||||
float fp32;
|
||||
convert_int_float convert_val;
|
||||
fp32 = cvk_convert_bf16_fp32(data);
|
||||
/* convert float32 to uint8_t*/
|
||||
cvk_f32_integer((void*)&fp32, &convert_val.ival, 2, 0, 0, int8_rnd_md);
|
||||
return (uint8_t) convert_val.ival;
|
||||
}
|
||||
|
||||
static inline uint8_t cvk_convert_bf16_u8(uint16_t data)
|
||||
{
|
||||
return (uint8_t) cvk_convert_bf16_u8_rnd(data, 0);
|
||||
}
|
||||
|
||||
static inline int8_t cvk_convert_bf16_s8_rnd(uint16_t data, int int8_rnd_md)
|
||||
{
|
||||
/* convert bf16 to float32 */
|
||||
float fp32;
|
||||
convert_int_float convert_val;
|
||||
fp32 = cvk_convert_bf16_fp32(data);
|
||||
/* convert float32 to uint8_t*/
|
||||
cvk_f32_integer((void*)&fp32, &convert_val.ival, 2, 0, 1, int8_rnd_md);
|
||||
return (int8_t) convert_val.ival;
|
||||
}
|
||||
|
||||
static inline int8_t cvk_convert_bf16_s8(uint16_t data)
|
||||
{
|
||||
return (int8_t) cvk_convert_bf16_s8_rnd(data, 0);
|
||||
}
|
||||
|
||||
static inline uint16_t cvk_convert_int8_bf16(uint8_t data, uint8_t sign)
|
||||
{
|
||||
int32_t val = sign ? (int8_t) data : (uint8_t) data;
|
||||
/* need to round to bf16 mode */
|
||||
return cvk_convert_fp32_bf16((float) val);
|
||||
}
|
||||
|
||||
static inline uint16_t cvk_convert_fp32_bf16(float fp32)
|
||||
{
|
||||
if (cvk_float_isnan(fp32))
|
||||
return NAN_VALUE;
|
||||
convert_int_float convert_val;
|
||||
convert_val.fval = fp32;
|
||||
uint32_t input = convert_val.ival;
|
||||
uint32_t lsb = (input >> 16) & 1;
|
||||
uint32_t rounding_bias = 0x7fff + lsb;
|
||||
input += rounding_bias;
|
||||
convert_val.bf16[1] = (uint16_t) (input >> 16);
|
||||
|
||||
/* HW behavior */
|
||||
if ((convert_val.bf16[1] & 0x7f80) == 0x7f80) {
|
||||
convert_val.bf16[1] = 0x7f7f;
|
||||
}
|
||||
return convert_val.bf16[1];
|
||||
}
|
||||
|
||||
static inline uint8_t cvk_convert_fp32_u8(float fp32)
|
||||
{
|
||||
convert_int_float convert_val;
|
||||
cvk_f32_integer((void*)&fp32, &convert_val.ival, 2, 0, 0, 0);
|
||||
return (uint8_t) convert_val.ival;
|
||||
}
|
||||
|
||||
static inline int8_t cvk_convert_fp32_s8(float fp32)
|
||||
{
|
||||
convert_int_float convert_val;
|
||||
cvk_f32_integer((void*)&fp32, &convert_val.ival, 2, 0, 1, 0);
|
||||
return (int8_t) convert_val.ival;
|
||||
}
|
||||
|
||||
static inline uint32_t cvk_convert_fp32_u32(float fp32)
|
||||
{
|
||||
convert_int_float convert_val;
|
||||
cvk_f32_integer((void*)&fp32, &convert_val.ival, 0, 0, 0, 0);
|
||||
return (uint32_t) convert_val.ival;
|
||||
}
|
||||
|
||||
static inline int32_t cvk_convert_fp32_s32(float fp32)
|
||||
{
|
||||
convert_int_float convert_val;
|
||||
cvk_f32_integer((void*)&fp32, &convert_val.ival, 0, 0, 1, 0);
|
||||
return (int32_t) convert_val.ival;
|
||||
}
|
||||
|
||||
/* convert hex to float directly */
|
||||
static inline float cvk_convert_hex_fp32(uint32_t hval)
|
||||
{
|
||||
convert_int_float convert_val;
|
||||
convert_val.ival = hval;
|
||||
return convert_val.fval;
|
||||
}
|
||||
/* convert float to hex directly */
|
||||
static inline uint32_t cvk_convert_fp32_hex(float val)
|
||||
{
|
||||
convert_int_float convert_val;
|
||||
convert_val.fval = val;
|
||||
return convert_val.ival;
|
||||
}
|
||||
static inline float cvk_convert_bf16_fp32(uint16_t bf16)
|
||||
{
|
||||
convert_int_float convert_val;
|
||||
convert_val.bf16[1] = bf16;
|
||||
convert_val.bf16[0] = 0;
|
||||
return convert_val.fval;
|
||||
}
|
||||
|
||||
static inline void cvk_flt2int_flt(float x, unsigned long long* integer_part, float * sub_part, uint8_t sign)
|
||||
{
|
||||
convert_int_float work_x;
|
||||
int level_code;
|
||||
unsigned long tail_code;
|
||||
work_x.fval = x;
|
||||
level_code = ((work_x.ival >> 23) & 0xff) - 127;
|
||||
|
||||
//if the level code is negaive, the integer part of the float is zero
|
||||
if ( level_code < 0 ){
|
||||
*integer_part = 0;
|
||||
*sub_part = x;
|
||||
}
|
||||
else {
|
||||
tail_code = (work_x.ival) & 0x7fffff;
|
||||
tail_code = tail_code | 0x800000;
|
||||
|
||||
if (level_code < 23){
|
||||
tail_code >>= (23 - level_code);
|
||||
*integer_part = tail_code;
|
||||
work_x.ival &= 0xffffffff << (23 - level_code);
|
||||
*sub_part = x - work_x.fval;
|
||||
}
|
||||
else {
|
||||
tail_code <<= (level_code - 23);
|
||||
*integer_part = tail_code;
|
||||
if(level_code>30){
|
||||
*integer_part = 0x7fffffff;
|
||||
if(sign)*integer_part = 0x800000000;
|
||||
}
|
||||
*sub_part = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline static int cvk_flt2int(float ifval, int int8_rnd_md)
|
||||
{
|
||||
union {
|
||||
float floatNum;
|
||||
unsigned long intNum;
|
||||
} tempIfval;
|
||||
tempIfval.floatNum = ifval;
|
||||
uint8_t isPositive = ((tempIfval.intNum & 0x80000000UL) == 0x80000000UL) ? 0 : 1;
|
||||
float abs_fval = (!isPositive) ? -ifval : ifval;
|
||||
float sub_part;
|
||||
unsigned long long integer_part;
|
||||
uint8_t sign = !isPositive;
|
||||
cvk_flt2int_flt(abs_fval, &integer_part, &sub_part, sign);
|
||||
if (!isPositive)
|
||||
{
|
||||
unsigned long long result;
|
||||
if(int8_rnd_md == 0) { // round to nearest even
|
||||
if ( sub_part > 0.5f )
|
||||
{
|
||||
result = integer_part + 1;
|
||||
}
|
||||
else if (sub_part == 0.5f)
|
||||
{
|
||||
if ( integer_part & 0x1 )
|
||||
{
|
||||
result = integer_part + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = integer_part;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = integer_part;
|
||||
}
|
||||
} else { //round to zero
|
||||
result = integer_part;
|
||||
}
|
||||
if ( result > 0x80000000UL )
|
||||
{
|
||||
result = 0x80000000UL;
|
||||
}
|
||||
return -result;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned long long result;
|
||||
if(int8_rnd_md == 0) { // round to nearest even
|
||||
if ( sub_part > 0.5f )
|
||||
{
|
||||
result = integer_part + 1;
|
||||
}
|
||||
else if ( sub_part == 0.5f )
|
||||
{
|
||||
if ( integer_part & 0x1 )
|
||||
{
|
||||
result = integer_part + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = integer_part;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = integer_part;
|
||||
}
|
||||
} else {
|
||||
result = integer_part;
|
||||
}
|
||||
if ( result > 0x7fffffff )
|
||||
{
|
||||
result = 0x7fffffff;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void cvk_f32_integer(void *if32, void *o_integer, int integer_size, int accumulate, int int8_signed, int int8_rnd_md)
|
||||
{
|
||||
int i_tmp;
|
||||
float *f_tmp;
|
||||
f_tmp = (float *)if32;
|
||||
i_tmp = cvk_flt2int(*f_tmp, int8_rnd_md);
|
||||
int *o32 = (int *)o_integer;
|
||||
int dst_f32 = *o32;
|
||||
short *o16 = (short *)o_integer;
|
||||
short dst_o16 = *o32;
|
||||
char *o8 = (char *)o_integer;
|
||||
char dst_o8 = *o8;
|
||||
|
||||
if (integer_size == 0) {
|
||||
*o32 = i_tmp;
|
||||
} else if (integer_size == 1) {
|
||||
*o16 = i_tmp;
|
||||
} else{
|
||||
*o8 = i_tmp;
|
||||
int min = (int8_signed) ? -128 : 0;
|
||||
int max = (int8_signed) ? 127 : 255;
|
||||
if (i_tmp < min ){
|
||||
*o8 = min;
|
||||
}
|
||||
else if (i_tmp > max){
|
||||
*o8 = max;
|
||||
}
|
||||
//*o8 = i_tmp;
|
||||
}
|
||||
if (accumulate) {
|
||||
if (integer_size == 0) {
|
||||
*o32 += dst_f32;
|
||||
} else if (integer_size == 1) {
|
||||
*o16 += dst_o16;
|
||||
} else
|
||||
*o8 += dst_o8;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CVK_FP_CONVERT_H */
|
||||
728
cvikernel/include/cvikernel/cvk_vlc_compress.h
Normal file
728
cvikernel/include/cvikernel/cvk_vlc_compress.h
Normal file
@ -0,0 +1,728 @@
|
||||
#ifndef __CVK_VLC_COMPRESS_H__
|
||||
#define __CVK_VLC_COMPRESS_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define MAX_UNARY_FIELD_SIZE 47
|
||||
#define MAX_ORDER_K 5
|
||||
|
||||
static inline int divide_ceil(int numerator, int denominator)
|
||||
{
|
||||
return (numerator + denominator - 1) / denominator;
|
||||
}
|
||||
|
||||
/**
|
||||
* \data_type 0 means 8bit, 1 means 16bit
|
||||
*/
|
||||
static inline size_t get_out_bs_buf_size(uint64_t in_size, uint8_t data_type) {
|
||||
size_t blk_num = (data_type) ? ((in_size + 31) >> 5) : ((in_size + 15) >> 4);
|
||||
size_t in_size_pad = blk_num << (4 + data_type);
|
||||
size_t bs_buf_size = in_size_pad + (divide_ceil(blk_num, 16) << 4) + 16;
|
||||
return bs_buf_size;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t signedness;
|
||||
uint8_t is_bfloat16;
|
||||
uint8_t bias0;
|
||||
uint8_t bias1;
|
||||
uint8_t zero_guard_en;
|
||||
} CommandInfo;
|
||||
typedef struct
|
||||
{
|
||||
uint8_t *stream; // stream buffer pointer
|
||||
int bit_pos; // current pointer (in bit)
|
||||
int buf_size; // in byte
|
||||
} StreamBuffer;
|
||||
|
||||
static inline int8_t two_side_circular_shift(int8_t val, uint8_t bias0, uint8_t bias1);
|
||||
static inline int8_t inv_two_side_circular_shift(int8_t val, uint8_t bias0, uint8_t bias1);
|
||||
static inline uint8_t center_shift(uint8_t val, uint8_t bias, uint8_t zero_guard);
|
||||
static inline uint8_t inv_center_shift(uint8_t val, uint8_t bias, uint8_t zero_guard);
|
||||
|
||||
static inline void init_stream(StreamBuffer *bs, const uint8_t *buf, int buf_size, uint8_t read_only);
|
||||
|
||||
static inline void cvk_vlc_est_weight_bias(const uint8_t *ibuf, size_t isz, uint8_t signedness, uint8_t isBfloat16, CommandInfo *cmd_info);
|
||||
static inline void cvk_vlc_enc_int8(const uint8_t *ibuf, size_t isz, uint8_t *obuf, size_t *osz, CommandInfo *cmd_info);
|
||||
static inline void cvk_vlc_dec_int8_ext(const uint8_t *ibuf, size_t isz, uint8_t *obuf, size_t *bs_size);
|
||||
static inline void cvk_vlc_dec_int8(const uint8_t *ibuf, size_t isz, uint8_t *obuf);
|
||||
static inline void cvk_vlc_enc_bf16(const uint16_t *ibuf, size_t isz, uint8_t *obuf, size_t *osz, CommandInfo *cmd_info);
|
||||
static inline void cvk_vlc_dec_bf16_ext(const uint8_t *ibuf, size_t isz, uint16_t *obuf, size_t *bs_size);
|
||||
static inline void cvk_vlc_dec_bf16(const uint8_t *ibuf, size_t isz, uint16_t *obuf);
|
||||
|
||||
static inline uint8_t get_bit_val(uint8_t *buf, int byte_idx, int bit_idx)
|
||||
{
|
||||
return (buf[byte_idx] >> bit_idx) & 0x1;
|
||||
}
|
||||
|
||||
static inline uint8_t sign_to_unsign(uint8_t val)
|
||||
{
|
||||
uint8_t sign_i = (val >> 7) & 0x1;
|
||||
int abs_data_i = abs(((int8_t)val));
|
||||
return ((abs_data_i << 1) - sign_i);
|
||||
}
|
||||
|
||||
static inline int8_t unsign_to_sign(uint8_t val)
|
||||
{
|
||||
uint8_t sign_i = val & 0x1;
|
||||
int abs_data_i = (((int)val) + 1) >> 1;
|
||||
return (uint8_t)((sign_i == 1) ? (-abs_data_i) : abs_data_i);
|
||||
}
|
||||
|
||||
static inline void dispatch_bf16_data(const uint16_t *bf16_in, uint8_t *exp, uint8_t *frac, size_t isz)
|
||||
{
|
||||
for (size_t i = 0; i < isz; i++)
|
||||
{
|
||||
exp[i] = (uint8_t)((bf16_in[i] >> 7) & 0xFF);
|
||||
frac[i] = (uint8_t)(((bf16_in[i] >> 15) << 7) | (bf16_in[i] & 0x7F));
|
||||
}
|
||||
}
|
||||
|
||||
static inline void merge_bf16_data(const uint8_t *exp_in, const uint8_t *frac_in, uint16_t *bf16_out, size_t isz)
|
||||
{
|
||||
memset(bf16_out, 0, sizeof(uint16_t));
|
||||
for (size_t i = 0; i < isz; i++)
|
||||
{
|
||||
bf16_out[i] = ((frac_in[i] >> 7) << 15) | (exp_in[i] << 7) | (frac_in[i] & 0x7F);
|
||||
}
|
||||
}
|
||||
|
||||
// -- streaming operation handler --
|
||||
static inline void init_stream(StreamBuffer *bs, const uint8_t *buf, int buf_size, uint8_t read_only)
|
||||
{
|
||||
bs->bit_pos = 0;
|
||||
bs->stream = (uint8_t *)buf;
|
||||
bs->buf_size = buf_size;
|
||||
if (!read_only)
|
||||
memset((uint8_t *)buf, 0, sizeof(uint8_t) * buf_size);
|
||||
}
|
||||
|
||||
static inline void write_stream(StreamBuffer *bs, uint8_t *src, int bit_len)
|
||||
{
|
||||
for (int bit = 0; bit < bit_len; bit++)
|
||||
{
|
||||
int src_byte_i = bit / 8;
|
||||
int src_bit_i = bit % 8;
|
||||
int dest_byte_i = (bs->bit_pos + bit) / 8;
|
||||
int dest_bit_i = (bs->bit_pos + bit) % 8;
|
||||
bs->stream[dest_byte_i] |= (get_bit_val(src, src_byte_i, src_bit_i) << dest_bit_i);
|
||||
}
|
||||
bs->bit_pos += bit_len;
|
||||
}
|
||||
|
||||
static inline void move_stream_ptr(StreamBuffer *bs, int bit_len)
|
||||
{
|
||||
bs->bit_pos += bit_len;
|
||||
}
|
||||
|
||||
static inline void parse_stream(StreamBuffer *bs, uint8_t *dest, int bit_len)
|
||||
{
|
||||
memset(dest, 0, sizeof(uint8_t) * (bit_len + 7) >> 3);
|
||||
for (int bit = 0; bit < bit_len; bit++)
|
||||
{
|
||||
int dest_byte_i = bit / 8;
|
||||
int dest_bit_i = bit % 8;
|
||||
int bs_byte_i = (bs->bit_pos + bit) / 8;
|
||||
int bs_bit_i = (bs->bit_pos + bit) % 8;
|
||||
dest[dest_byte_i] |= (get_bit_val(bs->stream, bs_byte_i, bs_bit_i) << dest_bit_i);
|
||||
}
|
||||
bs->bit_pos += bit_len;
|
||||
}
|
||||
|
||||
// -- header read/write operation handler --
|
||||
static inline void vlc_enc_header(StreamBuffer *bs_header, CommandInfo *cmd_info, size_t blk_bs_size)
|
||||
{
|
||||
write_stream(bs_header, (uint8_t *)&blk_bs_size, 24); // bit[23:0] compressed block stream size
|
||||
move_stream_ptr(bs_header, 4); // bit[27:24] reserved
|
||||
write_stream(bs_header, (uint8_t *)&cmd_info->signedness, 1); // bit[28] signedness
|
||||
write_stream(bs_header, (uint8_t *)&cmd_info->is_bfloat16, 1); // bit[29] data type
|
||||
move_stream_ptr(bs_header, 2); // bit[31:30] bit depth
|
||||
write_stream(bs_header, (uint8_t *)&cmd_info->bias0, 8); // bit[39:32] bias0 for symbol remapping
|
||||
write_stream(bs_header, (uint8_t *)&cmd_info->bias1, 7); // bit[46:40] bias1 for symbol remapping
|
||||
write_stream(bs_header, (uint8_t *)&cmd_info->zero_guard_en, 1); // bit[47] zero guard
|
||||
}
|
||||
|
||||
static inline void vlc_dec_header_ext(StreamBuffer *bs_header, CommandInfo *cmd_info, size_t *blk_bs_size)
|
||||
{
|
||||
parse_stream(bs_header, (uint8_t *)blk_bs_size, 24); // bit[23:0] compressed block stream size
|
||||
move_stream_ptr(bs_header, 4); // bit[27:24] reserved
|
||||
parse_stream(bs_header, (uint8_t *)&cmd_info->signedness, 1); // bit[28] signedness
|
||||
parse_stream(bs_header, (uint8_t *)&cmd_info->is_bfloat16, 1); // bit[29] data type
|
||||
move_stream_ptr(bs_header, 2);
|
||||
parse_stream(bs_header, (uint8_t *)&cmd_info->bias0, 8); // bit[39:32] bias0 for symbol remapping
|
||||
parse_stream(bs_header, (uint8_t *)&cmd_info->bias1, 7); // bit[46:40] bias1 for symbol remapping
|
||||
parse_stream(bs_header, (uint8_t *)&cmd_info->zero_guard_en, 1); // bit[47] zero guard
|
||||
}
|
||||
|
||||
static inline void vlc_dec_header(StreamBuffer *bs_header, CommandInfo *cmd_info)
|
||||
{
|
||||
size_t blk_bs_size;
|
||||
vlc_dec_header_ext(bs_header, cmd_info, &blk_bs_size);
|
||||
}
|
||||
|
||||
// -- symbol remmaping handler --
|
||||
static inline uint8_t center_shift(uint8_t val, uint8_t bias, uint8_t zero_guard)
|
||||
{
|
||||
if (val == 0 && zero_guard)
|
||||
return 0;
|
||||
|
||||
int16_t shift_data_i = val - bias;
|
||||
uint8_t range = (bias <= 128) ? bias : 255 - bias;
|
||||
if (bias <= 128)
|
||||
{
|
||||
return (val >= (range << 1)) ? val : sign_to_unsign(shift_data_i) + zero_guard;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (val < (bias - range)) ? (range + bias - val + zero_guard) : (sign_to_unsign(shift_data_i) + zero_guard);
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint8_t inv_center_shift(uint8_t val, uint8_t bias, uint8_t zero_guard)
|
||||
{
|
||||
if (val == 0 && zero_guard)
|
||||
return 0;
|
||||
|
||||
uint8_t unsign_data_i = val - zero_guard;
|
||||
uint8_t range = (bias <= 128) ? bias : 255 - bias;
|
||||
if (bias <= 128)
|
||||
{
|
||||
return (val >= (range << 1)) ? val : unsign_to_sign(unsign_data_i) + bias;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (unsign_data_i > (range << 1)) ? (range + bias - val + zero_guard) : unsign_to_sign(unsign_data_i) + bias;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int8_t two_side_circular_shift(int8_t val, uint8_t bias0, uint8_t bias1)
|
||||
{
|
||||
if (val == 0)
|
||||
return 0;
|
||||
|
||||
uint8_t sign = (val < 0) ? true : false;
|
||||
int32_t abs_val = abs(val);
|
||||
abs_val -= (sign) ? bias1 : bias0;
|
||||
abs_val += (abs_val <= 0) ? (127 + sign) : 0;
|
||||
return (sign) ? -abs_val : abs_val;
|
||||
}
|
||||
|
||||
static inline int8_t inv_two_side_circular_shift(int8_t val, uint8_t bias0, uint8_t bias1)
|
||||
{
|
||||
if (val == 0)
|
||||
return 0;
|
||||
|
||||
uint8_t sign = (val < 0) ? true : false;
|
||||
uint32_t abs_val = (uint32_t)abs(val);
|
||||
abs_val += (sign) ? bias1 : bias0;
|
||||
int32_t abs_val_minus = abs_val - (127 + sign);
|
||||
uint8_t abs_val_lsb = ((abs_val_minus <= 0)
|
||||
? (uint8_t)abs_val
|
||||
: (uint8_t)abs_val_minus) &
|
||||
0xFF;
|
||||
return (sign) ? -abs_val_lsb : abs_val_lsb;
|
||||
}
|
||||
|
||||
static inline void symbol_remapping(uint8_t *blk_in, uint8_t *blk_out, uint8_t bias0, uint8_t bias1, uint8_t signedness, uint8_t is_bf16_exp, uint8_t zero_guard)
|
||||
{
|
||||
if (is_bf16_exp == false && signedness == false)
|
||||
{
|
||||
// remapping bypass
|
||||
memcpy(blk_out, blk_in, sizeof(uint8_t) * 16);
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_bf16_exp == true)
|
||||
{
|
||||
// center circular shift
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
blk_out[i] = center_shift(blk_in[i], bias0, zero_guard);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// two-side circular shift
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
int8_t shift_data_i = two_side_circular_shift((int8_t)blk_in[i], bias0, bias1);
|
||||
blk_out[i] = sign_to_unsign(shift_data_i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void inv_symbol_remapping(uint8_t *blk_in, uint8_t *blk_out, uint8_t bias0, uint8_t bias1, uint8_t signedness, uint8_t is_bf16_exp, uint8_t zero_guard)
|
||||
{
|
||||
if (is_bf16_exp == false && signedness == false)
|
||||
{
|
||||
// remapping bypass
|
||||
memcpy(blk_out, blk_in, sizeof(uint8_t) * 16);
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_bf16_exp == true)
|
||||
{
|
||||
// center circular shift
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
blk_out[i] = inv_center_shift(blk_in[i], bias0, zero_guard);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// two-side circular shift
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
int8_t sign_data_i = unsign_to_sign(blk_in[i]);
|
||||
blk_out[i] = (uint8_t)inv_two_side_circular_shift(sign_data_i, bias0, bias1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline int vlc_estimate_block_order(uint8_t *blk_in, uint8_t bf16_zvc_en)
|
||||
{
|
||||
int best_k = 0;
|
||||
int best_bs_size = 0x7FFFFFFF;
|
||||
|
||||
for (int k = 0; k <= (int)MAX_ORDER_K; k++)
|
||||
{
|
||||
uint8_t remain_field_size = k << 4;
|
||||
int unary_field_len = 0;
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
uint8_t group_idx = blk_in[i] >> k;
|
||||
unary_field_len += (group_idx + 1);
|
||||
}
|
||||
int znum_bit = (bf16_zvc_en && k > 0) ? 4 : 0;
|
||||
int blk_size = (unary_field_len <= MAX_UNARY_FIELD_SIZE)
|
||||
? remain_field_size + unary_field_len + znum_bit
|
||||
: 255;
|
||||
if (blk_size < best_bs_size)
|
||||
{
|
||||
best_k = k;
|
||||
best_bs_size = blk_size;
|
||||
}
|
||||
}
|
||||
|
||||
best_k = (best_bs_size > 128) ? -1 : best_k;
|
||||
return best_k;
|
||||
}
|
||||
// -- vlc block parrelel GR encode/decode --
|
||||
static inline uint8_t vlc_gr_enc_block_data(uint8_t *blk_in, StreamBuffer *bs, int order_k, uint8_t bf16_zvc_en)
|
||||
{
|
||||
// uncompressed mode
|
||||
if (order_k == -1)
|
||||
{
|
||||
write_stream(bs, blk_in, 128);
|
||||
return 128;
|
||||
}
|
||||
|
||||
// remain field
|
||||
uint8_t remain_field[16] = {0};
|
||||
uint8_t unary_field[8] = {0};
|
||||
uint8_t sym_end_pos[16] = {0};
|
||||
uint8_t unary_field_len = 0;
|
||||
int sym_end_pos_accum = -1;
|
||||
|
||||
// bit plane encode for remain field
|
||||
for (int k = 0; k < order_k; k++)
|
||||
{
|
||||
uint8_t bit_plane0 = 0, bit_plane1 = 0;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
bit_plane0 |= (get_bit_val(blk_in, i, k) << i);
|
||||
bit_plane1 |= (get_bit_val(blk_in, i + 8, k) << i);
|
||||
}
|
||||
remain_field[k << 1] = bit_plane0;
|
||||
remain_field[(k << 1) + 1] = bit_plane1;
|
||||
}
|
||||
write_stream(bs, remain_field, order_k << 4);
|
||||
|
||||
if (bf16_zvc_en && order_k > 0)
|
||||
{
|
||||
int zero_num = 0;
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
if (blk_in[i] == 0)
|
||||
zero_num++;
|
||||
}
|
||||
// assert(zero_num < 16);
|
||||
if (zero_num >= 16)
|
||||
return 0;
|
||||
|
||||
write_stream(bs, (uint8_t *)&zero_num, 4);
|
||||
}
|
||||
|
||||
// unary encode for unary field
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
int group_idx = blk_in[i] >> order_k;
|
||||
sym_end_pos_accum += (group_idx + 1);
|
||||
sym_end_pos[i] = sym_end_pos_accum;
|
||||
int byte_idx = sym_end_pos[i] / 8;
|
||||
int bit_idx = sym_end_pos[i] % 8;
|
||||
unary_field[byte_idx] |= (1 << (bit_idx));
|
||||
}
|
||||
unary_field_len = sym_end_pos[15] + 1;
|
||||
|
||||
//assert(unary_field_len <= MAX_UNARY_FIELD_SIZE);
|
||||
if (unary_field_len > MAX_UNARY_FIELD_SIZE)
|
||||
return 0;
|
||||
|
||||
uint8_t ulen = (unary_field_len - 16) & 0x1F;
|
||||
write_stream(bs, unary_field, unary_field_len);
|
||||
|
||||
return ulen;
|
||||
}
|
||||
|
||||
static inline void vlc_gr_dec_block_data(StreamBuffer *bs, uint8_t bs_size, uint8_t *rec, int order_k, uint8_t bf16_zvc_en)
|
||||
{
|
||||
// assert(bs_size <= 128);
|
||||
if (bs_size > 128)
|
||||
return;
|
||||
|
||||
// uncompressed mode
|
||||
if (order_k == -1)
|
||||
{
|
||||
parse_stream(bs, rec, 128);
|
||||
return;
|
||||
}
|
||||
|
||||
// remain field
|
||||
uint8_t remain_data[16] = {0};
|
||||
uint8_t remain_bs[16] = {0};
|
||||
uint8_t unary_field[8] = {0};
|
||||
uint8_t sym_end_pos[16] = {0};
|
||||
uint8_t unary_sym[16] = {0};
|
||||
uint8_t remain_field_size = order_k << 4;
|
||||
|
||||
parse_stream(bs, remain_bs, remain_field_size);
|
||||
// bit plane encode for remain field
|
||||
for (int k = 0; k < order_k; k++)
|
||||
{
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
remain_data[i] |= (get_bit_val(remain_bs, k << 1, i) << k);
|
||||
remain_data[i + 8] |= (get_bit_val(remain_bs, (k << 1) + 1, i) << k);
|
||||
}
|
||||
}
|
||||
|
||||
// zero number info
|
||||
int znum_bit = (bf16_zvc_en && order_k > 0) ? 4 : 0;
|
||||
uint8_t znum = 0;
|
||||
parse_stream(bs, &znum, znum_bit);
|
||||
|
||||
// unary encode for unary field
|
||||
uint8_t unary_field_len = bs_size - remain_field_size - znum_bit;
|
||||
parse_stream(bs, unary_field, unary_field_len);
|
||||
|
||||
int sym_cnt = 0;
|
||||
for (uint8_t ubit_i = 0; ubit_i < unary_field_len; ubit_i++)
|
||||
{
|
||||
int byte_idx = ubit_i / 8;
|
||||
int bit_idx = ubit_i % 8;
|
||||
if (get_bit_val(unary_field, byte_idx, bit_idx) == 1)
|
||||
{
|
||||
sym_end_pos[sym_cnt] = ubit_i;
|
||||
sym_cnt++;
|
||||
}
|
||||
}
|
||||
unary_sym[0] = sym_end_pos[0];
|
||||
for (int i = 1; i < 16; i++)
|
||||
{
|
||||
unary_sym[i] = sym_end_pos[i] - sym_end_pos[i - 1] - 1;
|
||||
}
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
rec[i] = (unary_sym[i] << order_k) + remain_data[i];
|
||||
}
|
||||
}
|
||||
|
||||
// -- vlc encode int8 entry function --
|
||||
static inline void cvk_vlc_enc_int8(const uint8_t *ibuf, size_t isz, uint8_t *obuf, size_t *osz, CommandInfo *cmd_info)
|
||||
{
|
||||
StreamBuffer bs_header, bs_kmap, bs_data;
|
||||
size_t blk_num = (isz + 15) >> 4;
|
||||
size_t header_size = 16;
|
||||
size_t kmap_size = divide_ceil(blk_num, 16) << 4;
|
||||
size_t bs_buf_size = header_size + kmap_size + (blk_num << 4);
|
||||
uint8_t *bsbuf = (uint8_t *)calloc(bs_buf_size, sizeof(uint8_t));
|
||||
|
||||
// block encode
|
||||
init_stream(&bs_kmap, bsbuf + header_size, kmap_size, false);
|
||||
init_stream(&bs_data, bsbuf + header_size + kmap_size, blk_num << 4, false);
|
||||
|
||||
for (size_t blk_idx = 0; blk_idx < blk_num; blk_idx++)
|
||||
{
|
||||
uint8_t blk_data[16] = {0}, blk_sr_data[16] = {0};
|
||||
size_t in_size = (blk_idx == (blk_num - 1)) ? isz - (blk_idx << 4) : 16;
|
||||
memcpy(blk_data, &ibuf[blk_idx << 4], sizeof(uint8_t) * in_size);
|
||||
|
||||
symbol_remapping(blk_data, blk_sr_data, cmd_info->bias0, cmd_info->bias1, cmd_info->signedness, false, false);
|
||||
|
||||
int k = vlc_estimate_block_order(blk_sr_data, false);
|
||||
uint8_t ulen = vlc_gr_enc_block_data(blk_sr_data, &bs_data, k, false);
|
||||
uint8_t k_info = (k == -1) ? 0xE0 : (k << 5) + ulen;
|
||||
write_stream(&bs_kmap, &k_info, 8);
|
||||
}
|
||||
|
||||
int blk_bs_size = divide_ceil(((bs_data.bit_pos + 7) >> 3), 16) << 4; // 16 byte align
|
||||
*osz = header_size + kmap_size + blk_bs_size;
|
||||
|
||||
// write header
|
||||
init_stream(&bs_header, bsbuf, header_size, false);
|
||||
vlc_enc_header(&bs_header, cmd_info, blk_bs_size);
|
||||
|
||||
memcpy(obuf, bsbuf, (*osz) * sizeof(uint8_t));
|
||||
free(bsbuf);
|
||||
}
|
||||
|
||||
// -- vlc decode int8 entry function --
|
||||
static inline void cvk_vlc_dec_int8_ext(const uint8_t *ibuf, size_t isz, uint8_t *obuf, size_t *bs_size)
|
||||
{
|
||||
StreamBuffer bs_header, bs_kmap, bs_data;
|
||||
CommandInfo cmd_info;
|
||||
memset(&cmd_info, 0, sizeof(CommandInfo));
|
||||
|
||||
size_t blk_num = (isz + 15) >> 4;
|
||||
int header_size = 16;
|
||||
int kmap_size = divide_ceil(blk_num, 16) << 4;
|
||||
*bs_size = 0;
|
||||
|
||||
// parse header
|
||||
init_stream(&bs_header, ibuf, header_size, true);
|
||||
vlc_dec_header_ext(&bs_header, &cmd_info, bs_size);
|
||||
|
||||
// Check whether valid header
|
||||
size_t bs_buf_size = get_out_bs_buf_size(isz, 0); // int8
|
||||
|
||||
//ASSERT(*bs_size <= bs_buf_size);
|
||||
//ASSERT(cmd_info.is_bfloat16 == 0);
|
||||
if (*bs_size > bs_buf_size || cmd_info.is_bfloat16)
|
||||
return;
|
||||
|
||||
// block decode
|
||||
init_stream(&bs_kmap, ibuf + header_size, kmap_size, true);
|
||||
init_stream(&bs_data, ibuf + header_size + kmap_size, blk_num << 4, true);
|
||||
|
||||
for (size_t blk_idx = 0; blk_idx < blk_num; blk_idx++)
|
||||
{
|
||||
uint8_t blk_data[16] = {0}, blk_sr_data[16] = {0};
|
||||
uint8_t k_info = 0;
|
||||
parse_stream(&bs_kmap, &k_info, 8);
|
||||
uint8_t ulen = k_info & 0x1F;
|
||||
int k = (k_info >> 5 == 7) ? -1 : k_info >> 5;
|
||||
int blk_bs_size = (k == -1) ? 128 : (k << 4) + ulen + 16;
|
||||
vlc_gr_dec_block_data(&bs_data, blk_bs_size, blk_data, k, false);
|
||||
|
||||
inv_symbol_remapping(blk_data, blk_sr_data, cmd_info.bias0, cmd_info.bias1, cmd_info.signedness, false, false);
|
||||
|
||||
int out_size = (blk_idx == (blk_num - 1)) ? isz - (blk_idx << 4) : 16;
|
||||
memcpy(&obuf[blk_idx << 4], blk_sr_data, sizeof(uint8_t) * out_size);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void cvk_vlc_dec_int8(const uint8_t *ibuf, size_t isz, uint8_t *obuf)
|
||||
{
|
||||
size_t bs_size;
|
||||
cvk_vlc_dec_int8_ext(ibuf, isz, obuf, &bs_size);
|
||||
}
|
||||
|
||||
// -- vlc encode bfloat16 entry function --
|
||||
static inline void cvk_vlc_enc_bf16(const uint16_t *ibuf, size_t isz, uint8_t *obuf, size_t *osz, CommandInfo *cmd_info)
|
||||
{
|
||||
StreamBuffer bs_header, bs_kmap, bs_data;
|
||||
size_t blk_num = (isz + 31) >> 5; // 32 bytes per blok
|
||||
size_t header_size = 16;
|
||||
size_t kmap_size = divide_ceil(blk_num, 16) << 4;
|
||||
size_t bs_buf_size = header_size + kmap_size + (blk_num << 5);
|
||||
uint8_t *bsbuf = (uint8_t *)calloc(bs_buf_size, sizeof(uint8_t));
|
||||
|
||||
// block encode
|
||||
init_stream(&bs_kmap, bsbuf + header_size, kmap_size, false);
|
||||
init_stream(&bs_data, bsbuf + header_size + kmap_size, blk_num << 5, false);
|
||||
|
||||
for (size_t blk_idx = 0; blk_idx < blk_num; blk_idx++)
|
||||
{
|
||||
uint8_t blk_data[16] = {0}, blk_sr_data[16] = {0}, blk_data_frac[16] = {0};
|
||||
size_t in_num = (blk_idx == (blk_num - 1)) ? ((isz >> 1) - (blk_idx << 4)) : 16;
|
||||
dispatch_bf16_data(&ibuf[blk_idx << 4], blk_data, blk_data_frac, in_num);
|
||||
|
||||
// exp: BGR encode
|
||||
symbol_remapping(blk_data, blk_sr_data, cmd_info->bias0, cmd_info->bias1, false, true, cmd_info->zero_guard_en);
|
||||
|
||||
int k = vlc_estimate_block_order(blk_sr_data, cmd_info->zero_guard_en);
|
||||
uint8_t ulen = vlc_gr_enc_block_data(blk_sr_data, &bs_data, k, cmd_info->zero_guard_en);
|
||||
uint8_t k_info = (k == -1) ? 0xE0 : (k << 5) + ulen;
|
||||
write_stream(&bs_kmap, &k_info, 8);
|
||||
|
||||
// frac: implicit zero compression
|
||||
for (size_t i = 0; i < 16; i++)
|
||||
{
|
||||
if (!cmd_info->zero_guard_en || blk_data[i] != 0)
|
||||
{
|
||||
write_stream(&bs_data, &blk_data_frac[i], 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int blk_bs_size = divide_ceil(((bs_data.bit_pos + 7) >> 3), 16) << 4; // 16 byte align
|
||||
*osz = header_size + kmap_size + blk_bs_size;
|
||||
|
||||
// write header
|
||||
init_stream(&bs_header, bsbuf, header_size, false);
|
||||
vlc_enc_header(&bs_header, cmd_info, blk_bs_size);
|
||||
|
||||
memcpy(obuf, bsbuf, (*osz) * sizeof(uint8_t));
|
||||
free(bsbuf);
|
||||
}
|
||||
|
||||
// -- vlc decode bfloat16 entry function --
|
||||
static inline void cvk_vlc_dec_bf16_ext(const uint8_t *ibuf, size_t isz, uint16_t *obuf, size_t *bs_size)
|
||||
{
|
||||
StreamBuffer bs_header, bs_kmap, bs_data;
|
||||
CommandInfo cmd_info;
|
||||
memset(&cmd_info, 0, sizeof(CommandInfo));
|
||||
|
||||
size_t blk_num = (isz + 31) >> 5; // 32 bytes per blok
|
||||
int header_size = 16;
|
||||
int kmap_size = divide_ceil(blk_num, 16) << 4;
|
||||
*bs_size = 0;
|
||||
|
||||
// parse header
|
||||
init_stream(&bs_header, ibuf, header_size, true);
|
||||
vlc_dec_header_ext(&bs_header, &cmd_info, bs_size);
|
||||
|
||||
// Check whether valid header
|
||||
size_t bs_buf_size = get_out_bs_buf_size(isz, 1); // bf16
|
||||
|
||||
//ASSERT(*bs_size <= bs_buf_size);
|
||||
//ASSERT(cmd_info.is_bfloat16 == 1);
|
||||
if (*bs_size > bs_buf_size || cmd_info.is_bfloat16 != 1)
|
||||
return;
|
||||
|
||||
// block decode
|
||||
init_stream(&bs_kmap, ibuf + header_size, kmap_size, true);
|
||||
init_stream(&bs_data, ibuf + header_size + kmap_size, blk_num << 5, true);
|
||||
|
||||
for (size_t blk_idx = 0; blk_idx < blk_num; blk_idx++)
|
||||
{
|
||||
uint8_t blk_data[16] = {0}, blk_sr_data[16] = {0}, blk_data_frac[16] = {0};
|
||||
uint8_t k_info = 0;
|
||||
parse_stream(&bs_kmap, &k_info, 8);
|
||||
uint8_t ulen = k_info & 0x1F;
|
||||
int k = (k_info >> 5 == 7) ? -1 : k_info >> 5;
|
||||
int znum_bit = (cmd_info.zero_guard_en && k > 0) ? 4 : 0;
|
||||
uint8_t blk_bs_size = (k == -1) ? 128 : (k << 4) + ulen + 16 + znum_bit;
|
||||
|
||||
// exp: BGR decode
|
||||
vlc_gr_dec_block_data(&bs_data, blk_bs_size, blk_data, k, cmd_info.zero_guard_en);
|
||||
|
||||
inv_symbol_remapping(blk_data, blk_sr_data, cmd_info.bias0, cmd_info.bias1, false, true, cmd_info.zero_guard_en);
|
||||
|
||||
size_t out_num = (blk_idx == (blk_num - 1)) ? ((isz >> 1) - (blk_idx << 4)) : 16;
|
||||
|
||||
// frac: implicit zero compression
|
||||
for (size_t i = 0; i < out_num; i++)
|
||||
{
|
||||
if (!cmd_info.zero_guard_en || blk_sr_data[i] != 0)
|
||||
{
|
||||
parse_stream(&bs_data, &blk_data_frac[i], 8);
|
||||
}
|
||||
}
|
||||
merge_bf16_data(blk_sr_data, blk_data_frac, &obuf[blk_idx << 4], out_num);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void cvk_vlc_dec_bf16(const uint8_t *ibuf, size_t isz, uint16_t *obuf)
|
||||
{
|
||||
size_t bs_size;
|
||||
cvk_vlc_dec_bf16_ext(ibuf, isz, obuf, &bs_size);
|
||||
}
|
||||
|
||||
// -- offline estimate model weight params --
|
||||
static inline void cvk_vlc_est_weight_bias(const uint8_t *ibuf, size_t isz, uint8_t signedness, uint8_t isBfloat16, CommandInfo *cmd_info)
|
||||
{
|
||||
//assert(!(isBfloat16 && signedness)); // WARNING: signedness MUST be 0 as isBfloat16==True
|
||||
|
||||
cmd_info->is_bfloat16 = isBfloat16;
|
||||
if (isBfloat16 == false && signedness == true)
|
||||
{
|
||||
// two-side circular shift
|
||||
int hist[256] = {0};
|
||||
for (size_t i = 0; i < isz; i++)
|
||||
{
|
||||
hist[ibuf[i]]++;
|
||||
}
|
||||
|
||||
int8_t pos_v = 1;
|
||||
//while (pos_v < 128)
|
||||
// comparison is always true due to limited range of data type [-Werror=type-limits]
|
||||
while (true)
|
||||
{
|
||||
if (hist[((uint8_t)pos_v)] == 0)
|
||||
{
|
||||
pos_v++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
//cmd_info->bias0 = (pos_v > 1 && pos_v < 128) ? (pos_v - 1) : 0;
|
||||
// comparison is always true due to limited range of data type [-Werror=type-limits]
|
||||
cmd_info->bias0 = (pos_v > 1) ? (pos_v - 1) : 0;
|
||||
int8_t neg_v = -1;
|
||||
//while (neg_v >= (-128)) // comparison is always true due to limited range of data type [-Werror=type-limits]
|
||||
while (true)
|
||||
{
|
||||
if (hist[(uint8_t)neg_v] == 0)
|
||||
{
|
||||
neg_v--;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
//cmd_info->bias1 = (neg_v < -1 && neg_v >= -128) ? abs(neg_v + 1) : 0;
|
||||
// comparison is always true due to limited range of data type [-Werror=type-limits]
|
||||
cmd_info->bias1 = (neg_v < -1) ? abs(neg_v + 1) : 0;
|
||||
cmd_info->signedness = true;
|
||||
}
|
||||
|
||||
if (isBfloat16 == true)
|
||||
{
|
||||
// center shift
|
||||
int64_t exp_accum = 0;
|
||||
uint16_t *bf16_in = (uint16_t *)ibuf;
|
||||
size_t inum = (isz >> 1), cnt = 0;
|
||||
for (size_t i = 0; i < inum; i++)
|
||||
{
|
||||
uint8_t exp = ((bf16_in[i] >> 7) & 0xFF);
|
||||
if (exp != 0)
|
||||
{
|
||||
exp_accum += exp;
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
if (cnt > 0)
|
||||
{
|
||||
cmd_info->bias0 = (uint8_t)((exp_accum / (float)cnt) + 0.5);
|
||||
}
|
||||
cmd_info->zero_guard_en = (inum == cnt) ? false : true;
|
||||
cmd_info->signedness = false;
|
||||
}
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CVK_VLC_COMPRESS_H__ */
|
||||
Reference in New Issue
Block a user