HLS第二十课(位操作)

User-defined types may be created with the C/C++ ‘typedef’ statement as shown in the
following examples:

include "ap_cint.h" // use [u]int#W types
typedef uint128 uint128_t; // 128-bit user defined type
int96 my_wide_var; // a global variable declaration


uint15 a = 0;
uint52 b = 1234567890U;
uint52 c = 0o12345670UL;
uint96 d = 0x123456789ABCDEFULL;

int128 a;
// Set a to the value hex 00000000000000000123456789ABCDF0
a = apint_string2bits_hex(“-123456789ABCDEF”,128);



For bit-widths greater than 64-bit, the following functions can be used.
apint_string2bits_bin()
apint_string2bits_oct()
apint_string2bits_hex()

or
apint_vstring2bits_XXX()

apint_print() or apint_fprint()
This is used to print integers with values that are larger than those already permitted by the C
language.

#include <stdio.h>
#include "ap_cint.h"

int65 Var1 = 44;


//00000000000000000000000000000000000000000000000000000000000101100
apint_print(Var1,2);

// 0000000000000000000054
apint_print(Var1,8); 

apint_print(Var1,10); // 44

// 0000000000000002C
apint_print(Var1,16); 

for C++

include "ap_int.h"// use ap_[u]fixed<> types

typedef ap_uint<128> uint128_t; // 128-bit user defined type
ap_int<96> my_wide_var; // a global variable declaration

ap_int<42> a_42b_var(-1424692392255LL); // long long decimal format
a_42b_var = 0x14BB648B13FLL; // hexadecimal format
a_42b_var = -1; // negative int literal sign-extended to full width
ap_uint<96> wide_var(“76543210fedcba9876543210”, 16); // Greater than 64-bit
wide_var = ap_int<96>(“0123456789abcdef01234567”, 16);

ap_int<6> a_6bit_var(“101010”, 2); // 42d in binary format
a_6bit_var = ap_int<6>(“40”, 8); // 32d in octal format
a_6bit_var = ap_int<6>(“55”, 10); // decimal format
a_6bit_var = ap_int<6>(“2A”, 16); // 42d in hexadecimal format
a_6bit_var = ap_int<6>(“42”, 2); // COMPILE-TIME ERROR! “42” is not binary

ap_int<6> a_6bit_var(“0b101010”, 2); // 42d in binary format
a_6bit_var = ap_int<6>(“0o40”, 8); // 32d in octal format
a_6bit_var = ap_int<6>(“0x2A”, 16); // 42d in hexidecimal format
a_6bit_var = ap_int<6>(“0b42”, 2); // COMPILE-TIME ERROR! “42” is not binary

ap_ufixed<72,10> Val(“2460508560057040035.375”);

when it is prefixed with a zero (0) followed by one of the following characters: “b”, “o” or “x”. The prefixes “0b”, “0o” and “0x” correspond to binary, octal and hexadecimal formats respectively.

If the bit-width is greater than 53-bits, the ap_[u]fixed value must be initialized with a string

The easiest way to output any value stored in an ap_[u]int variable is to use the C++ standard
output stream:

#include <iostream> or <iostream.h>
// Alternative: #include <iostream>

ap_ufixed<72> Val(“10fedcba9876543210”);
cout << Val << endl; // Yields: “313512663723845890576”
cout << hex << val << endl; // Yields: “10fedcba9876543210”
cout << oct << val << endl; // Yields: “41773345651416625031020”

You can also use the standard C library (#include <stdio.h>) to print out values larger than
64-bits:
Convert the value to a C++ std::string using the ap_[u]fixed classes method
to_string().
Convert the result to a null-terminated C character string using the std::string class
method c_str().

#include <stdio.h>
ap_int<72> Val(“80fedcba9876543210”);
printf(“%s\n”, Val.to_string().c_str()); // => “80FEDCBA9876543210”
printf(“%s\n”, Val.to_string(10).c_str()); // => “-2342818482890329542128”
printf(“%s\n”, Val.to_string(8).c_str()); // => “401773345651416625031020”
printf(“%s\n”, Val.to_string(16, true).c_str()); // => “-7F0123456789ABCDF0”

The ap_[u]int types do not support implicit conversion from wide ap_[u]int (>64bits) to
builtin C/C++ integer types.
To convert wide ap_[u]int types to built-in integers, use the explicit conversion functions
included with the ap_[u]int types:
• to_int()
• to_long()
• to_bool()

++++++++++++++++++++++++++++++++++++++++++++++
Binary Arithmetic Operators

Standard binary integer arithmetic operators are overloaded to provide arbitrary precision
arithmetic.

When expressions contain a mix of ap_[u]int and C/C++ fundamental integer types, the C++
types assume the following widths:
• char: 8-bits
• short: 16-bits
• int: 32-bits
• long: 32-bits
• long long: 64-bits

for C or C++:
When you use the ternary operator with the standard C int type, you must explicitly cast from
one type to the other to ensure that both results have the same type. For example:

// Integer type is cast to ap_int type
ap_int<32> testc3(int a, ap_int<32> b, ap_int<32> c, bool d) {
return d?ap_int<32>(a):b;
}
// ap_int type is cast to an integer type
ap_int<32> testc4(int a, ap_int<32> b, ap_int<32> c, bool d) {
return d?a+1:(int)b;
}
// Integer type is cast to ap_int type
ap_int<32> testc5(int a, ap_int<32> b, ap_int<32> c, bool d) {
return d?ap_int<33>(a):b+1;
}

+++++++++++++++++++++++++++++++++++++++++++++
Bitwise Logical Operators
Bitwise OR
Bitwise AND
Bitwise XOR
Shift

++++++++++++++++++++++++++++++++++++++++++++++
Bit-Level Operation: Support Function for C

The [u]int#W types allow variables to be expressed with bit-level accuracy. It is often desirable
with hardware algorithms to perform bit-level operations.

----apint_bitwidthof()
Returns an integer value that provides the number of bits in an arbitrary precision integer value.
It can be used with a type or a value.

int5 Var1, Res1;
Var1= -1;

Res1 = apint_bitwidthof(Var1); // Res1 is assigned 5

Res1 = apint_bitwidthof(int7); // Res1 is assigned 7

----apint_concatenate()

int#(N+M) apint_concatenate(int#N high, int#M low)

Concatenates two [u]int#W variables. The width of the returned value is the sum of the widths
of the operands.
The High and Low arguments are placed in the higher and lower order bits of the result
respectively.

----apint_get_bit()
Selects one bit from an arbitrary precision integer value and returns it
The least significant bit has index 0. The highest permissible index is one less than the bit-width of this [u]int#W.

----apint_set_bit()
Sets the specified bit, index, of the [u]int#W instance source to the value specified (zero or
one).

----apint_get_range()

int#N apint_get_range(int#N source, int high, int low)

Returns the value represented by the range of bits specified by the arguments.
The High argument specifies the most significant bit (MSB) position of the range.
THE Low argument specifies the least significant bit (LSB) position of the range.
The LSB of the source variable is in position 0. If the High argument has a value less than
Low, the bits are returned in reverse order.

----apint_set_range()

int#N apint_set_range(int#N source, int high, int low, int#M part)

Sets the source specified bits between High and Low to the value of the part.

----apint_and_reduce()
Applies the AND operation on all bits in the value.

int5 Var1, Res1;
Var1= -1;
Res1 = apint_and_reduce(Var1); // Res1 is assigned 1
Var1= 1;
Res1 = apint_and_reduce(Var1); // Res1 is assigned 0

It returns a 1 if it matches. It returns a 0 if it does not match.

----apint_or_reduce()
Applies the OR operation on all bits in the value
Returns the resulting single bit as an integer value (which can be cast onto a bool).
Equivalent to comparing to 0, and return a 0 if it matches, 1 otherwise

int5 Var1, Res1;
Var1= 1;
Res1 = apint_or_reduce(Var1); // Res1 is assigned 1
Var1= 0;
Res1 = apint_or_reduce(Var1); // Res1 is assigned 0

----apint_xor_reduce()
Applies the XOR operation on all bits in the value.
Returns the resulting single bit as an integer value (which can be cast onto a bool).
Equivalent to counting the ones in the word.
Returns 0 if there is an even number.
Returns 1 if there is an odd number (even parity)

int5 Var1, Res1;
Var1= 0;
Res1 = apint_xor_reduce(Var1); // Res1 is assigned 0
Var1= 1;
Res1 = apint_xor_reduce(Var1); // Res1 is assigned 1

----apint_nand_reduce()
Applies the NAND operation on all bits in the value.
Returns the resulting single bit as an integer value (which can be cast onto a bool)
Equivalent to comparing this value against -1 (all ones) and returning false if it matches, true
otherwise

int5 Var1, Res1;
Var1= 1;
Res1 = apint_nand_reduce(Var1); // Res1 is assigned 1
Var1= -1;
Res1 = apint_nand_reduce(Var1); // Res1 is assigned 0

----apint_nor_reduce()
Applies the NOR operation on all bits in the value.
Returns the resulting single bit as an integer value (which can be cast onto a bool).
Equivalent to comparing this value against 0 (all zeros) and returning true if it matches, false
otherwise.

int5 Var1, Res1;
Var1= 0;
Res1 = apint_nor_reduce(Var1); // Res1 is assigned 1
Var1= 1;
Res1 = apint_nor_reduce(Var1); // Res1 is assigned 0

----apint_xnor_reduce()
Applies the XNOR operation on all bits in the value.
Returns the resulting single bit as an integer value (which can be cast onto a bool).
Equivalent to counting the ones in the word.
Returns 0 if there is an odd number.
Returns 1 if there is an even number (odd parity).

int5 Var1, Res1;
Var1= 0;
Res1 = apint_xnor_reduce(Var1); // Res1 is assigned 1
Var1= 1;
Res1 = apint_xnor_reduce(Var1); // Res1 is assigned 0

+++++++++++++++++++++++++++++++++++++++++++++++++
Bit-Level Operation: Support Function for C++

----Length

int ap_(u)int::length ()

Returns an integer value providing the total number of bits in the ap_[u]int variable

----Concatenation

ap_concat_ref ap_(u)int::concat (ap_(u)int low)
ap_concat_ref ap_(u)int::operator , (ap_(u)int high, ap_(u)int low)

Concatenates two ap_[u]int variables, the width of the returned value is the sum of the
widths of the operands.
The High and Low arguments are placed in the higher and lower order bits of the result
respectively; the concat() method places the argument in the lower order bits.

ap_uint<10> Rslt;
ap_int<3> Val1 = -3;
ap_int<7> Val2 = 54;
Rslt = (Val2, Val1); // Yields: 0x1B5
Rslt = Val1.concat(Val2); // Yields: 0x2B6
(Val1, Val2) = 0xAB; // Yields: Val1 == 1, Val2 == 43

----Bit Selection

ap_bit_ref ap_(u)int::operator [] (int bit_index)

Selects one bit from an arbitrary precision integer value and returns it
The returned value is a reference value that can set or clear the corresponding bit in this
ap_[u]int.
The bit argument must be an int value. It specifies the index of the bit to select. The least
significant bit has index 0. The highest permissible index is one less than the bit-width of this
ap_[u]int.
The result type ap_bit_ref represents the reference to one bit of this ap_[u]int instance
specified by bit.

----Range Selection

ap_range_ref ap_(u)int::range (unsigned Hi, unsigned Lo)
ap_range_ref ap_(u)int::operator () (unsigned Hi, unsigned Lo)

Returns the value represented by the range of bits specified by the arguments.
The Hi argument specifies the most significant bit (MSB) position of the range, and Lo specifies
the least significant bit (LSB).
The LSB of the source variable is in position 0. If the Hi argument has a value less than Lo, the
bits are returned in reverse order.

ap_uint<4> Rslt;
ap_uint<8> Val1 = 0x5f;
ap_uint<8> Val2 = 0xaa;
Rslt = Val1.range(3, 0); // Yields: 0xF
Val1(3,0) = Val2(3, 0); // Yields: 0x5A
Val1(3,0) = Val2(4, 1); // Yields: 0x55
Rslt = Val1.range(4, 7); // Yields: 0xA; bit-reversed!

----AND reduce

bool ap_(u)int::and_reduce ()

Equivalent to comparing this value against -1 (all ones) and returning true if it matches,
false otherwise.

----OR reduce

bool ap_(u)int::or_reduce ()

Equivalent to comparing this value against 0 (all zeros) and returning false if it matches,
true otherwise.

----XOR reduce

bool ap_(u)int::xor_reduce ()

Equivalent to counting the number of 1 bits in this value and returning false if the count is
even or true if the count is odd.

----NAND reduce

bool ap_(u)int::nand_reduce ()

Equivalent to comparing this value against -1 (all ones) and returning false if it matches,
true otherwise.

----NOR reduce

bool ap_int::nor_reduce ()

Equivalent to comparing this value against 0 (all zeros) and returning true if it matches,
false otherwise.

----XNOR reduce

bool ap_(u)int::xnor_reduce ()

Equivalent to counting the number of 1 bits in this value and returning true if the count is
even or false if the count is odd.

ap_uint<8> Val = 0xaa;
bool t = Val.and_reduce(); // Yields: false
t = Val.or_reduce(); // Yields: true
t = Val.xor_reduce(); // Yields: false
t = Val.nand_reduce(); // Yields: true
t = Val.nor_reduce(); // Yields: false
t = Val.xnor_reduce(); // Yields: true

----Bit Reverse

void ap_(u)int::reverse ()

The LSB becomes the MSB.
The MSB becomes the LSB.

ap_uint<8> Val = 0x12;
Val.reverse(); // Yields: 0x48

----Test Bit Value

bool ap_(u)int::test (unsigned index)

Checks whether specified bit of ap_(u)int instance is 1
等效于用掩码做与操作。

ap_uint<8> Val = 0x12;
bool t = Val.test(5); // Yields: true

----Set Bit Value


void ap_(u)int::set (unsigned i, bool v)
void ap_(u)int::set_bit (unsigned i, bool v)

Sets the specified bit of the ap_(u)int instance to the value of integer V

----Set or Clear Bit

void ap_(u)int::set (unsigned i)
void ap_(u)int:: clear(unsigned i)

----Invert Bit

void ap_(u)int:: invert(unsigned i)

Inverts the bit specified in the function argument of the ap_(u)int instance. The specified bit
becomes 0 if its original value is 1 and vice versa.

ap_uint<8> Val = 0x12;
Val.set(0, 1); // Yields: 0x13
Val.set_bit(4, false); // Yields: 0x03
Val.set(7); // Yields: 0x83
Val.clear(1); // Yields: 0x81
Val.invert(4); // Yields: 0x91

----Rotate Shift Right or left

ap_uint<8> Val = 0x12;
Val.rrotate(3); // Yields: 0x42
Val.lrotate(6); // Yields: 0x90

----Bitwise NOT

ap_uint<8> Val = 0x12;
Val.b_not(); // Yields: 0xED

----Explicit Conversion

int ap_(u)int::to_int ()
unsigned ap_(u)int::to_uint ()
long long ap_(u)int::to_int64 ()
unsigned long long ap_(u)int::to_uint64 ()
double ap_(u)int::to_double ()

----SIZEOF

sizeof(ap_int<127>)=16
sizeof(ap_int<128>)=16
sizeof(ap_int<129>)=24
sizeof(ap_int<130>)=24

sizeof(ap_int<N>) always returns the number of bytes used.

猜你喜欢

转载自blog.csdn.net/weixin_42418557/article/details/120891937