Specman - add bits in the beginning and end of list of bit - unpack

I have the following list of bit which contains 8 bits (input to function):
bs: list of bit;
I have the following struct:
struct uart_frame_s like any_sequence_item {
%start_bit : bit;
data_size : uint;
%data[data_size] : list of bit;
%stop_bit : bit;
keep soft start_bit == 0;
keep soft stop_bit == 1;
keep soft data_size == 8;
};
I have to execute the following:
unpack(packing.low, bs, current_frame);
The problem that bs size is 8, but current frame contains 10 bits....
So how can I add bits in the beginning and end of list of bit ('0' in the beginning and '1' in the end).
Or alternatively verify that the bs will unpack to 1-8 bits in current frame.

if you want to pack the bs into the frame data field, you can -
unpack(packing.low, bs, current_frame.data);

Related

How to Optimally Shift Large Arrays n Number of Incidences

I am creating my own version of a music visualizer that responds to the frequency of music; a common project. I am using 2 strips of Neopixels, each with 300 LEDs making a total of 600 LEDs.
I have written functions, shown below, that create the desired affect of having a pulse of light travel down the strips independently. However, when running in real time with music, the updates per second is too slow to create a nice pulse; it looks choppy.
I believe the problem is the number of operations that must be preformed when the function is called. For each call to the function, a 300 value array per strip must be shifted 5 indices and 5 new values added.
Here is an illustration of how the function currently works:
-Arbitrary numbers are used to fill the array
-A shift of 2 indices shown
-X represents an index with no value assigned
-N represents the new value added by the function
Initial array: [1][3][7][2][9]
Shifted array: [X][X][1][3][7]
New array: [N][N][1][3][7]
Here if my code. Function declarations below loop(). I am using random() to trigger a pulse for testing purposes; no other functions were included for brevity.
#include <FastLED.h>
// ========================= Define setup parameters =========================
#define NUM_LEDS1 300 // Number of LEDS in strip 1
#define NUM_LEDS2 300 // Number of LEDS in strip 1
#define STRIP1_PIN 6 // Pin number for strip 1
#define STRIP2_PIN 10 // Pin number for strip 2
#define s1Band 1 // String 1 band index
#define s2Band 5 // String 2 band index
#define numUpdate 5 // Number of LEDs that will be used for a single pulse
// Colors for strip 1: Band 2 (Index 1)
#define s1R 255
#define s1G 0
#define s1B 0
// Colors for strip 2: Band 6 (Index 5)
#define s2R 0
#define s2G 0
#define s2B 255
// Create the arrays of LEDs
CRGB strip1[NUM_LEDS1];
CRGB strip2[NUM_LEDS2];
void setup() {
FastLED.addLeds<NEOPIXEL, STRIP1_PIN>(strip1, NUM_LEDS1);
FastLED.addLeds<NEOPIXEL, STRIP2_PIN>(strip2, NUM_LEDS2);
FastLED.setBrightness(10);
FastLED.clear();
FastLED.show();
}
void loop() {
int num = random(0, 31);
// Pulse strip based on random number for testing
if (num == 5) {
pulseDownStrip1();
}
pulseBlack1();
}
// ======================= FUNCTION DECLARATIONS =======================
// Pulse a set of colored LEDs down the strip
void pulseDownStrip1() {
// Move all current LED states by n number of leds to be updated
for (int i = NUM_LEDS1 - 1; i >= 0; i--) {
strip1[i] = strip1[i - numUpdate];
}
// Add new LED values to the pulse
for (int j = 0; j < numUpdate; j++) {
strip1[j].setRGB(s1R, s1G, s1B);
}
FastLED.show();
}
// Pulse a set of black LEDs down the strip
void pulseBlack1(){
// Move all current LED states by n number of leds to be updated
for (int i = NUM_LEDS1 - 1; i >= 0; i--) {
strip1[i] = strip1[i - numUpdate];
}
// Add new LED values to the pulse
for (int j = 0; j < numUpdate; j++) {
strip1[j].setRGB(0, 0, 0);
}
FastLED.show();
}
I am looking for any suggestions regarding optimizing this operation. Through my research, copying the desired values to a new array rather than shifting the existing array seems to be a faster operation.
If you have any advice on optimizing this process, or alternate methods to produce the same animation, I would appreciate the help.
The secret is to not shift it. Shift where you start reading it instead. Keep track of a separate variable that keeps the start position and alter your reading through the array to start there, roll back over to zero when it gets to the array length, and stop one short of where it starts.
Google the term "circular buffer" Look at the Arduino HardwareSerial class for a decent implementation example.

Error with verilog generate loop : Unable to bind wire/reg/memory

I am building a signed multiplier verilog code based on Row Adder Tree (binary tree) architecture and modified baugh-wooley algorithm.
However, I am facing issue with generate loop as follows when I add the partial products across subsequent layer of the binary tree.
Do you guys have any idea how to get away from those error ?
edaplayground online code
Is using generate loop the only feasible way (given large length of multiplicand and multiplier) to do the additions of partial products across layers of a binary tree ?
module multiply(clk, reset, in_valid, out_valid, in_A, in_B, out_C); // C=A*B
parameter A_WIDTH = 16;
parameter B_WIDTH = 16;
input clk, reset;
input in_valid; // to signify that in_A, in_B are valid
input signed [(A_WIDTH-1):0] in_A;
input signed [(B_WIDTH-1):0] in_B;
output reg signed [(A_WIDTH+B_WIDTH-1):0] out_C;
output reg out_valid; // to signify that out_C is valid
/*
This multiplier code architecture requires an area of O(N*M*logN) and time O(logN)
with M being the length or bitwidth of the multiplicand
see https://i.imgur.com/NaqjC6G.png or
Row Adder Tree Multipliers in http://www.andraka.com/multipli.php or
https://pdfs.semanticscholar.org/415c/d98dafb5c9cb358c94189927e1f3216b7494.pdf#page=10
regarding the mechanisms within all layers
In the case of an adder tree, the adders making up the levels closer to the input
take up real estate (remember the structure of row adder tree). As the size of
the input multiplicand bitwidth grows, it becomes more and more difficult to find a
placement that does not use long routes involving multiple switch nodes. The result
is the maximum clocking speed degrades quickly as the size of the bitwidth grows.
For signed multiplication, see also modified baugh-wooley algorithm for trick in
skipping sign extension, thus smaller final routed silicon area.
https://stackoverflow.com/questions/54268192/understanding-modified-baugh-wooley-multiplication-algorithm/
All layers are pipelined, so throughput = one result for each clock cycle
but each multiplication result still have latency = NUM_OF_INTERMEDIATE_LAYERS
*/
// The multiplication of two numbers is equivalent to adding as many copies of one
// of them, the multiplicand, as the value of the other one, the multiplier.
localparam SMALLER_WIDTH = (A_WIDTH <= B_WIDTH) ? A_WIDTH : B_WIDTH;
localparam LARGER_WIDTH = (A_WIDTH > B_WIDTH) ? A_WIDTH : B_WIDTH;
wire [(LARGER_WIDTH-1):0] MULTIPLICAND = (A_WIDTH > B_WIDTH) ? in_A : in_B ;
wire [(SMALLER_WIDTH-1):0] MULTIPLIPLIER = (A_WIDTH <= B_WIDTH) ? in_A : in_B ;
localparam NUM_OF_INTERMEDIATE_LAYERS = $clog2(SMALLER_WIDTH);
/*Stage 1: Binary multiplications to generate partial products rows*/
// first layer has "SMALLER_WIDTH" entries of data of width "LARGER_WIDTH"
// This resulted in a binary tree with faster vertical addition processes as we have
// lesser (NUM_OF_INTERMEDIATE_LAYERS) rows to add
reg [(LARGER_WIDTH-1):0] partial_products [0:(SMALLER_WIDTH-1)];
generate
genvar first_layer_index; // all partial products rows are in first layer
for(first_layer_index=0; first_layer_index<SMALLER_WIDTH; first_layer_index=first_layer_index+1) begin: first_layer
always #(posedge clk, posedge reset)
begin
if(reset) partial_products[first_layer_index] <= 0;
else begin
partial_products[first_layer_index] <= (MULTIPLICAND & MULTIPLIPLIER[first_layer_index]); // generation of partial products rows
end
end
end
endgenerate
/*Stage 2 : Intermediate partial products additions*/
// intermediate partial product rows
// Imagine a rhombus of height of "NUM_OF_INTERMEDIATE_LAYERS"
// and width of "LARGER_WIDTH" being re-arranged into binary row adder tree
// such that additions can be done in O(logN) time
generate
genvar layer;
for(layer=1; layer<NUM_OF_INTERMEDIATE_LAYERS; layer=layer+1) begin: middle_layers
// number of leafs (or children) in each layer within the binary tree
localparam NUM_OF_PP_ADDITION = (SMALLER_WIDTH >> layer);
reg [(LARGER_WIDTH+layer-1):0] middle_rows[0:(NUM_OF_PP_ADDITION-1)];
integer pp_index; // leaf index within each layer of the tree
always #(posedge clk, posedge reset)
begin
if(reset)
begin
for(pp_index=0; pp_index<NUM_OF_PP_ADDITION ; pp_index=pp_index+1)
middle_rows[pp_index] <= 0;
end
else begin
for(pp_index=0; pp_index<NUM_OF_PP_ADDITION ; pp_index=pp_index+1)
middle_rows[pp_index] <=
middle_layers[layer-1].middle_rows[1<<pp_index] +
(middle_layers[layer-1].middle_rows[(1<<pp_index) + 1]) << 1;
end
end
end
endgenerate
/*Stage 3 : Adding the final two partial products*/
wire sign_bit = in_A[A_WIDTH-1] ^ in_B[B_WIDTH-1];
always #(posedge clk, posedge reset)
begin
if(reset)
begin
out_C <= 0;
out_valid <= 0;
end
else out_C <= 0;// {sign_bit, };
end
endmodule
iverilog '-Wall' '-g2012' design.sv testbench.sv && unbuffer vvp a.out
design.sv:107: error: Unable to bind wire/reg/memory 'middle_layers[(layer)-('sd1)].middle_rows[('sd1)<<(pp_index)]' in 'test.mul.middle_layers[1]'
design.sv:108: error: Unable to bind wire/reg/memory 'middle_layers[(layer)-('sd1)].middle_rows[(('sd1)<<(pp_index))+('sd1)]' in 'test.mul.middle_layers[1]'
2 error(s) during elaboration.
your mistake is that there is no block named multiple_layers[0] in your code.
you start with
for(layer=1; ...) begin: multile_layers
reg [(LARGER_WIDTH+layer-1):0] middle_rows;
always begin
reset middle rows;
for ... multiple_layers [layer - 1] ...
end
end
so, the last reference to the previous block failed.
I guess you would need something like the following
for(layer=0; ...) begin: multile_layers
reg [(LARGER_WIDTH+layer-1):0] middle_rows;
if (layer > 1) begin
always begin
reset middle rows
for ... multiple_layers [layer - 1] ...
end
end
else begin
always begin
reset middle_rows
// no for
end
end
end

Specman soft select on variable, decimal vs. hexadecimal values

Here are two similar constraint blocks, one written using decimal notation, and the other using hexadecimal notation. The first works as expected, but the second only generates positive values (including 0) out of the 5 available values:
-- positive and negative values generated as expected
var rnd_byte : int(bits: 8);
for i from 0 to 9 {
gen rnd_byte keeping {
soft it == select {
90 : [-1, -128 , 127, 1];
10 : 0x00;
};
};
print rnd_byte;
};
-- only positive values (including 0) generated!!!
var rnd_byte : int(bits: 8);
for i from 0 to 9 {
gen rnd_byte keeping {
soft it == select {
90 : [0xFF, 0x80, 0x7F, 0x01];
10 : 0x00;
};
};
print rnd_byte;
};
How can I make the second example behave as the first one, but keep the hexadecimal notation. I don't want to write large decimal numbers.
some more about this issue - with procedural code there is auto casting. so you can write
var rnd_byte : int( bits : 8);
rnd_byte = 0xff;
and it will result with rnd_byte == -1.
constraints work with int (bits :8 ) semantics, and this code would fail:
var rnd_byte : int( bits : 8);
gen rnd_byte keeping {it == 0xff};
as suggested - for getting 0xff - define the field as unsigned.
0xff and 0x80 are not in the range of the rnd_byte data type. You need to declare rnd_byte as uint(bits:8).
Alternatively, try to typecast the literals (I could not verify the syntax):
(0xff).as_a(int(bits:8))
In procedural code, automatic casting between numeric types takes care of the absolute majority of cases. However, in generation numbers are viewed by their natural values, as in int(bits:*) semantics. Hex notation means the value is unsigned.

Specman/e list of lists (multidimensional array)

How can I create a fixed multidimensional array in Specman/e using varibles?
And then access individual elements or whole rows?
For example in SystemVerilog I would have:
module top;
function automatic my_func();
bit [7:0] arr [4][8]; // matrix: 4 rows, 8 columns of bytes
bit [7:0] row [8]; // array : 8 elements of bytes
row = '{1, 2, 3, 4, 5, 6, 7, 8};
$display("Array:");
foreach (arr[i]) begin
arr[i] = row;
$display("row[%0d] = %p", i, row);
end
$display("\narr[2][3] = %0d", arr[2][3]);
endfunction : my_func
initial begin
my_func();
end
endmodule : top
This will produce this output:
Array:
row[0] = '{'h1, 'h2, 'h3, 'h4, 'h5, 'h6, 'h7, 'h8}
row[1] = '{'h1, 'h2, 'h3, 'h4, 'h5, 'h6, 'h7, 'h8}
row[2] = '{'h1, 'h2, 'h3, 'h4, 'h5, 'h6, 'h7, 'h8}
row[3] = '{'h1, 'h2, 'h3, 'h4, 'h5, 'h6, 'h7, 'h8}
arr[2][3] = 4
Can someone rewrite my_func() in Specman/e?
There are no fixed arrays in e. But you can define a variable of a list type, including a multi-dimensional list, such as:
var my_md_list: list of list of my_type;
It is not the same as a multi-dimensional array in other languages, in the sense that in general each inner list (being an element of the outer list) may be of a different size. But you still can achieve your purpose using it. For example, your code might be rewritten in e more or less like this:
var arr: list of list of byte;
var row: list of byte = {1;2;3;4;5;6;7;8};
for i from 0 to 3 do {
arr.add(row.copy());
print arr[i];
};
print arr[2][3];
Notice the usage of row.copy() - it ensures that each outer list element will be a copy of the original list.
If we don't use copy(), we will get a list of many pointers to the same list. This may also be legitimate, depending on the purpose of your code.
In case of a field (as opposed to a local variable), it is also possible to declare it with a given size. This size is, again, not "fixed" and can be modified at run time (by adding or removing items), but it determines the original size of the list upon creation, for example:
struct foo {
my_list[4][8]: list of list of int;
};

Non repeating random numbers in Objective-C

I'm using
for (int i = 1, i<100, i++)
int i = arc4random() % array count;
but I'm getting repeats every time. How can I fill out the chosen int value from the range, so that when the program loops I will not get any dupe?
It sounds like you want shuffling of a set rather than "true" randomness. Simply create an array where all the positions match the numbers and initialize a counter:
num[ 0] = 0
num[ 1] = 1
: :
num[99] = 99
numNums = 100
Then, whenever you want a random number, use the following method:
idx = rnd (numNums); // return value 0 through numNums-1
val = num[idx]; // get then number at that position.
num[idx] = val[numNums-1]; // remove it from pool by overwriting with highest
numNums--; // and removing the highest position from pool.
return val; // give it back to caller.
This will return a random value from an ever-decreasing pool, guaranteeing no repeats. You will have to beware of the pool running down to zero size of course, and intelligently re-initialize the pool.
This is a more deterministic solution than keeping a list of used numbers and continuing to loop until you find one not in that list. The performance of that sort of algorithm will degrade as the pool gets smaller.
A C function using static values something like this should do the trick. Call it with
int i = myRandom (200);
to set the pool up (with any number zero or greater specifying the size) or
int i = myRandom (-1);
to get the next number from the pool (any negative number will suffice). If the function can't allocate enough memory, it will return -2. If there's no numbers left in the pool, it will return -1 (at which point you could re-initialize the pool if you wish). Here's the function with a unit testing main for you to try out:
#include <stdio.h>
#include <stdlib.h>
#define ERR_NO_NUM -1
#define ERR_NO_MEM -2
int myRandom (int size) {
int i, n;
static int numNums = 0;
static int *numArr = NULL;
// Initialize with a specific size.
if (size >= 0) {
if (numArr != NULL)
free (numArr);
if ((numArr = malloc (sizeof(int) * size)) == NULL)
return ERR_NO_MEM;
for (i = 0; i < size; i++)
numArr[i] = i;
numNums = size;
}
// Error if no numbers left in pool.
if (numNums == 0)
return ERR_NO_NUM;
// Get random number from pool and remove it (rnd in this
// case returns a number between 0 and numNums-1 inclusive).
n = rand() % numNums;
i = numArr[n];
numArr[n] = numArr[numNums-1];
numNums--;
if (numNums == 0) {
free (numArr);
numArr = 0;
}
return i;
}
int main (void) {
int i;
srand (time (NULL));
i = myRandom (20);
while (i >= 0) {
printf ("Number = %3d\n", i);
i = myRandom (-1);
}
printf ("Final = %3d\n", i);
return 0;
}
And here's the output from one run:
Number = 19
Number = 10
Number = 2
Number = 15
Number = 0
Number = 6
Number = 1
Number = 3
Number = 17
Number = 14
Number = 12
Number = 18
Number = 4
Number = 9
Number = 7
Number = 8
Number = 16
Number = 5
Number = 11
Number = 13
Final = -1
Keep in mind that, because it uses statics, it's not safe for calling from two different places if they want to maintain their own separate pools. If that were the case, the statics would be replaced with a buffer (holding count and pool) that would "belong" to the caller (a double-pointer could be passed in for this purpose).
And, if you're looking for the "multiple pool" version, I include it here for completeness.
#include <stdio.h>
#include <stdlib.h>
#define ERR_NO_NUM -1
#define ERR_NO_MEM -2
int myRandom (int size, int *ppPool[]) {
int i, n;
// Initialize with a specific size.
if (size >= 0) {
if (*ppPool != NULL)
free (*ppPool);
if ((*ppPool = malloc (sizeof(int) * (size + 1))) == NULL)
return ERR_NO_MEM;
(*ppPool)[0] = size;
for (i = 0; i < size; i++) {
(*ppPool)[i+1] = i;
}
}
// Error if no numbers left in pool.
if (*ppPool == NULL)
return ERR_NO_NUM;
// Get random number from pool and remove it (rnd in this
// case returns a number between 0 and numNums-1 inclusive).
n = rand() % (*ppPool)[0];
i = (*ppPool)[n+1];
(*ppPool)[n+1] = (*ppPool)[(*ppPool)[0]];
(*ppPool)[0]--;
if ((*ppPool)[0] == 0) {
free (*ppPool);
*ppPool = NULL;
}
return i;
}
int main (void) {
int i;
int *pPool;
srand (time (NULL));
pPool = NULL;
i = myRandom (20, &pPool);
while (i >= 0) {
printf ("Number = %3d\n", i);
i = myRandom (-1, &pPool);
}
printf ("Final = %3d\n", i);
return 0;
}
As you can see from the modified main(), you need to first initialise an int pointer to NULL then pass its address to the myRandom() function. This allows each client (location in the code) to have their own pool which is automatically allocated and freed, although you could still share pools if you wish.
You could use Format-Preserving Encryption to encrypt a counter. Your counter just goes from 0 upwards, and the encryption uses a key of your choice to turn it into a seemingly random value of whatever radix and width you want.
Block ciphers normally have a fixed block size of e.g. 64 or 128 bits. But Format-Preserving Encryption allows you to take a standard cipher like AES and make a smaller-width cipher, of whatever radix and width you want (e.g. radix 2, width 16), with an algorithm which is still cryptographically robust.
It is guaranteed to never have collisions (because cryptographic algorithms create a 1:1 mapping). It is also reversible (a 2-way mapping), so you can take the resulting number and get back to the counter value you started with.
AES-FFX is one proposed standard method to achieve this. I've experimented with some basic Python code which is based on the AES-FFX idea, although not fully conformant--see Python code here. It can e.g. encrypt a counter to a random-looking 7-digit decimal number, or a 16-bit number.
You need to keep track of the numbers you have already used (for instance, in an array). Get a random number, and discard it if it has already been used.
Without relying on external stochastic processes, like radioactive decay or user input, computers will always generate pseudorandom numbers - that is numbers which have many of the statistical properties of random numbers, but repeat in sequences.
This explains the suggestions to randomise the computer's output by shuffling.
Discarding previously used numbers may lengthen the sequence artificially, but at a cost to the statistics which give the impression of randomness.
The best way to do this is create an array for numbers already used. After a random number has been created then add it to the array. Then when you go to create another random number, ensure that it is not in the array of used numbers.
In addition to using secondary array to store already generated random numbers, invoking random no. seeding function before every call of random no. generation function might help to generate different seq. of random numbers in every run.