Bitwise operations on different sized data types - scala

I am trying to concatenate two Bytes, defined as p1 and p2 to form an Int pnum, and this is the implementation I came up with
pnum = p1 << 8
pnum |= p2
But a test case fails, when one of the numbers is negative (i.e has the MSB set), it is converted to an Int and the MSB is moved to the 32nd bit instead of the 8th, producing an incorrect value
What is the correct way to concatenate these two bytes, or preserving the MSB of the byte during the conversion?

You could mask it before adding the p2 bits (also masked).
val pnum = p1 << 8 & 0xFF00 | p2 & 0xFF

Related

How to access multidimensional array in systemverilog? [duplicate]

What are the +: and -: Verilog/SystemVerilog operators? When and how do you use them? For example:
logic [15:0] down_vect;
logic [0:15] up_vect;
down_vect[lsb_base_expr +: width_expr]
up_vect [msb_base_expr +: width_expr]
down_vect[msb_base_expr -: width_expr]
up_vect [lsb_base_expr -: width_expr]
That particular syntax is called an indexed part select. It's very useful when you need to select a fixed number of bits from a variable offset within a multi-bit register.
Here's an example of the syntax:
reg [31:0] dword;
reg [7:0] byte0;
reg [7:0] byte1;
reg [7:0] byte2;
reg [7:0] byte3;
assign byte0 = dword[0 +: 8]; // Same as dword[7:0]
assign byte1 = dword[8 +: 8]; // Same as dword[15:8]
assign byte2 = dword[16 +: 8]; // Same as dword[23:16]
assign byte3 = dword[24 +: 8]; // Same as dword[31:24]
The biggest advantage with this syntax is that you can use a variable for the index. Normal part selects in Verilog require constants. So attempting the above with something like dword[i+7:i] is not allowed.
So if you want to select a particular byte using a variable select, you can use the indexed part select.
Example using variable:
reg [31:0] dword;
reg [7:0] byte;
reg [1:0] i;
// This is illegal due to the variable i, even though the width is always 8 bits
assign byte = dword[(i*8)+7 : i*8]; // ** Not allowed!
// Use the indexed part select
assign byte = dword[i*8 +: 8];
The purpose of this operator is when you need to access a slice of a bus, both MSB position and LSB positions are variables, but the width of the slice is a constant value, as in the example below:
bit[7:0] bus_in = 8'hAA;
int lsb = 3;
int msb = lsb+3; // Setting msb=6, for out bus of 4 bits
bit[3:0] bus_out_bad = bus_in[msb:lsb]; // ILLEGAL - both boundaries are variables
bit[3:0] bus_out_ok = bus_in[lsb+:3]; // Good - only one variable
5.2.1 Vector bit-select and part-select addressing
Bit-selects extract a particular bit from a vector net, vector reg, integer, or time variable, or parameter. The bit can be addressed using an expression. If the bit-select is out of the address bounds or the bit-select is x or z , then the value returned by the reference shall be x . A bit-select or part-select of a scalar, or of a variable orparameter of type real or realtime, shall be illegal.
Several contiguous bits in a vector net, vector reg, integer, or time variable, or parameter can be addressed and are known as part-selects. There are two types of part-selects, a constant part-select and an indexed part-select. A constant part-select of a vector reg or net is given with the following syntax:
vect[msb_expr:lsb_expr]
Both msb_expr and lsb_expr shall be constant integer expressions. The first expression has to address a more significant bit than the second expression.
An indexed part-select of a vector net, vector reg, integer, or time variable, or parameter is given with the following syntax:
reg [15:0] big_vect;
reg [0:15] little_vect;
big_vect[lsb_base_expr +: width_expr]
little_vect[msb_base_expr +: width_expr]
big_vect[msb_base_expr -: width_expr]
little_vect[lsb_base_expr -: width_expr]
The msb_base_expr and lsb_base_expr shall be integer expressions, and the width_expr shall be a positive constant integer expression. The lsb_base_expr and msb_base_expr can vary at run time. The first two examples select bits starting at the base and ascending the bit range. The number of bits selected is equal to the width expression. The second two examples select bits starting at the base and descending the bit range.
A part-select of any type that addresses a range of bits that are completely out of the address bounds of the net, reg, integer, time variable, or parameter or a part-select that is x or z shall yield the value x when read and shall have no effect on the data stored when written. Part-selects that are partially out of range shall, when read, return x for the bits that are out of range and shall, when written, only affect the bits that are in range.
For example:
reg [31: 0] big_vect;
reg [0 :31] little_vect;
reg [63: 0] dword;
integer sel;
big_vect[ 0 +: 8] // == big_vect[ 7 : 0]
big_vect[15 -: 8] // == big_vect[15 : 8]
little_vect[ 0 +: 8] // == little_vect[0 : 7]
little_vect[15 -: 8] // == little_vect[8 :15]
dword[8sel +: 8] // variable part-select with fixed width*
Example 1—The following example specifies the single bit of acc vector that is addressed by the operand
index :
acc[index]
The actual bit that is accessed by an address is, in part, determined by the declaration of acc . For instance, each of the declarations of acc shown in the next example causes a particular value of index to access a different bit:
reg [15:0] acc;
reg [2:17] acc
Example 2—The next example and the bullet items that follow it illustrate the principles of bit addressing. The code declares an 8-bit reg called vect and initializes it to a value of 4. The list describes how the separate bits of that vector can be addressed.
reg [7:0] vect;
vect = 4; // fills vect with the pattern 00000100
// msb is bit 7, lsb is bit 0
— If the value of addr is 2, then vect[addr] returns 1.
— If the value of addr is out of bounds, then vect[addr] returns x.
— If addr is 0, 1, or 3 through 7, vect[addr] returns 0.
— vect[3:0] returns the bits 0100.
— vect[5:1] returns the bits 00010.
— vect[ expression that returns x ] returns x.
— vect[ expression that returns z ] returns x.
— If any bit of addr is x or z , then the value of addr is x.
NOTE 1—Part-select indices that evaluate to x or z may be flagged as a compile time error.
NOTE 2—Bit-select or part-select indices that are outside of the declared range may be flagged as a compile time error.

Boolean size in Ada

In my ada's project I have 2 different libraries with base types. I found two different definition for a boolean :
Library A :
type Bool_Type is new Boolean;
Library B :
type T_BOOL8 is new Boolean;
for T_BOOL8'Size use 8;
So I have a question, what is the size used for Bool_Type ?
Bool_Type will inherit the 'Size of Boolean, which is required to be 1,
see RM 13.3(49)
Compile with switch -gnatR2 to see its representation clause. For example:
main.adb
with Ada.Text_IO; use Ada.Text_IO;
procedure Main is
type Bool_Type is new Boolean;
type T_BOOL8 is new Boolean;
for T_BOOL8'Size use 8;
begin
Put_Line ("Bool_Type'Object_Size = " & Integer'Image (Bool_Type'Object_Size));
Put_Line ("Bool_Type'Value_Size = " & Integer'Image (Bool_Type'Value_Size));
Put_Line ("Bool_Type'Size = " & Integer'Image (Bool_Type'Size));
New_Line;
Put_Line ("T_BOOL8'Object_Size = " & Integer'Image (T_BOOL8'Object_Size));
Put_Line ("T_BOOL8'Value_Size = " & Integer'Image (T_BOOL8'Value_Size));
Put_Line ("T_BOOL8'Size = " & Integer'Image (T_BOOL8'Size));
New_Line;
end Main;
compiler output (partial):
Representation information for unit Main (body)
-----------------------------------------------
for Bool_Type'Object_Size use 8;
for Bool_Type'Value_Size use 1;
for Bool_Type'Alignment use 1;
for T_Bool8'Size use 8;
for T_Bool8'Alignment use 1;
program output
Bool_Type'Object_Size = 8
Bool_Type'Value_Size = 1
Bool_Type'Size = 1
T_BOOL8'Object_Size = 8
T_BOOL8'Value_Size = 8
T_BOOL8'Size = 8
As can be seen, the number returned by the 'Size / 'Value_Size attribute for Bool_Type is equal to 1 (as required by the RM; see egilhh's answer). The attribute 'Size / 'Value_Size states the number of bits used to represent a value of the type. The 'Object_Size attribute, on the other hand, equals 8 bits (1 byte) and states the amount of bits used to store a value of the given type in memory (see Simon Wright's comment). See here and here for details.
Note that the number of bits indicated by 'Size / 'Value_Size must be sufficient to uniquely represent all possible values within the (discrete) type. For Boolean derived types, at least 1 bit is required, for an enumeration type with 3 values, for example, you need at least 2 bits.
An effect of explicitly setting the 'Size / 'Value_Size attribute can be observed when defining a packed array (as mentioned in G_Zeus’ answer):
type Bool_Array_Type is
array (Natural range 0 .. 7) of Bool_Type with Pack;
type T_BOOL8_ARRAY is
array (Natural range 0 .. 7) of T_BOOL8 with Pack;
compiler output (partial):
Representation information for unit Main (body)
-------------------------------------------------
[...]
for Bool_Array_Type'Size use 8;
for Bool_Array_Type'Alignment use 1;
for Bool_Array_Type'Component_Size use 1;
[...]
for T_Bool8_Array'Size use 64;
for T_Bool8_Array'Alignment use 1;
for T_Bool8_Array'Component_Size use 8;
Because the number of bits used to represent a value of type T_BOOL8 is forced to be 8, the size of a single component of a packed array of T_BOOL8s will also be 8, and the total size of T_BOOL8_ARRAY will be 64 bits (8 bytes). Compare this to the total length of 8 bits (1 byte) for Bool_Array_Type.
You should find your answer (or enough information to find the answer to your specific question) in the Ada wikibooks entry for 'Size attribute.
Most likely Bool_Type has a the same size as Boolean, or 1 bit for the type (meaning you can pack Bool_Type elements in an array, for example) and 8 bits for instances (rounded up to full byte).
Whatever size the compiler wants, unless you override as in library B. Probably 8 bits but on some 32 bit RISC targets, 32 bits may be faster than 8. On a tiny microcontroller, 1 bit may save space.
The other answers let you find out for the specific target you compile for.
As your booleans are separate types, you need type conversions between them, providing hooks for the compiler to handle any format or size conversion without any further ado.

Why does the Streaming-Operator in SystemVerilog reverse the byte order?

I simulated the following example:
shortint j;
byte unsigned data_bytes[];
j = 16'b1111_0000_1001_0000;
data_bytes = { >>{j}};
`uvm_info(get_type_name(), $sformatf("j data_bytes: %b_%b", data_bytes[1], data_bytes[0]), UVM_LOW)
Result:
UVM_INFO Initiator.sv(84) # 0: uvm_test_top.sv_initiator [Initiator] j data_bytes: 10010000_11110000
However, this seems strange to me, since the byte-order is reversed, as I expect the LSB to be at index 0 of data_byte[0] and the MSB at index 7 of data_byte[1]. Why does this happen? According to documentation (Cadence Help) this should not be the case.
As defined in section 6.24.3 Bit-stream casting of the IEEE 1800-2017 LRM, the [0] element of an unpacked dynamic array is considered the left index, and streaming >> goes from left to right indexes. To get the results you want, write
data_bytes = { << byte {j}};
This reverses the stream, but keeps the individual bytes in right to left order.

convert 4 bytes to float matlab

I read from the serial port 4 bytes and I want to create a Matlab
function to convert them into a float number
for example: if I read A=[65 240 0 0] I must have 30 according to
IEEE754 standard.
- I have used Simulink block "byte unpack" but i have problems. in fact
I should read over 18 parameters. each parameters is 4 bytes
array.then I should use 18 byte unpack.
By default, Matlab will use double precision to store any new value which doesn't have a type specified. If you know you are reading byte, then the best is to collect them directly as uint8 (the unsigned byte type of Matlab) if you can (in your call to fread or equivalent).
If you cannot collect them directly as uint8 then cast them as such then use the typecast function.
A = [65 240 0 0] ; %// Collected bytes
A = uint8(A) ; %// cast them to "uint8" if they are not already
Afloat = typecast( A , 'single') ; %// cast the 4 bytes as a 32 bit float
wait a minute:
Afloat =
8.6186862e-41
oops, it seems the byte ordering used by your collection mechanism is the opposite as the one used by Matlab. No problem, you can just change the endianness by "flipping" the byte array.
So instead, use:
>> Afloat = typecast( fliplr(A) , 'single')
Afloat =
30
success :)
You can also look at the function swapbytes to manage the endianess.
To avoid reinventing the wheel, simply use
A = fread(obj,size,'precision')
as described in documentation
For example,
[A,count] = fread(obj, 18, 'float32');
should read 18 4 byte floats.

Understanding a code snippet in verilog

I found the following code snippet in verilog code for AES.
function [7:0] xtime;
input [7:0] b; xtime={b[6:0],1'b0}^(8'h1b&{8{b[7]}});
endfunction
Please explain what does this do. The more elaborate explanation, the better.
b is a 8 bit input.
b[6:0],1'b0 last 7 bits left shifted, and padded with 0
^ xor
8'h1b 8 bits hex 1b anded with the sign bit.
Explained in one line: If msb is set xor with 0x1b otherwise just *2
A quick search of xtime and AES leads me to this c implementation’s comment:
// xtime is a macro that finds the product of {02} and the argument to
// xtime modulo {1b}
#define xtime(x) ((x<<1) ^ (((x>>7) & 1) * 0x11b))
looks like it maybe is doing about the same.
Lets clean up the code and breakdown some of the assignments:
function [7:0] xtime;
input [7:0] b;
reg [7:0] temp1;
reg [7:0] temp2;
begin
temp1 = {b[6:0],1'b0};
temp2 = ( 8'h1b & {8{b[7]}} );
xtime = temp1 ^ temp2;
end
endfunction
Function called xtime outputs the variable xtime 8 bits wide. Has 8 bit wide input called b.
temp1 left shifts input b, padding LSB (Least Significant Bit) with 0 and throwing away MSB (Most Significant Bit).
temp2 bitwise ANDs 8'h1B (8'b0001_1011) with the MSB of input b.
b[7] selects bit 7 of b.
{8{value}} is the replication operator.
{8{1'b1}} => 8'b1111_1111
{4{2'b10}} => 8'b1010_1010
xtime performs the bitwise XOR of temp1 and temp2.