Trying to use a DFRobot IR Camera to find infrared lights - raspberry-pi3

I am currently using a Raspberry Pi 3, python 2.7.16, and a DFRobot Positioning IR Camera. I am trying to read IR positioning lights with the camera and then have it do a continuous print. I keep running into an error that can be seen below. I apologize if something is not correct, as this is my first time posting.
I have been working on this project for about a month. I have tried some libraries such as pigpio, but with no success. Below is me making sure the Pi can read the device.
pi#raspberrypi:~/Desktop $ sudo i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- 58 -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
Below are the 2 Codes I used
SeniorDesign_Test.py
from SeniorDesign_IRcam import pyIRcam
from time import sleep,time
from Tkinter import *
update_rate = 20 # 20ms update rate
camera = pyIRcam() # Sensor initialization
master = Tk()
w = Canvas(master, width = 1024, height =768) #IR Camera Dimensions
w.pack(fill = BOTH, expand = 1)
def update_Image():
camera.getPositions() #Update with new IR objects
w.delete(ALL)
if camera.positions['found']:
camera.findTarget()
if(camera.targetFound):
color = "blue"
else:
color ="red"
w.create_rectangle(camera.positions['1'][0], camera.positions['1'][1], camera.positions['1'][0] + 10, camera.positions['1'][1] + 10, fill = color)
w.create_rectangle(camera.positions['2'][0], camera.positions['2'][1], camera.positions['2'][0] + 10, camera.positions['2'][1] + 10, fill = color)
w.create_rectangle(camera.positions['3'][0], camera.positions['3'][1], camera.positions['3'][0] + 10, camera.positions['3'][1] + 10, fill = color)
w.create_rectangle(camera.positions['4'][0], camera.positions['4'][1], camera.positions['4'][0] + 10, camera.positions['4'][1] + 10, fill = color)
master.after(0, update_Image)
master.mainloop()
SeniorDesign_IRCam.py
import smbus
import math
from time import sleep
bus = smbus.SMBus(1)
degPerPixel = 0.0299947917
ledDistance = 1.3 #In Inches
class pyIRcam:
def __init__(self):
self.sensorAddress = 0x58 # address of camera
self.device = smbus.SMBus(1)
self.positions = {'found':False,'1':[0,0],'2':[0,0],'3':[0,0],'4':[0,0]}
# Initialization of the IR sensor
self.initCMDs = [0x30, 0x01, 0x30, 0x08, 0x06, 0x90, 0x08, 0xC0, 0x1A, 0x40, 0x33, 0x33]
for i,j in zip(self.initCMDs[0::2], self.initCMDs[1::2]):
self.device.write_byte_data(self.sensorAddress, i, j)
sleep(0.01)
def getPositions(self):
self.device.write_byte(self.sensorAddress, 0x36)
data = self.device.read_i2c_block_data(self.sensorAddress, 0x36, 16) # Read the data from the I2C bus
x = [0x00]*4
y = [0x00]*4
i=0
for j in xrange(1,11,3): # Decode the data coming from the I2C bus
x[i]=data[j]+((data[j+2] & 0x30) << 4)
y[i]=data[j+1]+((data[j+2] & 0xC0) << 2)
i+=1
i=0
for j in ('1','2','3','4'): # Put the x and y positions into the dictionary
self.positions[j][0]=x[i]
self.positions[j][1]=y[i]
i+=1
if ( all(i == 1023 for i in x) and all(i == 1023 for i in y) ): # If all objects are 1023, then there is no IR object in front of the sensor
self.positions['found'] = False
else:
self.positions['found'] = True
def getDistance(self):
#getting minimum distance
distance12 = math.sqrt((self.positions['1'][0] - self.positions ['2'][0]) ** 2 + (self.positions['1'][1] - self.positions['2'][1]) ** 2)
distance23 = math.sqrt((self.positions['2'][0] - self.positions ['3'][0]) ** 2 + (self.positions['2'][1] - self.positions['3'][1]) ** 2)
distance13 = math.sqrt((self.positions['1'][0] - self.positions ['3'][0]) ** 2 + (self.positions['1'][1] - self.positions['3'][1]) ** 2)
distance = min(distance12, distance23, distance13)
theta = distance * degPerPixel
phi = 90 - theta / 2
d = (ledDistance / 2.0) * math.tan (phi * math.pi / 180.0)
print d
It should continuously print out coordinates of where the IR lights are, along with a simple 3 dot image. Instead I get this.
pi#raspberrypi:~/Desktop $ python SeniorDesign_Test.py
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1550, in __call__
return self.func(*args)
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 599, in callit
func(*args)
File "SeniorDesign_Test.py", line 15, in update_Image
camera.getPositions() #Update with new IR objects
File "/home/pi/Desktop/SeniorDesign_IRcam.py", line 23, in getPositions
data = self.device.read_i2c_block_data(self.sensorAddress, 0x36, 16) # Read the data from the I2C bus
IOError: [Errno 121] Remote I/O error

Related

VHDL: assign new value to the specific element of 2D Array

I want to copy the Average Variable value to the specific location of 2d Array. For this code it is array_new_signal11(3,2).
Can anyone guide me how can I do this? This code gives me error while simulation.
architecture Behavioral of Correction is
type array_new is array (0 to 4, 0 to 4) of integer;
signal array_new_signal: array_new;
begin
array_new_signal11 <= ((1,2,3,4,5),
(4,5,6,7,8),
(7,8,9,0,1),
(1,3,6,5,9),
(2,3,5,4,5));
Process(kelvin)
variable Sum1: integer:= 0;
Variable Sum2: integer:= 0;
Variable Total_Sum: integer:= 0;
Variable Average: integer:= 0;
begin
for Row in 0 to 4 loop
for Column in 0 to 4 loop
if(Row = 1 and Column = 1) then
for Column in 1 to 3 loop
sum1 := array_new_signal11(Row, Column) + Sum1;
end loop;
end if;
if(Row = 2 and Column = 1) then
for Column in 1 to 3 loop
sum2 := array_new_signal11(Row, Column) + Sum2;
end loop;
end if;
end loop;
end loop;
Total_Sum := Sum1 + Sum2;
Average := Total_Sum / 8;
**array_new_signal11(3,2) <= Average;**
end Process;
end Behavioral;
Constructing a Minimal, Complete and Verifiable example from the question:
entity correction is
end correction;
architecture behavioral of correction is
type array_new is array (0 to 4, 0 to 4) of integer;
signal array_new_signal11: array_new := ((1,2,3,4,5),
(4,5,6,7,8),
(7,8,9,0,1),
(1,3,6,5,9),
(2,3,5,4,5));
signal kelvin: boolean;
begin
-- array_new_signal11 <= ((1,2,3,4,5),
-- (4,5,6,7,8),
-- (7,8,9,0,1),
-- (1,3,6,5,9),
-- (2,3,5,4,5));
process (kelvin)
variable sum1: integer:= 0;
variable sum2: integer:= 0;
variable total_sum: integer:= 0;
variable average: integer:= 0;
begin
for row in 0 to 4 loop
for column in 0 to 4 loop
if row = 1 and column = 1 then
for column in 1 to 3 loop
sum1 := array_new_signal11(row, column) + sum1;
end loop;
end if;
if row = 2 and column = 1 then
for column in 1 to 3 loop
sum2 := array_new_signal11(row, column) + sum2;
end loop;
end if;
end loop;
end loop;
total_sum := sum1 + sum2;
average := total_sum / 8;
report "sum1 = " & integer'image(sum1) & ", " &
"sum2 = " & integer'image(sum2) & ", " &
"average = " & integer'image(average);
array_new_signal11(3,2) <= average;
end process;
MONITOR_PROCESS:
process
begin
wait on array_new_signal11;
for row in 0 to 4 loop
report "row" & integer'image(row) & " = " &
integer'image(array_new_signal11(row,0)) & ", " &
integer'image(array_new_signal11(row,1)) & ", " &
integer'image(array_new_signal11(row,2)) & ", " &
integer'image(array_new_signal11(row,3)) & ", " &
integer'image(array_new_signal11(row,4));
end loop;
end process;
end behavioral;
We see the report statements tell us the average and report the new array values.
We see the Row 3 Column 2 was initialized to 6 and is now 4:
ghdl -a correction.vhdl
ghdl -e correction
ghdl -r correction
correction.vhdl:42:7:#0ms:(report note): sum1 = 18, sum2 = 17, average = 4
correction.vhdl:52:13:#0ms:(report note): row0 = 1, 2, 3, 4, 5
correction.vhdl:52:13:#0ms:(report note): row1 = 4, 5, 6, 7, 8
correction.vhdl:52:13:#0ms:(report note): row2 = 7, 8, 9, 0, 1
correction.vhdl:52:13:#0ms:(report note): row3 = 1, 3, 4, 5, 9
correction.vhdl:52:13:#0ms:(report note): row4 = 2, 3, 5, 4, 5
as specified by the value of average.
As Renaud Pacalet notes you have two different processes driving array_new_signal11, which is not legal in VHDL, as it's element type integer is not a resolved data type.
The solution is to initialize the array in this case where it's declared.
Otherwise every assignment to an element of array signal must be in the same process. The concurrent signal assignment you had will be elaborated to an equivalent process statement and generate an error when elaborated as it was originally shown:
ghdl -r correction
for signal: .correction(behavioral).array_new_signal11(3,2)
./correction:error: several sources for unresolved signal
./correction:error: error during elaboration
(For the ghdl simulator part of elaboration (which consists of linking and loading) is done when invoking simulation (the -r command, the loading part, where the design network is created)).
Renaud Pacalet suggests assigning the array value inside the process, but without an intervening wait statement the values are not available for subsequent use in the same simulation cycle. The new signal values are not available in the same simulation cycle they are assigned.
Each signal assignment schedules a waveform update and only one entry for a particular simulation time is available. In this case it would guarantee array(3, 2) would be the average of eight values of integer'left (which would be incorrect, you should get errors causing simulation to end during the accumulation of sum1 in the unlabelled 3rd loop statement first loop iteration).
And that tells us you need the array initialized before being read.
The only reason the above example succeeds is that there are no array elements when added together won't violate the value range of type integer with the values you specified.
You can get around this sort of thing by using binary array equivalents of integers and paying attention to the needed accuracy.
There are several morals to this story. First, VHDL isn't a programming language, second it's strongly typed and third signals assignment values are never visible in the simulation cycle they are made in.
Note that kelvin has been added as boolean signal to trigger execution of the process once without changing it.
You are trying to drive the array_new_signal11 signal from two different processes. Yes, your first concurrent signal assignment:
array_new_signal11 <= ((1,2,3,4,5),
(4,5,6,7,8),
(7,8,9,0,1),
(1,3,6,5,9),
(2,3,5,4,5));
is a shorthand for a process. It models a hardware driver that continuously imposes these values to your array signal (which is just a bunch of wires, at the end).
Your second process also tries to impose a value to one cell of your array (cell array_new_signal11(3,2)). In electrical engineering, this situation is called a short-circuit: what would you expect when the two drivers disagree? This is also the reason why your simulator refuses this: it does not know what to do with this signal.
Solution: drive this signal from one single process:
process(kelvin)
...
begin
array_new_signal11 <= (
(1,2,3,4,5),
(4,5,6,7,8),
...
for Row in 0 to 4 loop
...
end process;
Notes:
Average being a variable you should have another error on:
Average <= Total_Sum / 8;
which should be:
Average := Total_Sum / 8;
You are using the same loop index (Column) in two nested loops. Not sure what you are trying to do but this is not very safe.
Even with my suggestion to fix your error you will hit another problem: the array_new_signal11 is both an input (you read it) and an output (you assign it) of your process. It should thus also be listed in the sensitivity list. In electrical engineering this is called a combinatorial loop and is usually highly undesirable, except if you want to create an oscillator or a kind of random generator.
Your process is sensitive to signal Kelvin but does not use it. Strange situation. Do you have a clear idea of what hardware you are trying to model?
You probably believe that your process variables are re-initialized to 0 each time the process resumes (that is, each time Kelvin changes). This is not the case: they retain the last value they were assigned. Probably not what you want. You should initialize them at the beginning of your process body.

How to do a bubble sort in Occam

I am trying to program in occam, and I think that it is not so easy to understand because the documentation is not so good. Anyway, I hope someone to help me.
I am trying just to learn how make a simple program. A bubble sort in occam.
#INCLUDE "course.module"
[32]INT x:
INT aux:
BOOL flag:
flag:= TRUE
aux:=0
--put values on the array
SEQ k=0 for 10
x[i] = -x[i]
-- bubble sort
WHILE (flag)
SEQ i = 0 for 9
IF
x[i] > x[i+1]
aux:= x[i]
x[i]:= x[i+1]
x[i+1] := aux
flag:= false
:
I got this image on the terminal:
What is wrong with this code?
occam-pi is indentation sensitive
A few hints in the code may help and courtesy of TiO-IDE may provide a place for online experimentation:
#INCLUDE "course.module"
PROC main( CHAN BYTE keyboard, screen, error )
[32]INT x:
INT aux:
BOOL flag:
SEQ -- ------------------------- BoSEQ:
SEQ i = 0 FOR 31 -- SEQ used as <-an-iterator->
x[i] := i -- put values on the array
SEQ i = 0 FOR 10 -- SEQ used as <-an-iterator->
x[i] := -x[i] -- put values on the array
flag := TRUE
WHILE ( flag ) -- WHILE
SEQ -- SEQ as a bubble sort
SEQ i = 0 FOR 10 -- SEQ used as <-an-iterator->
IF -- IF
x[i] > x[i+1] -- CASE: x[i] > x[i+1]
SEQ -- SEQ of steps
aux := x[i] -- 1
x[i] := x[i+1] -- 2
x[i+1] := aux -- 3
-- -- -- -- -- -- -- -- -- -- -- -- -- --
-- INTERESTING [occam-pi] FEATURE IS, THAT
-- [occam-pi] CAN _SWAP_ IN-PLACE
-- USING JUST x[i], x[i+1] := x[i+1], x[i]
TRUE -- OTHERWISE:
SKIP
-- SEQ used above as <-an-iterator-> got exhausted
flag := FALSE -- SET FALSE
-- ----------------------------- EoSEQ:
: -- main()

Please help me with the syntax errors in the following vhdl code that i wrote

I used Xlinix ISE 14.1 to write the following code.
I found the syntax to be correct but the xilinx IDE shows errors at line 27 and 30.
I am trying to find the first partial derivatives of a matrix of numbers which is similar to finding the edges in an image.
The function by2i is used to convert the bytes (i.e. bits) to integer number.
In this VHDL code I am getting error messages:
"ERROR:HDLCompiler:806 B:/gxgyVHDL.vhd" Line 27: Syntax error near "return".
"ERROR:HDLCompiler:806 - "B:/gxgyVHDL.vhd" Line 30: Syntax error near ","".
I am unable to correct these errors as I know very little in VHDL. I learned basic programming in VHDL like implementing MUX, counters etc.
This is the first time I am writing a program for image processing And I'm not sure whether this program works like expected but it works well matlab and python.
Please help to correct these errors.
Here is vhdl code:
enter code here
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.numeric_std.ALL;
use IEEE.math_real.ALL;
entity getGxGy is
generic (width : natural := 66;
height : natural := 130); --width and height of the image window.
Port( pxl : in STD_LOGIC_VECTOR(7 downto 0);
clk : in bit;
fv : out real); --need to configure 'fv' signal properly to appropriate bit vector.
end getHOGfv;
architecture behave of getGxGy is
function by2i (b : STD_LOGIC_VECTOR(7 downto 0)) return natural is
variable num : natural;
begin
num := 0;
for i in b'Range loop
if b(i) = '1' then
num := num + 2**i;
end if;
end loop
return num
end by2i;
type bufarr is array (1 to height, 1 to width) of natural;
type gxgy is array (1 to height-2, 1 to width-2) of integer;
--signal tempfv : mat4;
process(clk, pxl)
variable buf: bufarr;
variable gx, gy: gxgy;
begin
--Buffer to store/create 64*128 pixels/widthindowidth
for h in 2 to height-1 loop
for w in 2 to width-1 loop
buf(h)(w) := by2i(pxl);
end loop;
end loop;
--1pixel padding
for w in 1 to width loop
buf(1)(w) := 0;
end loop;
for w in 1 to width loop
buf(height)(w) := 0;
end loop;
for h in 2 to height-1 loop
buf(h)(1) := 0;
end loop;
for h in 2 to height-1 loop
buf(h)(width) := 0;
end loop;
--compute gradients
for h in 2 to height-1 loop
for w in 2 to width-1 loop
gx(h)(w) := buf(h+1)(w)-buf(h-1)(w);
gy(h)(w) := buf(h)(w+1)-buf(h)(w-1);
mag(h)(w) := abs(gx(h)(w)+gy(h)(w));
ang(h)(w) := gy(h)(w)/gx(h)(w);
end loop;
end loop;
end process;
end behave;
Several problems:
Your entity names do not match. That is, entity getGxGy does not match end getHOGfv;
You are missing a trailing ; on the end loop in by2i
You are missing a trailing ; on the return in by2i
You are missing a begin statement in your architecture (between the type gxgy and the process(clk, pxl)
Your syntax for the use of multidimensional arrays is wrong. Rather than buf(1)(w), it should be buf(1, 2).
Neither mag nor ang are defined.
When you have a large number of errors, it can be difficult to track down the exact cause. Often the compilers get confused at reporting the errors. Start with the first one, fix it, and re-compile. Continue until things cleanup.
Also, a point of clarification. You don't need by2i. You can use numeric_std to do the converstion (thanks to scary_jeff for pointing this out). Use to_integer(unsigned(pxl)) to do the conversion.
And one further point. Do not use both std_logic_unsigned and numeric_std at the same time. numeric_std is the standard way to use signed and unsigned numbers. std_logic_unsigned was a vendor specific extension that is not standard.
Edit: You used the following syntax to define your arrays:
type bufarr is array (1 to height, 1 to width) of natural;
This is fine. And as I noted above you have to use the buf(h, w) syntax. But you could define it differently, such as:
type width_array is array(1 to width) of natural;
type bufarr is array(1 to height) of width_array;
Which you could then index using buf(h)(w).
I prefer the former.
In addition to the syntax items and missing declarations noted by PlayDough there are two superfluous context clauses for packages numeric_std (which should not be mixed with the Synopsys arithmetic pages std_logic_unsigned) and math_real (which isn't yet used).
After all the changes are edited in:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
-- use ieee.numeric_std.all;
-- use ieee.math_real.all;
entity getgxgy is
generic (width : natural := 66;
height : natural := 130); -- width and height of the image window.
port( pxl : in std_logic_vector(7 downto 0);
clk : in bit;
fv : out real); -- need to configure 'fv' signal properly to appropriate bit vector.
end getgxgy; -- WAS gethogfv;
architecture behave of getgxgy is
function by2i (b : std_logic_vector(7 downto 0)) return natural is
variable num : natural;
begin
num := 0;
for i in b'range loop
if b(i) = '1' then
num := num + 2 ** i;
end if;
end loop; -- MISSING ';'
return num; -- MISSING ';'
end function by2i;
type bufarr is array (1 to height, 1 to width) of natural;
type gxgy is array (1 to height - 2, 1 to width - 2) of integer;
--signal tempfv : mat4;
begin -- for architecture modiy WAS MISSING
process (clk, pxl)
variable buf: bufarr;
variable gx, gy: gxgy;
variable mag, ang: gxgy; -- MISSING DECLARATIONS
begin
--buffer to store/create 64*128 pixels/widthindowidth
for h in 2 to height - 1 loop
for w in 2 to width - 1 loop
buf(h, w) := by2i(pxl); -- WAS buf(h)(w)
end loop;
end loop;
--1pixel padding
for w in 1 to width loop
buf(1, w) := 0; -- WAS buf(1)(w)
end loop;
for w in 1 to width loop
buf(height, w) := 0; -- WAS buf(height)(w)
end loop;
for h in 2 to height - 1 loop
buf(h, 1) := 0; -- WAS buf(h)(1)
end loop;
for h in 2 to height - 1 loop
buf(h, width) := 0; -- WAS buf(h)(width)
end loop;
--compute gradients
for h in 2 to height - 1 loop
for w in 2 to width - 1 loop
gx(h, w) := buf(h + 1, w) - buf(h - 1, w); -- WAS gx(h)(w), buf(h+1)(w) and buf(h-1)(w)
gy(h, w) := buf(h, w + 1) - buf(h, w - 1); -- WAS gy(h)(w), buf(h)(w+1) and buf(h)(w-1)
mag(h, w) := abs(gx(h, w) + gy(h, w)); -- WAS mag(h)(w), x(h)(w) and gy(h)(w)
ang(h, w) := gy(h, w) / gx(h, w); --WAS ang(h)(w), gy(h)(w) and gx(h)(w)
end loop;
end loop;
end process;
end architecture behave;
your code analyzes and elaborates, noting there is no assignment to fv, type REAL is not synthesis eligible and there is no synthesis eligible use of clk.
If clk were std_logic (or std_ulogic) you could use the std_logic_1164 function rising_edge.
Adding a recognized sequential logic RTL construct for a clock edge gives:
process (clk) -- pxl NOT NEEDED , pxl)
variable buf: bufarr;
variable gx, gy: gxgy;
variable mag, ang: gxgy; -- MISSING DECLARATIONS
begin
if clk'event and clk = '1' then
--buffer to store/create 64*128 pixels/widthindowidth
for h in 2 to height - 1 loop
for w in 2 to width - 1 loop
buf(h, w) := conv_integer(pxl); -- WAS buf(h)(w)
end loop; -- CHANGED to use conv_integer
end loop;
--1pixel padding
for w in 1 to width loop
buf(1, w) := 0; -- WAS buf(1)(w)
end loop;
for w in 1 to width loop
buf(height, w) := 0; -- WAS buf(height)(w)
end loop;
for h in 2 to height - 1 loop
buf(h, 1) := 0; -- WAS buf(h)(1)
end loop;
for h in 2 to height - 1 loop
buf(h, width) := 0; -- WAS buf(h)(width)
end loop;
--compute gradients
for h in 2 to height - 1 loop
for w in 2 to width - 1 loop
gx(h, w) := buf(h + 1, w) - buf(h - 1, w); -- WAS gx(h)(w), buf(h+1)(w) and buf(h-1)(w)
gy(h, w) := buf(h, w + 1) - buf(h, w - 1); -- WAS gy(h)(w), buf(h)(w+1) and buf(h)(w-1)
mag(h, w) := abs(gx(h, w) + gy(h, w)); -- WAS mag(h)(w), x(h)(w) and gy(h)(w)
ang(h, w) := gy(h, w) / gx(h, w); --WAS ang(h)(w), gy(h)(w) and gx(h)(w)
end loop;
end loop;
end if;
end process;
also noting the switch to the package std_logic_unsigned function conv_integer from using function by2i.
So these changes along with deleting the function by2i analyzes.
Genning up a testbench to look for bounds errors:
library ieee;
use ieee.std_logic_1164.all;
entity getgxgy_tb is
end entity;
architecture foo of getgxgy_tb is
signal pxl: std_logic_vector(7 downto 0) := (others => '0');
signal clk: bit;
signal fv: real;
begin
DUT:
entity work.getgxgy
port map (
pxl => pxl,
clk => clk,
fv => fv
);
CLOCK:
process
begin
wait for 10 ns;
clk <= not clk;
if now > 120 ns then
wait;
end if;
end process;
end architecture;
And we elaborate and run the testbench and get a run time error!
The error is division by zero in the assignment to ang, so your algorithm needs a bit of work still.
Blocking that with an if statement and we find there's a bounds error in the assignment:
gx(h, w) := buf(h + 1, w) - buf(h - 1, w); -- WAS gx(h)(w), buf(h+1)(w) and buf(h-1)(w)
And that's caused by hitting w = 65 when
type gxgy is array (1 to height - 2, 1 to width - 2) of integer;
type gxgy's second dimension corresponding to w has a range to width - 2 while w reaches width - 1 which is out of bounds.
So a bit more algorithmic expression tuning still to do.
It isn't particularly clear what you intend to register. If it's just fv that could occur in a different process, with the current processes sensitivity list set to just pxl and gx, gy, mag and ang made into signals.
It's likely that all the abs, multiplies and divides may not fit in a target FPGA, requiring operations be spread over some number of clocks using common resources for arithmetic operations. VHDL describes hardware and every operator invocation or function call can imply it's own hardware.
In synthesis a loop statement has it's sequence of statements 'unrolled' and where no interdependencies are found produce separate hardware. For h in 2 to height - 1 and w in 2 to width - 1 ranges in your nested loops your generic values are implying 8001 subtracts for each of gx and gy, abs and addition for mag and divides for ang, all from changing the value of pxl. This tells us your hardware isn't going to fit in any FPGA without sharing resources over some number of clocks, a time and space tradeoff.
So not only does your algorithm need a bit work, you need to take implementation resources into account.
You don't program in VHDL you describe hardware.

Verilog Code:FIR Filter= RAM modeling for reading coefficients values from file .. not showing simulation results

In verilog for only this line of code its showing simulation output
1)
#( parameter width=1, length=16 )
(* ram_style = "block" *)
reg [(width)-1:0] mem[(1<<length)-1:0];
2)but for the below line it is not showing simulation output
#( parameter width=8, length=16 )
(* ram_style = "block" *)
reg [(2*width)-1:0] mem[(1<<length)-1:0];
Explain why 2nd set of code is not showing simulation results?
actually I want store 8 bits of min 65535 filter coefficients.. I want to read and write ..
please guide me in this...
A model of a RAM might look some thing like the code below, to write to it it is just a mater of sequencing the wr_addr, wr_data and wr_en.
module ram #(
parameter DATA_W = 8,
parameter DATA_D = 256
) (
input clk,
input rst_an,
input [0:$clog2(DATA_D)] rd_addr,
input [0:$clog2(DATA_D)] wr_addr,
input [0:DATA_W-1] wr_data,
input wr_en,
output [0:DATA_W-1] rd_data
);
reg [0:DATA_W-1] ram_data [0:DATA_D-1];
//READ
always #* begin
rd_data = ram_data[rd_addr];
end
//WRITE
always #(posedge clk, negedge rst_an) begin
if (~rst_an) begin
for(int i = 0; i<DATA_D ; i++) begin
ram_data[i] <= 'b0 ;
end
end
else begin
if (wr_en) begin
ram_data[wr_addr] <= wr_data ;
end
end
end
for(int i = 0; i<DATA_D ; i++) is system verilog syntax.
for plain verilog declare integer i then replace the for loop with :
for(i = 0; i<DATA_D ; i=1+1)
clog2 : is used to get the address width required for the given depth.
If you want a depth of 4, you need 2 bits to address it. Depth of 16, 4 bits to address, ie
log2( 4) => 2
log2(16) => 4
If you use non-powers of two you want to round up or ceiling
log2(5) => 2.32192809489
clog2(5) => 3
Therefore clog2 is very useful to get the required addressing width from the depth of the RAM.

port size does not match connection size

I have this code:
Alu.v
module ALU(
src1_i,
src2_i,
src3_i,
src4_i,
ctrl_i,
result_o,
zero_o
);
//I/O ports
input [32-1:0] src1_i;
input [32-1:0] src2_i;
input [4-1:0] src3_i;//shmat is 5 bits instruction[10:6]
input [15-1:0] src4_i;//ori have to deal with 'zero-extended' number
input [4-1:0] ctrl_i;
output [32-1:0] result_o;
output zero_o;
//Internal signals
reg [32-1:0] result_o;
wire zero_o;
//Parameter
assign zero_o = (result_o == 0);
//Main function
always #(*) begin
case(ctrl_i)
0 :result_o <= src1_i & src2_i;//and
1 :result_o <= src1_i | src2_i;//or
2 :result_o <= src1_i + src2_i;//add
6 :result_o <= src1_i - src2_i;//substract
7 :result_o <= src1_i < src2_i ? 1 : 0;//set less than
10:result_o <= ~(src1_i - src2_i);//not the result for bne
11:result_o <= (src1_i | {16'b0000000000000000, src4_i});//ori
12:result_o <= ~(src1_i | src2_i);//nor
13:result_o <= src2_i << 16;//lui
14:result_o <= src2_i << src1_i;//sllv
15:result_o <= src2_i << src3_i;//sll
default:result_o <= 0;//default
endcase
end
endmodule
And in the other module:
Simple_Single_CPU.v
.....
ALU ALU(
.src1_i(RSdata_o),
.src2_i(reg_mux_data_o),
.src3_i(instr_o[10:6]),
.src4_i(instr_o[15:0]),
.ctrl_i(ALUCtrl_o),
.result_o(result_o),
.zero_o(zero_o)
);
I have checked that the port size and connection port size is right, but it gives me these warnings:
# ** Warning: (vsim-3015) C:/Users/lypan/Downloads/Lab2/Lab2/code/Simple_Single_CPU.v(116): [PCDPC] - Port size (4 or 4) does not match connection size (5) for port 'src3_i'. The port definition is at: C:/Users/lypan/Downloads/Lab2/Lab2/code/ALU.v(15).
#
# Region: /TestBench/cpu/ALU
# ** Warning: (vsim-3015) C:/Users/lypan/Downloads/Lab2/Lab2/code/Simple_Single_CPU.v(116): [PCDPC] - Port size (15 or 15) does not match connection size (16) for port 'src4_i'. The port definition is at: C:/Users/lypan/Downloads/Lab2/Lab2/code/ALU.v(16).
#
# Region: /TestBench/cpu/ALU
How can I fix the warnings?
The warning is correct.
In module ALU, you have this declaration:
input [4-1:0] src3_i;//shmat is 5 bits instruction[10:6]
This sets the width of src3_i to 4 because 4-1=3, and 3:0 is 4 bits.
But, in Simple_Single_CPU.v, you have:
.src3_i(instr_o[10:6]),
This connects a 5-bit signal (instr_o[10:6]) to a 4-bit port (src3_i).
You must decide whether the signal should really be 4 bits or 5 bits. For example, if you want 5 bits, use:
input [5-1:0] src3_i;//shmat is 5 bits instruction[10:6]

Resources