How to remove the repeated consecutive elements in dynamic array in systemverilog? - arrays

module tb;
bit [7:0] bytes [];
bit [7:0] q[$];
initial begin
bytes = new[20];
bytes[0] = 8'hee;
bytes[1] = 8'hea;
bytes[2] = 8'haf;
bytes[3] = 8'haf;
bytes[4] = 8'haf;
bytes[5] = 8'h50;
bytes[6] = 8'h6a;
bytes[7] = 8'h0d;
bytes[8] = 8'hc8;
bytes[9] = 8'hc8;
bytes[10] = 8'h21;
foreach(bytes[i])
$write("%h ", bytes[i]);
$display("\n");
q = bytes.unique();
foreach(q[i])
$write("%h ", q[i]);
end
endmodule
In the above code, I need to remove the consecutive duplicate elements (only the consecutive duplicate elements) of the dynamic array called bytes and put them in a queue called q. Also, I need to remove all the trailing 0's. I tried using unique(), but what I get is something different.
Expected output:
ee ea af af af 50 6a 0d c8 c8 21 00 00 00 00 00 00 00 00 00 00
ee ea af 50 6a 0d c8 21
Output I am getting on QuestaSim on edaplayground
ee ea af af af 50 6a 0d c8 c8 21 00 00 00 00 00 00 00 00 00 00
00 0d 21 50 6a af c8 ea ee
More information:
Once it's 0, it cannot have more duplicates. Since it's a dynamic array created by reading the data values on DUT interface, last value read is the 0 and that remains at 0 unless new data.
Since its duplication is only due to the current data being held on the output interface (following some arbitartion priority, waiting for few cycles for next priority port data). and the data is constraint randomized to have unique values (data which is input to DUT).
eg. I send a,b,c,d on the input on port 3 and port 3 waits for few cycles to check is any other port is requested, hence the output may be something like a bbb cc d ( 3 cycle for b and 2 cycle for c) and the dynamic array reads this output. Removing the duplicated items is so as to compare the input and output equivalence in Scoreboard.

You can loop through the original array and only add items to the new queue when consecutive items do not match. This also removes the trailing 00.
module tb;
bit [7:0] bytes [];
bit [7:0] q[$];
initial begin
bytes = new[20];
bytes[0] = 8'hee;
bytes[1] = 8'hea;
bytes[2] = 8'haf;
bytes[3] = 8'haf;
bytes[4] = 8'haf;
bytes[5] = 8'h50;
bytes[6] = 8'h6a;
bytes[7] = 8'h0d;
bytes[8] = 8'hc8;
bytes[9] = 8'hc8;
bytes[10] = 8'h21;
$display;
foreach (bytes[i]) $write("%h ", bytes[i]);
$display;
q[0] = bytes[0];
for (int i=1; i<bytes.size(); i++) begin
if (bytes[i] != bytes[i-1]) q.push_back(bytes[i]);
end
if (q[$] == 0) void'(q.pop_back());
foreach (q[i]) $write("%h ", q[i]);
$display;
$display;
end
endmodule
This outputs:
ee ea af af af 50 6a 0d c8 c8 21 00 00 00 00 00 00 00 00 00
ee ea af 50 6a 0d c8 21
Here is a demonstration on edaplayground.
Regarding the unique array method, the IEEE Std 1800-2017, section 7.12.1 Array locator methods, states:
The ordering of the returned elements is unrelated to the ordering of
the original array.
Perhaps that means that the resulting order can't be guaranteed. With your code, we get mixed results on different simulators on edaplayground (original code in Question); some produce your desired output order, while others do not.

It seems like the order of the elements in the queue which is returned by the unique method is not defined. So, how about changing your queue to be a queue of ints:
int q[$];
and then using unique_index:
q = bytes.unique_index();
and then using the sort method on that:
q.sort();
Then the order is defined, whatever simulator you use. (And it is better to write code that works on any simulator). So, we now have a queue of indexes, which we can use to index the original array (byte):
foreach(q[i])
$write("%h ", bytes[q[i]]);
This gives me this output (on Aldec Riviera Pro):
ee ea af af af 50 6a 0d c8 c8 21 00 00 00 00 00 00 00 00 00
ee ea af 50 6a 0d c8 21 00
https://www.edaplayground.com/x/6pV6
module tb;
bit [7:0] bytes [];
int q[$];
initial begin
bytes = new[20];
bytes[0] = 8'hee;
bytes[1] = 8'hea;
bytes[2] = 8'haf;
bytes[3] = 8'haf;
bytes[4] = 8'haf;
bytes[5] = 8'h50;
bytes[6] = 8'h6a;
bytes[7] = 8'h0d;
bytes[8] = 8'hc8;
bytes[9] = 8'hc8;
bytes[10] = 8'h21;
foreach(bytes[i])
$write("%h ", bytes[i]);
$display("\n");
q = bytes.unique_index();
q.sort();
foreach(q[i])
$write("%h ", bytes[q[i]]);
end
endmodule

module duplicateremoval;
int array[] = {1, 2, 3, 4, 5, 2, 3, 4, 6, 8, 3};
int i, j, k;
initial begin
for(i=0 ; i<array.size()-1 ; i=i+1)
begin
for(j=i+1 ; j<array.size() ; j=j+1) //j should be one step advanced to i
begin
if(array[i] == array[j])
begin
for(k=j ; k<array.size() ; k=k+1)
begin
array[k] = array[k+1];
end
j--;
end
end
$display("array[%0d]=%0d", i, array[i]);
end
end
endmodule
In this code, using for loops comparing the next value with the current value. if current value is same as next value , the current value will be skipped and next value will be assigned to current value .after replace, reduce the iterator by 1,so that it will be in current position.

Related

Why can't I use increment operators with useState? [duplicate]

I was browsing Google Code when I chanced upon this project called JSpeed - optimization for Javascript.
I noticed one of the optimization was to change i++ to ++i in for loop statements.
Before Optimization
for (i=0;i<1;i++) {}
for (var i = 0, j = 0; i < 1000000; i++, j++) {
if (i == 4) {
var tmp = i / 2;
}
if ((i % 2) == 0) {
var tmp = i / 2;
i++;
}
}
var arr = new Array(1000000);
for (i = 0; i < arr.length; i++) {}
After optimization
for(var i=0;i<1;++i){}
for(var i=0,j=0;i<1000000;++i,++j){if(i==4){var tmp=i>>1;}
if((i&1)==0){var tmp=i>>1;i++;}}
var arr=new Array(1000000);for(var i=0,arr_len=arr.length;i<arr_len;++i){}
I know what pre and post increments do, but any idea how does this speeds the code up?
This is what I read and could answer your question: "preincrement (++i) adds one to the value of i, then returns i; in contrast, i++ returns i then adds one to it, which in theory results in the creation of a temporary variable storing the value of i before the increment operation was applied".
This is a faux optimization. As far as I understand it, you're saving 1 op code. If you're looking to optimize your code with this technique, then you've gone the wrong way. Also, most compilers/interpreters will optimize this for you anyway (reference 1). In short I wouldn't worry about. But, if you're really worried, you should use i+=1.
Here's the quick-and-dirty benchmark I just did
var MAX = 1000000, t=0,i=0;
t = (new Date()).getTime();
for ( i=0; i<MAX;i++ ) {}
t = (new Date()).getTime() - t;
console.log(t);
t = (new Date()).getTime();
for ( i=0; i<MAX;++i ) {}
t = (new Date()).getTime() - t;
console.log(t);
t = (new Date()).getTime();
for ( i=0; i<MAX;i+=1 ) {}
t = (new Date()).getTime() - t;
console.log(t);
Raw results
Post Pre +=
1071 1073 1060
1065 1048 1051
1070 1065 1060
1090 1070 1060
1070 1063 1068
1066 1060 1064
1053 1063 1054
Removed lowest and highest
Post Pre +=
1071 ---- 1060
1065 ---- ----
1070 1065 1060
---- 1070 1060
1070 1063 ----
1066 1060 1064
---- 1063 1054
Averages
1068.4 1064.2 1059.6
Notice that this is over one million iterations and the results are within 9 milliseconds on average. Not really much of an optimization considering that most iterative processing in JavaScript is done over much smaller sets (DOM containers for example).
In theory, using a post-increment operator may produce a temporary. In practice, JavaScript compilers are smart enough to avoid that, especially in such trivial case.
For example, let's consider that sample code:
sh$ cat test.js
function preInc(){
for(i=0; i < 10; ++i)
console.log(i);
}
function postInc(){
for(i=0; i < 10; i++)
console.log(i);
}
// force lazy compilation
preInc();
postInc();
In that case, the V8 compiler in NodeJS produces exactly the same bytecode (look esp. at opcodes 39-44 for the increment):
sh$ node --version
v8.9.4
sh$ node --print-bytecode test.js | sed -nEe '/(pre|post)Inc/,/^\[/p'
[generating bytecode for function: preInc]
Parameter count 1
Frame size 24
77 E> 0x1d4ea44cdad6 # 0 : 91 StackCheck
87 S> 0x1d4ea44cdad7 # 1 : 02 LdaZero
88 E> 0x1d4ea44cdad8 # 2 : 0c 00 03 StaGlobalSloppy [0], [3]
94 S> 0x1d4ea44cdadb # 5 : 0a 00 05 LdaGlobal [0], [5]
0x1d4ea44cdade # 8 : 1e fa Star r0
0x1d4ea44cdae0 # 10 : 03 0a LdaSmi [10]
94 E> 0x1d4ea44cdae2 # 12 : 5b fa 07 TestLessThan r0, [7]
0x1d4ea44cdae5 # 15 : 86 23 JumpIfFalse [35] (0x1d4ea44cdb08 # 50)
83 E> 0x1d4ea44cdae7 # 17 : 91 StackCheck
109 S> 0x1d4ea44cdae8 # 18 : 0a 01 0d LdaGlobal [1], [13]
0x1d4ea44cdaeb # 21 : 1e f9 Star r1
117 E> 0x1d4ea44cdaed # 23 : 20 f9 02 0f LdaNamedProperty r1, [2], [15]
0x1d4ea44cdaf1 # 27 : 1e fa Star r0
121 E> 0x1d4ea44cdaf3 # 29 : 0a 00 05 LdaGlobal [0], [5]
0x1d4ea44cdaf6 # 32 : 1e f8 Star r2
117 E> 0x1d4ea44cdaf8 # 34 : 4c fa f9 f8 0b CallProperty1 r0, r1, r2, [11]
102 S> 0x1d4ea44cdafd # 39 : 0a 00 05 LdaGlobal [0], [5]
0x1d4ea44cdb00 # 42 : 41 0a Inc [10]
102 E> 0x1d4ea44cdb02 # 44 : 0c 00 08 StaGlobalSloppy [0], [8]
0x1d4ea44cdb05 # 47 : 77 2a 00 JumpLoop [42], [0] (0x1d4ea44cdadb # 5)
0x1d4ea44cdb08 # 50 : 04 LdaUndefined
125 S> 0x1d4ea44cdb09 # 51 : 95 Return
Constant pool (size = 3)
Handler Table (size = 16)
[generating bytecode for function: get]
[generating bytecode for function: postInc]
Parameter count 1
Frame size 24
144 E> 0x1d4ea44d821e # 0 : 91 StackCheck
154 S> 0x1d4ea44d821f # 1 : 02 LdaZero
155 E> 0x1d4ea44d8220 # 2 : 0c 00 03 StaGlobalSloppy [0], [3]
161 S> 0x1d4ea44d8223 # 5 : 0a 00 05 LdaGlobal [0], [5]
0x1d4ea44d8226 # 8 : 1e fa Star r0
0x1d4ea44d8228 # 10 : 03 0a LdaSmi [10]
161 E> 0x1d4ea44d822a # 12 : 5b fa 07 TestLessThan r0, [7]
0x1d4ea44d822d # 15 : 86 23 JumpIfFalse [35] (0x1d4ea44d8250 # 50)
150 E> 0x1d4ea44d822f # 17 : 91 StackCheck
176 S> 0x1d4ea44d8230 # 18 : 0a 01 0d LdaGlobal [1], [13]
0x1d4ea44d8233 # 21 : 1e f9 Star r1
184 E> 0x1d4ea44d8235 # 23 : 20 f9 02 0f LdaNamedProperty r1, [2], [15]
0x1d4ea44d8239 # 27 : 1e fa Star r0
188 E> 0x1d4ea44d823b # 29 : 0a 00 05 LdaGlobal [0], [5]
0x1d4ea44d823e # 32 : 1e f8 Star r2
184 E> 0x1d4ea44d8240 # 34 : 4c fa f9 f8 0b CallProperty1 r0, r1, r2, [11]
168 S> 0x1d4ea44d8245 # 39 : 0a 00 05 LdaGlobal [0], [5]
0x1d4ea44d8248 # 42 : 41 0a Inc [10]
168 E> 0x1d4ea44d824a # 44 : 0c 00 08 StaGlobalSloppy [0], [8]
0x1d4ea44d824d # 47 : 77 2a 00 JumpLoop [42], [0] (0x1d4ea44d8223 # 5)
0x1d4ea44d8250 # 50 : 04 LdaUndefined
192 S> 0x1d4ea44d8251 # 51 : 95 Return
Constant pool (size = 3)
Handler Table (size = 16)
Of course, other JavaScript compilers/interpreters may do otherwise, but this is doubtful.
As the last word, for what it worth, I nevertheless consider as a best practice to use pre-increment when possible: since I frequently switch languages, I prefer using the syntax with the correct semantic for what I want, instead of relying on compiler smartness. For example, modern C compilers won't make any difference either. But in C++, this can have a significant impact with overloaded operator++.
Sounds like premature optimization. When you're nearly done your app, check where the bottlenecks are and optimize those as needed. But if you want a thorough guide to loop performance, check this out:
http://blogs.oracle.com/greimer/entry/best_way_to_code_a
But you never know when this will become obsolete because of JS engine improvements and variations between browsers. Best choice is to not worry about it until it's a problem. Make your code clear to read.
Edit: According to this guy the pre vs. post is statistically insignificant. (with pre possibly being worse)
Anatoliy's test included a post-increment inside the pre-increment test function :(
Here are the results without this side effect...
function test_post() {
console.time('postIncrement');
var i = 1000000, x = 0;
do x++; while(i--);
console.timeEnd('postIncrement');
}
function test_pre() {
console.time('preIncrement');
var i = 1000000, x = 0;
do ++x; while(--i);
console.timeEnd('preIncrement');
}
test_post();
test_pre();
test_post();
test_pre();
test_post();
test_pre();
test_post();
test_pre();
Output
postIncrement: 3.21ms
preIncrement: 2.4ms
postIncrement: 3.03ms
preIncrement: 2.3ms
postIncrement: 2.53ms
preIncrement: 1.93ms
postIncrement: 2.54ms
preIncrement: 1.9ms
That's a big difference.
The optimization isn't the pre versus post increment. It's the use of bitwise 'shift' and 'and' operators rather than divide and mod.
There is also the optimization of minifying the javascript to decrease the total size (but this is not a runtime optimization).
This is probably cargo-cult programming.
It shouldn't make a difference when you're using a decent compilers/interpreters for languages that don't have arbitrary operator overloading.
This optimization made sense for C++ where
T x = ...;
++x
could modify a value in place whereas
T x = ...;
x++
would have to create a copy by doing something under-the-hood like
T x = ...;
T copy;
(copy = T(x), ++x, copy)
which could be expensive for large struct types or for types that do lots of computation in their `copy constructor.
Just tested it in firebug and found no difference between post- and preincrements. Maybe this optimization other platforms?
Here is my code for firebug testing:
function test_post() {
console.time('postIncrement');
var i = 1000000, x = 0;
do x++; while(i--);
console.timeEnd('postIncrement');
}
function test_pre() {
console.time('preIncrement');
var i = 1000000, x = 0;
do ++x; while(i--);
console.timeEnd('preIncrement');
}
test_post();
test_pre();
test_post();
test_pre();
test_post();
test_pre();
test_post();
test_pre();
Output is:
postIncrement: 140ms
preIncrement: 160ms
postIncrement: 136ms
preIncrement: 157ms
postIncrement: 148ms
preIncrement: 137ms
postIncrement: 136ms
preIncrement: 148ms
Using post increment causes stack overflow. Why? start and end would always return the same value without first incrementing
function reverseString(string = [],start = 0,end = string.length - 1) {
if(start >= end) return
let temp = string[start]
string[start] = string[end]
string[end] = temp
//dont't do this
//reverseString(string,start++,end--)
reverseString(string,++start,--end)
return array
}
let array = ["H","a","n","n","a","h"]
console.log(reverseString(array))

LIBMODBUS: Writing to a double register?

Is there a way I can write one value to a double register using LIBMODBUS? For example writing value 100,000 to be spread across one register. Currently using modbus_write_registers to write 10,000 I am sending the modbus message
rc = modbus_write_registers(ctx, 4, 2, tab_reg); (Where tab_reg[0] = 10,000 and tab_reg[1] = 0)
0A 10 00 04 00 02 04 27 10 00 00 DC 09
Ideally the message i believe I would like to send would not send the 00 00 for the zero value. Is this possible to utilise using Libmodbus?
NB - I have also attempted using modbus_write_register() and this produced a much longer message so I am inclined to believe write registerS is the way to go.

Converting a hexadecimal array into Binary and then into Decimal

I have a sample structure which has two sets of data. The first data contains the following Hex array '00 7F 3F FF 08 FF 60 26' and then when I convert it into binary and then decimal I get a correct answer which is '0 127 63 255 8 255 96 38'.
However, I have some data arrays which are not exactly arranged as the first one, they look something like this '1 40 0 F 00 40 00 47' and when I try to convert these kind of data sets the result is inaccurate. I get something like this '64 0 64 0 71' while the expected result is '1 64 0 15 0 64 0 71'.
This is my code with a sample data:
%% Structure
a(1).Id = 118;
a(1).Data = '00 7F 3F FF 08 FF 60 26';
a(2).Id = 108;
a(2).Data = '1 40 0 F 00 40 00 47';
%% Hexadecimal (Data) --> Binary --> Decimal
Data = a(2).Data;
str = regexp(Data,' ','split');
Ind = cellfun(#length,str);
str = str(Ind==2);
%Hex to Binary
binary = hexToBinaryVector(str,8,'MSBFirst');
%Binary to Decimal
Decimal = bi2de(binary,'left-msb');
Any help will be really appreciated!
adding 2 lines should do the trick:
str = regexp(Data,' ','split');
Ind = cellfun(#length,str);
str(Ind==1) = strcat('0',str(Ind==1) );
Ind = cellfun(#length,str);
str = str(Ind==2);
All it is doing is when it sees a String (your Hex) that is 1 Char, it puts a 0 infront of it, so correct it into its correct format. you can actually do this in the cellfun.

Array contents display in pairs

I have an array for example: A=[01 255 03 122 85 107]; and I want to print the contents as
A=
FF 01
7A 03
6B 55
Basically a read out from a memory. Is there any function in MatLab lib? I need to do this with minimum use of loops.
Use this -
str2num(num2str(fliplr(reshape(A,2,[])'),'%1d'))
Output -
ans =
21
43
65
87
If you only want to print it as characters, use it without str2num, like this -
num2str(fliplr(reshape(A,2,[])'),'%1d')
Output -
ans =
21
43
65
87
General case with zeros padding -
A=[1 2 3 4 5 6 7 8 9 3] %// Input array
N = 3; %// groupings, i.e. 2 for pairs and so on
A = [A zeros(1,N-mod(numel(A),N))]; %// pad with zeros
out = str2num(num2str(fliplr(reshape(A,N,[])'),'%1d'))
Output -
out =
321
654
987
3
Edit for hex numbers :
Ar = A(flipud(reshape(1:numel(A),2,[])))
out1 = reshape(cellstr(dec2hex(Ar))',2,[])'
out2 = [char(out1(:,1)) repmat(' ',[numel(A)/2 1]) char(out1(:,2))]
Output -
out1 =
'FF' '01'
'7A' '03'
'6B' '55'
out2 =
FF 01
7A 03
6B 55

Detecting I-frame data in an MPEG-4 transport stream

I am testing a project. I need to break the payload data(making zero some bytes) of the MPEG-4 ts packets by a percentage coming from the user. I am doing it by reading the ".ts" file packet by packet(188 bytes). But the video is changing to really mud after process. (By the way I'm writing the program in C)
So I decided to find the data/packets that belongs to I-frames, then not touching them but scrambling the other datas by percentage. I could find below
(in hex)
00 00 00 01 E0 start of video PES packet
..
..
00 00 01 B8 start of group of pictures header
..
..
00 00 01 00 the picture start code. This is 32 bits. The 10 bits immediately following this is called as the temporal reference. So temporal reference will include the byte following the picture start code and the first two bits of the second byte after the picture start code ie one byte(8 bits) + 2 bits. These we need to skip. Now the three bits present(3, 4 and 5th bits of the second byte from the picture start code) will indicate the Frame type ie I, B or P. So to get this simply logical AND & the second byte from the picture start code with 0x38 and right shift >> with 3.
For example the data is like that;
00 00 01 00 00 0F FF F8 00 00 01 B5........... and so on.
Here the first four bytes 00 00 01 00 is the picture start code.
The fifth byte and the first two bits of the sixth byte is the temporal reference.
So our concern is in the sixth byte --> 0F
((0F & 38)>>3)
Frame type = 1 ==> I Frame
Frame type 000 forbidden
Frame type 001 intra-coded (I) - iframe
Frame type 010 predictive-coded (P) - p frame
Frame type 011 bidirectionally-predictive-coded (B) - b frame
But this is for MPEG-2. Is there some patterns like that so I recognize and get the frame type with bitwise operations for MPEG-4 transport stream(extension is ".ts")?
And I need to get how many bytes or packets belong to that frame?
Thanks a lot for your help
I would parse the complete TS packet. So first determine what PID your video stream belongs to (by parsing the PAT and PMT). Then find keyframes by looking for the 'Random Access indicator' bit in the Adaptation Field.
uint8_t *pkt = <your 188 byte TS packet>;
assert( 0x47 == pkt[0] );
int16_t pid = ( ( pkt[1] & 0x1F) << 8 ) | pkt[2];
if ( pid == video_pid ) {
// found video stream
if( ( pkt[3] & 0x20 ) && ( pkt[4] > 0 ) ) {
// have AF
if ( pkt[5] & 0x40 ) {
// found keyframe
} } }
If you are using H.264 there should be specific byte stream for I and P frame ..
Like 0x0000000165 for I frame and 0x00000001XX for P frame ..
So just parse and look for continuous such byte stream in such a way you can identify I or P frame..
Again above byte stream is codec implementation dependent ..
For more information you can look into FFMPEG..

Resources