Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
20704 Discussions

How to measure distance between two data

Altera_Forum
Honored Contributor II
12,711 Views

really i have a problem for measure the distance between these data as the following.could i can make it in vhdl from enter this data to vhdl to measure distance between them. 

d(s1,s2)=(1+1+0+1+1)/(n^2/2)=4/12=0.33333
0 Kudos
51 Replies
Altera_Forum
Honored Contributor II
1,666 Views

do you really calculate square root in HDL? 

 

I recommend you to use NiosII CPU ( or other CPU ) 

and get result in software ( like C-language ). 

 

but, you insist to get result in HDL. 

there is IP-core such as ALTFP_SQRT ( and other floating-point functions ). 

 

both way are tough for newbie. 

 

let study.
0 Kudos
Altera_Forum
Honored Contributor II
1,666 Views

hi akira 

thanks for reply 

first i want to know how to create table using vhdl,then calculate the distance between the position of each element in s1 and the position of the same element in s2 then find normalized distance
0 Kudos
Altera_Forum
Honored Contributor II
1,666 Views

by distance you mean d(s1,s2) as per equation given. But what does this equation mean? what is n^2/2 = 12 ?? and what does 1+1+0+1+1 mean

0 Kudos
Altera_Forum
Honored Contributor II
1,666 Views

you can create onchip(or external)RAM. 

 

and you can create ram -initializ like following (this is verilog-HDL sorry) 

 

//////////////////////////////////////////////////////////////////////////////////////////////// 

reg [WORD_WIDTH-1:0]pattern_rom[0:2**ADDR_WIDTH]; 

initial $readmemh( "ROM_HEX_FILE.txt",pattern_rom); 

reg [WORD_WIDTH-1:0]outbuff; 

always @ ( posedge csi_clk ) 

begin 

outbuff <= pattern_rom[reg_read_addr]; 

end 

assign wir_read_data = outbuff; 

//////////////////////////////////////////////////////////////////////////////////////////////// 

 

ROM_HEX_FILE.txt is initial data of pattern_rom. 

 

anyway, there is a way you can create table. 

but I am not sure you really have big enough memory on your FPGA.
0 Kudos
Altera_Forum
Honored Contributor II
1,666 Views

d(s1,s2) is the distance between the position of each element in s1 and the position of the same element in s2  

which is 1+1+0+1+1=4 then divided by (n^2-1)/2 where n is the number of elements in table  

 

sorry for not clear at first. i want to make a vhdl code for that 

so i need help
0 Kudos
Altera_Forum
Honored Contributor II
1,666 Views

 

--- Quote Start ---  

d(s1,s2) is the distance between the position of each element in s1 and the position of the same element in s2  

which is 1+1+0+1+1=4 then divided by (n^2-1)/2 where n is the number of elements in table  

 

sorry for not clear at first. i want to make a vhdl code for that 

so i need help 

--- Quote End ---  

 

 

So in the given case you have the given distances as 1+1+0+1+1 (n = 5) so distance = 1+1+0+1+1 = 4 then normalised to 5^2-1/2 i.e. /12 

=.333 

 

is n constant 5 always. How do you get the positions of 1,1,0,1,1? are these five inputs? 

 

Once you are clear about the requirement then you can go for coding.
0 Kudos
Altera_Forum
Honored Contributor II
1,666 Views

first n is not constant it depend on table element which is definitely changed . 

second , the position of each element corresponding to the same element in the other table  

i wrote a code put didn't know ,is it right? give a code for every element in table  

library IEEE; 

use IEEE.STD_LOGIC_1164.all; 

 

package profile_A is 

 

type A1 is array (0 to 4) of std_logic_vector( 23 downto 0); 

 

constant table1:A1:= ("011010010110001101100001","011011010110010101110010", 

"011000010110110101100101","011100100110100101100100","011001010111001001101001"); 

 

type A2 is array (0 to 4) of std_logic_vector( 23 downto 0); 

constant table2:A2:= ("011011010110010101110010","011010010110001101100001", 

"011000010110110101100101","011001010111001001101001","011100100110100101100100"); 

 

end profile_A; 

 

---------------------------------------------------------------------------- 

library IEEE; 

use IEEE.STD_LOGIC_1164.ALL; 

use IEEE.STD_LOGIC_ARITH.ALL; 

use IEEE.STD_LOGIC_UNSIGNED.ALL; 

use work.profile_A.all; 

 

entity samples is 

port ( s1:in A1; 

s2: in A2; 

clk:in bit; 

distance:out integer); 

end samples; 

 

architecture Behavioral of samples is 

signal d :integer ; 

 

begin 

process(clk,s1,s2) 

begin  

for idx in 0 to s1'length loop 

if (clk='1'or clk'event) then 

if s1(idx)=s2(idx)then  

d <= idx-1; 

end if; 

end if; 

end loop; 

 

end process; 

end Behavioral;
0 Kudos
Altera_Forum
Honored Contributor II
1,666 Views

Judging from your code you assume S1/S2 are inputs each 24 bits. However I doubt it. 

More likely you enter (n) elements each 24 bits wide into two rom tables (e.g. from a file). 

Once you have these two roms then you read rom1 output and check each output against rom2 output until you find a match then the distance is 

address2 - address1 then you perform your computation circuitry of adding all results * (n^2-1)/2 

 

The divide by 2 is easiest(just discard 1 LSB from final result). 

for n^2-1 use multiplier subtractor directly(multiply n * n) then subtract 1 

for final division you will need a divider
0 Kudos
Altera_Forum
Honored Contributor II
1,666 Views

thanks kaz , y really helped me 

first i tried to make vhdl code for dual port ram because i will compare between two samples ..is it right thing???  

but i have a problem when i tray to test the test bench is (all generics must take a default value) here is code i need your help... 

library ieee; 

use ieee.std_logic_1164.all; 

use ieee.std_logic_unsigned.all; 

 

entity bram_tdp is 

generic ( 

DATA : std_logic_vector (0 to 6) ; 

ADDR : std_logic_vector (0 to 6)); 

port ( 

-- Port A 

a_clk : in std_logic; 

a_wr : in std_logic; 

a_addr : in std_logic_vector(6 downto 0); 

a_din : in std_logic_vector(6 downto 0); 

a_dout : out std_logic_vector(6 downto 0); 

 

-- Port B 

b_clk : in std_logic; 

b_wr : in std_logic; 

b_addr : in std_logic_vector(6 downto 0); 

b_din : in std_logic_vector(6 downto 0); 

b_dout : out std_logic_vector(6 downto 0) 

); 

end bram_tdp; 

 

architecture rtl of bram_tdp is 

-- Shared memory 

type mem_type is array ( 6 downto 0 ) of std_logic_vector(6 downto 0); 

shared variable mem : mem_type; 

begin 

 

-- Port A 

process(a_clk) 

begin 

if(a_clk'event and a_clk='1') then 

if(a_wr='1') then 

mem(conv_integer(a_addr)) := a_din; 

end if; 

a_dout <= mem(conv_integer(a_addr)); 

end if; 

end process; 

 

-- Port B 

process(b_clk) 

begin 

if(b_clk'event and b_clk='1') then 

if(b_wr='1') then 

mem(conv_integer(b_addr)) := b_din; 

end if; 

b_dout <= mem(conv_integer(b_addr)); 

end if; 

end process; 

 

end rtl;
0 Kudos
Altera_Forum
Honored Contributor II
1,666 Views

sorry ,,, i found it  

i should change  

DATA : std_logic_vector (0 to 6) ; 

ADDR : std_logic_vector (0 to 6)) 

to 

DATA : integer :=7 ; 

ADDR : integer :=7; 

but i ask you if i can enter data as in the table i mean word (asd,sdf,rto....etc) 

and is it right to use dual port ram 

thanks a lot
0 Kudos
Altera_Forum
Honored Contributor II
1,666 Views

Let me suggest an easier way. 

assume S1,S2 are inputs (8 bits wide each). Use two shift registers with (n) stages. Let the data S1,S2 shift through till the end and freeze the shift register then you can compare each value with others for equality and distance becomes index difference. For example if s1_shift(0) = s2_shift(3) then distance is 3-0 = 3 and so on. 

 

To code for shift register do this in a clocked process. 

s1_shift(0) <= s1; for i in 1 to n-1 loop -- n declared somewhere s1_shift(i) <= s1_shift(i-1); end loop;  

 

the code for checking equality can also be done in a loop to check say index(0) of s1 with indices 0 to n-1 of s2 then index(1) of s1 with indices 0 to n-1 of s2 and so on.
0 Kudos
Altera_Forum
Honored Contributor II
1,666 Views

Regarding those strings like asd,sdf etc. what is't and what does your tables actually mean  

for example MER is 255 in table1 and is 215 in table2 then you look for MER (not the number next to it), what is it, are you clear about it, I am not
0 Kudos
Altera_Forum
Honored Contributor II
1,666 Views

OK .... actually this table is some samples taken from user A represent in trigraphs from any text he wrote and digit behind it be the time he take to type those trigraphs such as ( acs--125 ms, asd--200 ms ........) build a sorted table1(S1) ,(sorted according to the time), consists of these data and table2 (S2) of the same trigraphs  

compare between these samples and found the distance between the same trigraphs from the two samples i should make it in vhdl code , but you make me in doubt what i use ram or registers. 

regarding you code about register how i can find index in vhdl code.
0 Kudos
Altera_Forum
Honored Contributor II
1,666 Views

 

--- Quote Start ---  

 

regarding you code about register how i can find index in vhdl code. 

--- Quote End ---  

 

 

The index of register would be the loop 

for i in 0 to n-1 loop for j in 0 to n-1 loop if s1_shift(i) = s2_shift(j) then d(i) <= j-i; end if; end loop; end loop;  

you will get d(0) ~ d(n-1) as distance then you compute it further 

you need to get the type conversion right and test the code idea.
0 Kudos
Altera_Forum
Honored Contributor II
1,666 Views

i can't do this code in memory like register 

i try but failed 

process(addr_a) 

begin 

for i in data_a'range loop 

for j in data_a'range loop 

if data_a(i) = data_b(j) then 

d <= addr_a - addr_b; 

end if ; 

distance <= d; 

end loop; 

end loop;
0 Kudos
Altera_Forum
Honored Contributor II
1,666 Views

 

--- Quote Start ---  

i can't do this code in memory like register 

i try but failed 

process(addr_a) 

begin 

for i in data_a'range loop 

for j in data_a'range loop 

if data_a(i) = data_b(j) then 

d <= addr_a - addr_b; 

end if ; 

distance <= d; 

end loop; 

end loop; 

--- Quote End ---  

 

 

The code I suggested was for shift register(not ram). even then you have to use d(i) not just d 

if you want to use ram then use two rams one for s1 and one for s2 then subtract addresses without the need for loop
0 Kudos
Altera_Forum
Honored Contributor II
1,666 Views

if you want to use ram then use two rams one for s1 and one for s2 then subtract addresses without the need for loop 

--- Quote End ---  

 

 

actually i use dual port ram for s1 and s2 and make this code 

if data_a = data_b then 

distance <= addr_a - addr_b; 

end if; 

the big problem is if and only if data_a = data_b at the same clock cycle not for all data index ,you understand me
0 Kudos
Altera_Forum
Honored Contributor II
1,666 Views

use two single port rams one for s1 and one for s2 then address subtraction applies. 

If you also want to write inputs to the rams then use two dual port rams again one for s1 rd/wr and one for s2 rd/wr. 

 

It really depends how you are going to get your inputs s1/s2 in the first place which you haven't told us yet.
0 Kudos
Altera_Forum
Honored Contributor II
1,666 Views

may i said in another way,when i tried to match between every element in mem1 with every element in mem2 such as 

if data_a=data_b then  

d<=addr_a - addr_b; 

it happened if data_a=data_ b in the same clock cycle not for all mem data i/p
0 Kudos
Altera_Forum
Honored Contributor II
1,555 Views

how can i make the match between the two rams. 

i search but not found any thing help me
0 Kudos
Reply