matrix enlargement in vhdl - matrix

I have a matrix (size n x m) in matlab. And I want to enlarge the matrix size to n+2x, m+2y) by adding zeros around the original n x m matrix.
Example:
original 2x2 matrix
1 2
3 4
New 4x4 matrix [0 0 0 0; 0 1 2 0; 0 3 4 0; 0 0 0 0]
0 0 0 0
0 1 2 0
0 3 4 0
0 0 0 0
How can I do it in vhdl?

type matrix is array(natural range <>, natural range <>) of natural;
signal matrix2x2 : matrix(0 to 1, 0 to 1);
signal matrix6x4 : matrix(0 to 5, 0 to 3);
function expand_matrix(m : matrix; x : natural; y : natural) return matrix is
constant ROWS : natural := m'length(1) + 2 * y;
constant COLS : natural := m'length(2) + 2 * x;
variable mx : matrix(0 to ROWS-1, 0 to COLS-1) := (others => (others => 0));
begin
for r in y to y + m'length(1) - 1 loop
for c in x to x + m'length(2) - 1 loop
mx(r, c) := m(r-y, c-x);
end loop;
end loop;
return mx;
end function;
begin
matrix2x2 <= ((1, 2), (3, 4));
matrix6x4 <= expand_matrix(matrix2x2, 1, 2);
For simplicity I made the matrix type a 2D array of natural. If you intend to eventually synthesize this you will be better off changing to a more constrained integer type or use the signed/unsigned vector types with only the number of bits you need.

Related

How to assign an array of a custom type of length one in VHDL [duplicate]

I'm trying to create a flexible array of constants. I want to use a 2D array which may sometimes be for example a 2x1, 2x2, 3x2 array etc. For example:
type int_2d_array is array (integer range<>, integer range<>) of integer;
constant M : positive := 2;
constant nMax : positive := 1;
constant n : int_2d_array(M - 1 downto 0, nMax - 1 downto 0) := ( (1) , (2) ); -- wrong
error: type int_2d_array does not match with the integer literal
If I do this, it doesn't complain:
type int_2d_array is array (integer range<>, integer range<>) of integer;
constant M : positive := 2;
constant nMax : positive := 2;
constant n : int_2d_array(M - 1 downto 0, nMax - 1 downto 0) := ( ( 0,1 ) , ( 2,2 )); -- accepted
Is the first example even possible using a 2D array?
The LRM (section 9.3.3 Aggregates) states:
Aggregates containing a single element association
shall always be specified using named association in order to distinguish them from parenthesized expressions.
So, this is OK:
constant n : int_1d_array(0 downto 0) := ( 0 => 1 );
and this is not:
constant n : int_1d_array(0 downto 0) := ( 1 );
http://www.edaplayground.com/x/6a4
I managed to compile the first example in the following ugly way:
type int_2d_array is array (integer range<>, integer range<>) of integer;
constant M : positive := 2;
constant nMax : positive := 1;
constant n : int_2d_array(M - 1 downto 0, nMax - 1 downto 0) := ( (others => 1) , (others => 2) );
Strange behavior, indeed.

Pascal - Sum of odd numbers between 0 and X

I've beeng having some trouble with this code... I need to create an algorithm which makes the user input a number (X), and then the program calculates the sum of all the odd numbers below (x).
This what I've tried so far, but can't really wrap my head around the logic behind it:
Program odd_numbers;
Var
Num, Limite, Soma: integer;
Begin;
Soma := 0;
Writeln('Choose a limit:');
Readln(Limite);
While (Limite / 2 > 0) do
Begin;
Soma := ((Num < Limite) mod 2 > 0);
Writeln('The sum of odd numbers from 0 to ', Limite, ' é ', Soma);
End;
if (Limite mod 2 = 0) then
Begin;
Soma := ((Num < Limite) mod 2 = 0);
Writeln('The sum of odd numbers from 0 to ', Limite, ' é ', Soma);
End;
End.
*PS: Been writing the code with variables in Portuguese, so don't mind the variables appearing weird to understand. *
I see that everyone is happily looping, but this is not necessary. This is a simple arithmetic sequence, and the sum can be calculated without a loop.
Just think of the following:
1 + 3 = 2 * (1 + 3) / 2 = 2 * 2 = 4 ; limits 3 and 4
1 + 3 + 5 = 3 * (1 + 5) / 2 = 3 * 3 = 9 ; limits 5 and 6
1 + 3 + 5 + 7 = 4 * (1 + 7) / 2 = 4 * 4 = 16 ; limits 7 and 8
1 + 3 + 5 + 7 + 9 = 5 * (1 + 9) / 2 = 5 * 5 = 25 ; limits 9 and 10
1 + 3 + 5 + 7 + 9 + 11 = 6 * (1 + 11) / 2 = 6 * 6 = 36 ; limits 11 and 12
But not only that, you'll see that it is in fact always a perfect square: Sqr((n+1) div 2).
So just calculate:
program odd_numbers;
var
Num, Limite, Soma: Integer;
begin
Write('Choose a limit: ');
Readln(Limite);
Num := (Limite + 1) div 2;
Soma := Num * Num;
Writeln('The sum of odd numbers from 0 to ', Limite, ' is ', Soma);
end.
Looks a little simpler than what the others propose.
The loop While (Limite / 2 > 0) do ... uses real arithmetic and not integer arithmetic. I guess you mean While (Limite div 2 > 0) do ... And you should change Limite in the loop otherwise you get stuck because the exit condition can never be reached.
After you have asked the user to enter a number, Limite, you need to keep that unchanged, because you need it in the final message. You also need a loop where you go through all numbers from Limite towards 0.
You started with a while loop which is ok, you are just missing the loop control variable. That is a variable that eventually gets a terminating value which then stops the loop. Use for example the Num variable you already have declared. You can use the same variable to investigate the numbers between user input and 0, for being odd values.
num := limite-1; // give num a start value based on user input (-1 because of "... numbers below (x)")
while num > 0 do // stop the loop when 0 is reached
begin
// here you investigate if `num` is a odd number (e.g. using `mod` operator or
// possibly your pascal has a built in `function Odd(value: integer): boolean;`)
// and add it to `Soma` if it is
num := num - 1;// decrement num at every iteration
end;
Finally you need to consider changes to the above, to handle negative input from the user.
To test if an integer is an odd value, you could use following function:
function IsOdd( value : Integer) : Boolean;
begin
IsOdd := (value mod 2) <> 0;
end;
Many pascal compilers have a built-in function called Odd(), which you could use.
A while loop works well to solve this problem. If you start with lowest odd number above zero, i.e. one and continue upwards so long we do not exceed the limit value we have a simple start:
function GetOddSumBelowX( X : Integer) : Integer;
var
i,sum: Integer;
begin
i := 1; // Start with first odd number
sum := 0;
while (i < X) do begin // as long as i less than X, loop
if IsOdd(i) then begin
sum := sum + i; // add to sum
end;
i := i + 1; // Increment i
end;
GetOddSumBelowX := sum;
end;
Now, that was simple enough. Next step to simplify the loop is to increment the i variable by two instead, just to jump between all odd numbers:
function GetOddSumBelowX( X : Integer) : Integer;
var
i,sum: Integer;
begin
i := 1; // Start with first odd number
sum := 0;
while (i < X) do begin // as long as i less than X, loop
sum := sum + i; // add to sum
i := i + 2; // Increment to next odd number
end;
GetOddSumBelowX := sum;
end;

Number of Integer Composition with the number which is in a specific list

Each positive integer n has 2^(n−1) distinct compositions. what If I want the number of composition which is only have specific number which is in my list:
for example composition of 4 is
4
3 1
1 3
2 2
2 1 1
1 2 1
1 1 2
1 1 1 1
but if I want the number of composition of 4 which it has only 1 and 2,
How could I calculate the NUMBER of distinct compositions?
2 2
2 1 1
1 2 1
1 1 2
1 1 1 1
Edited:
Here Haskell code which calculate the number, But I think It takes too long even IF I add memorization for Number 70
main :: IO ()
main = do
putStrLn "Enter the integer number"
num' <- getLine
let num = read num' :: Int
putStr ""
let result= composition num
let len=length result
print len
--print result
composition 0 = [[]]
composition n = [x:rest | x <- [1,2,3,4,5,6,7,8,9,10,20,30,40,50,60,70,80,90,100,200,300,400,500,600,700,800,900,1000],x<=n ,rest <- composition (n-x)]
You can use dynamic programming to calculate the number of needed compositions.
Example of recursive relation for your example:
P(4, [1,2]) = P(3, [1,2]) + P(2, [1,2])
here P(N, [list]) is the number of variants to make N from the list
Try to generalize formulas and use top-down memoization or bottom-up table filling DP to quickly find the result.
Delphi example:
var
A: TArray<Integer>;
Mem: TArray<Int64>;
N, i: Integer;
function Calc(N: Integer): Int64;
var
i: Integer;
begin
if Mem[N] >= 0 then
Exit(Mem[N]);
i := 0;
Result := 0;
while A[i] <= N do begin
Result := Result + Calc(N - A[i]);
Inc(i);
end;
Mem[N] := Result;
end;
begin
//should be sorted
//-1 - sentinel value to stop
A := TArray<Integer>.Create(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 60,
70, 80, 90, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, -1);
for N := 10 to 64 do begin
SetLength(Mem, N + 1);
for i := 1 to N do
Mem[i] := -1; //not initialized yet
Mem[0] := 1;
Memo1.Lines.Add(Format('%d %d', [N, Calc(N)]));
end;

Easy way of dividing an integer by 3

I'm working on a project that is to make a simple music player on an FPGA. It takes a music file of a specified format from the PC and plays it out loud in loops.
We need to implement the standard note lengths, i.e. Quaver for half a beat, Minim for 2 beats, etc. Currently we have a table of the lengths of a beat in numbers of clock cycles at various BPM values. We need to multiply them by these note lengths to yield the correct clock cycles. The only problem is Tuplet, which is a third of a full beat.
Without implementing a full-blown divider circuit, are there any maths tricks one can do to divide, approximately, an integer by 3?
Dividing by 3 is the same as multiplying by 1/3 (=0.33333). 0.3333 can be expressed as an addition of two or more (depending on the needed accuracy) (left) shifted input values.
input*2^-a + input*2^-b + input*2^-c ...
Just find suitable values for a, b, c, ...
This works for (almost) all divisions.
The following is a VHDL translation of some code from Hank Warren’s Hacker’s Delight. It divides an unsigned integer by the constant value 3 using only shifts, additions, and multiplications by the constant values 3 and 5 (which can also be reduced to shifts and additions).
-- q is quotient, d is dividend
q := (d srl 2) + (d srl 4); -- q = d*0.0101 (approx)
q := q + (q srl 4); -- q = d*0.01010101
q := q + (q srl 8);
q := q + (q srl 16);
r := resize(d - q * 3, 32); -- 0 <= r <= 15.
q := resize(q + (5 * (r + 1) srl 4), 32);
If the exact result of integer division by 3 (x / 3) is required for an unsigned value of length LEN, then truncating integer operations can be used with a little trick. The constant for 1/3 should be of length LEN + 1 and 1 should be added. Truncation can then be used afterwards. Pseudo code as:
C = 2 ** (LEN + 1) / 3 + 1
y = (x * C) / 2 ** (LEN + 1)
A Python function that shows and tests the algorithm for all values is:
def div_by_3_test(LEN):
DIVISOR = 3
C = 2 ** (LEN + 1) // DIVISOR + 1
for x in range(2 ** LEN):
if (x * C) // 2 ** (LEN + 1) != x // DIVISOR: exit('Failed')
A VHDL module that implements this as:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity div_by_3 is
generic(
LEN : natural := 12);
port(
x_i : in std_logic_vector(LEN - 1 downto 0);
y_o : out std_logic_vector(LEN - 1 downto 0));
end entity;
architecture syn of div_by_3 is
-- Constant to multiply, basically 1/3, but adding 1 to avoid error
constant C : std_logic_vector(LEN - 1 + 1 downto 0) :=
std_logic_vector(to_unsigned(2 ** (LEN + 1) / 3 + 1, LEN + 1));
-- Intermediate, with length as 2 * LEN + 1
signal t : std_logic_vector(2 * LEN + 1 - 1 downto 0);
begin
-- Intermediate with full length result
t <= std_logic_vector(unsigned(C) * unsigned(x_i));
-- Result after truncation for division by LEN + 1
y_o <= t(2 * LEN + 1 - 1 downto LEN + 1);
end architecture;
The advantage is that a division by 3 of an LEN bit number can be made in one cycle using only a single 2 * LEN + 1 bit multiplication.
Registers may be added to allow pipeline for high speed design.
Note that a similar scheme is possible for any divisor, but length of C must then be LEN + ceil(log2(DIVISOR)), with C scaled accordingly. Please see https://math.stackexchange.com/q/2444306/275980 regarding the mathematical foundation.
As mentioned by dieli, multiply by 0.333333.
However, instead of using several negative powers of 2 (i.e. a, b, c,..) just multiply 1/3 by some large power of 2, e.g. 2^24 * (1/3) = 5592405. After multiplying the clock cycles and 5592405, just divide by 2^24.
B = (clock cycles)*5592405
result = B/2^24
The size of B would depend the maximum size of clock cycles and can be computed by
maximum register size for B = integer of ( (log10((max size of clock cycles)*5592405)/log10(2)) + 0.5)

Matrix and algorithm "spiral"

i wanted ask if there some algorithm ready, that allowed me to do this: i have a matrix m (col) x n (row) with m x n elements. I want give position to this element starting from center and rotating as a spiral, for example, for a matrix 3x3 i have 9 elements so defined:
5 6 7
4 9 8
3 2 1
or for una matrix 4 x 3 i have 12 elements, do defined:
8 9 10 1
7 12 11 2
6 5 4 3
or again, a matrix 5x2 i have 10 elements so defined:
3 4
7 8
10 9
6 5
2 1
etc.
I have solved basically defining a array of integer of m x n elements and loading manually the value, but in generel to me like that matrix maked from algorithm automatically.
Thanks to who can help me to find something so, thanks very much.
UPDATE
This code, do exactely about i want have, but not is in delphi; just only i need that start from 1 and not from 0. Important for me is that it is valid for any matrics m x n. Who help me to translate it in delphi?
(defun spiral (rows columns)
(do ((N (* rows columns))
(spiral (make-array (list rows columns) :initial-element nil))
(dx 1) (dy 0) (x 0) (y 0)
(i 0 (1+ i)))
((= i N) spiral)
(setf (aref spiral y x) i)
(let ((nx (+ x dx)) (ny (+ y dy)))
(cond
((and (< -1 nx columns)
(< -1 ny rows)
(null (aref spiral ny nx)))
(setf x nx
y ny))
(t (psetf dx (- dy)
dy dx)
(setf x (+ x dx)
y (+ y dy)))))))
> (pprint (spiral 6 6))
#2A ((0 1 2 3 4 5)
(19 20 21 22 23 6)
(18 31 32 33 24 7)
(17 30 35 34 25 8)
(16 29 28 27 26 9)
(15 14 13 12 11 10))
> (pprint (spiral 5 3))
#2A ((0 1 2)
(11 12 3)
(10 13 4)
(9 14 5)
(8 7 6))
Thanks again very much.
Based on the classic spiral algorithm. supporting non-square matrix:
program SpiralMatrix;
{$APPTYPE CONSOLE}
uses
SysUtils;
type
TMatrix = array of array of Integer;
procedure PrintMatrix(const a: TMatrix);
var
i, j: Integer;
begin
for i := 0 to Length(a) - 1 do
begin
for j := 0 to Length(a[0]) - 1 do
Write(Format('%3d', [a[i, j]]));
Writeln;
end;
end;
var
spiral: TMatrix;
i, m, n: Integer;
row, col, dx, dy,
dirChanges, visits, temp: Integer;
begin
m := 3; // columns
n := 3; // rows
SetLength(spiral, n, m);
row := 0;
col := 0;
dx := 1;
dy := 0;
dirChanges := 0;
visits := m;
for i := 0 to n * m - 1 do
begin
spiral[row, col] := i + 1;
Dec(visits);
if visits = 0 then
begin
visits := m * (dirChanges mod 2) + n * ((dirChanges + 1) mod 2) - (dirChanges div 2) - 1;
temp := dx;
dx := -dy;
dy := temp;
Inc(dirChanges);
end;
Inc(col, dx);
Inc(row, dy);
end;
PrintMatrix(spiral);
Readln;
end.
3 x 3:
1 2 3
8 9 4
7 6 5
4 x 3:
1 2 3 4
10 11 12 5
9 8 7 6
2 x 5:
1 2
10 3
9 4
8 5
7 6
There you go!!! After 30some syntax errors...
On ideone.com, I ran it with some tests and it seems to work fine. I think you can see the output there still and run it yourself...
I put some comments in the code. Enough to understand most of it. The main navigation system is a little bit harder to explain. Briefly, doing a spiral is going in first direction 1 time, second 1 time, third 2 times, fourth 2 times, fifth 3 times, 3, 4, 4, 5, 5, and so on. I use what I called a seed and step to get this behavior.
program test;
var
w, h, m, n, v, d : integer; // Matrix size, then position, then value and direction.
spiral : array of array of integer; // Matrix/spiral itself.
seed, step : integer; // Used to travel the spiral.
begin
readln(h);
readln(w);
setlength(spiral, h, w);
v := w * h; // Value to put in spiral.
m := trunc((h - 1) / 2); // Finding center.
n := trunc((w - 1) / 2);
d := 0; // First direction is right.
seed := 2;
step := 1;
// Travel the spiral.
repeat
// If in the sub-spiral, store value.
if ((m >= 0) and (n >= 0) and (m < h) and (n < w)) then
begin
spiral[m, n] := v;
v := v - 1;
end;
// Move!
case d of
0: n := n + 1;
1: m := m - 1;
2: n := n - 1;
3: m := m + 1;
end;
// Plan trajectory.
step := step - 1;
if step = 0 then
begin
d := (d + 1) mod 4;
seed := seed + 1;
step := trunc(seed / 2);
end;
until v = 0;
// Print the spiral.
for m := 0 to (h - 1) do
begin
for n := 0 to (w - 1) do
begin
write(spiral[m, n], ' ');
end;
writeln();
end;
end.
If you really need that to print text spirals I'll let you align the numbers. Just pad them with spaces.
EDIT:
Was forgetting... In order to make it work on ideone, I put the parameters on 2 lines as input. m, then n.
For example:
5
2
yields
3 4
7 8
10 9
6 5
2 1
Here's the commented JavaScript implementation for what you're trying to accomplish.
// return an array representing a matrix of size MxN COLxROW
function spiralMatrix(M, N) {
var result = new Array(M * N);
var counter = M * N;
// start position
var curCol = Math.floor((M - 1) / 2);
var curRow = Math.floor(N / 2);
// set the center
result[(curRow * M) + curCol] = counter--;
// your possible moves RIGHT, UP, LEFT, DOWN * y axis is flipped
var allMoves = [[1,0], [0,-1], [-1,0], [0,1]];
var curMove = 0;
var moves = 1; // how many times to make current Move, 1,1,2,2,3,3,4,4 etc
// spiral
while(true) {
for(var i = 0; i < moves; i++) {
// move in a spiral outward counter clock-wise direction
curCol += allMoves[curMove][0];
curRow += allMoves[curMove][1];
// naively skips locations that are outside of the matrix bounds
if(curCol >= 0 && curCol < M && curRow >= 0 && curRow < N) {
// set the value and decrement the counter
result[(curRow * M) + curCol] = counter--;
// if we reached the end return the result
if(counter == 0) return result;
}
}
// increment the number of times to move if necessary UP->LEFT and DOWN->RIGHT
if(curMove == 1 || curMove == 3) moves++;
// go to the next move in a circular array fashion
curMove = (curMove + 1) % allMoves.length;
}
}
The code isn't the most efficient, because it walks the spiral naively without first checking if the location it's walking on is valid. It only checks the validity of the current location right before it tries to set the value on it.
Even though the question is already answered, this is an alternative solution (arguably simpler).
The solution is in python (using numpy for bidimendional arrays), but can be easily ported.
The basic idea is to use the fact that the number of steps is known (m*n) as end condition,
and to properly compute the next element of the loop at each iteration:
import numpy as np
def spiral(m, n):
"""Return a spiral numpy array of int with shape (m, n)."""
a = np.empty((m, n), int)
i, i0, i1 = 0, 0, m - 1
j, j0, j1 = 0, 0, n - 1
for k in range(m * n):
a[i, j] = k
if i == i0 and j0 <= j < j1: j += 1
elif j == j1 and i0 <= i < i1: i += 1
elif i == i1 and j0 < j <= j1: j -= 1
elif j == j0 and 1 + i0 < i <= i1: i -= 1
else:
i0 += 1
i1 -= 1
j0 += 1
j1 -= 1
i, j = i0, j0
return a
And here some outputs:
>>> spiral(3,3)
array([[0, 1, 2],
[7, 8, 3],
[6, 5, 4]])
>>> spiral(4,4)
array([[ 0, 1, 2, 3],
[11, 12, 13, 4],
[10, 15, 14, 5],
[ 9, 8, 7, 6]])
>>> spiral(5,4)
array([[ 0, 1, 2, 3],
[13, 14, 15, 4],
[12, 19, 16, 5],
[11, 18, 17, 6],
[10, 9, 8, 7]])
>>> spiral(2,5)
array([[0, 1, 2, 3, 4],
[9, 8, 7, 6, 5]])

Resources