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

How to measure distance between two data

Altera_Forum
Honored Contributor II
13,715 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,077 Views

 

--- Quote Start ---  

how can i make the match between the two rams. 

i search but not found any thing help me 

--- Quote End ---  

 

read address 0 of ram1, save it, then all addresses of ram2 till a match occurs then distance is address2 - 0 

then read address 1 of ram1, then all addresses of ram2 until a match occurs then distance is address2 - 1 and so on. 

(assuming you don't copy contents to registers)
0 Kudos
Altera_Forum
Honored Contributor II
1,077 Views

sorry, kaz 

i tried many times by many ways but it can't be solved  

what is the mistake,and what is the correct way 

 

 

 

library ieee; 

use ieee.std_logic_1164.all; 

use ieee.std_logic_unsigned.all; 

use IEEE.numeric_std.all; 

 

 

entity true_dpram_sclk is 

port  

(  

data_a : in std_logic_vector(7 downto 0); 

data_b : in std_logic_vector(7 downto 0); 

addr_a : in std_logic_vector(7 downto 0); 

addr_b : in std_logic_vector(7 downto 0); 

we_a : in std_logic := '1'; 

we_b : in std_logic := '1'; 

clk : in std_logic; 

q_a : out std_logic_vector(7 downto 0); 

q_b : out std_logic_vector(7 downto 0); 

distance: out std_logic_vector(7 downto 0) 

); 

 

end true_dpram_sclk; 

 

architecture rtl of true_dpram_sclk is 

 

-- Build a 2-D array type for the RAM 

subtype word_t is std_logic_vector(7 downto 0); 

type memory_t is array(63 downto 0) of word_t; 

 

-- Declare the RAM 

shared variable ram : memory_t; 

signal a_output:std_logic_vector(7 downto 0 ); 

signal b_output:std_logic_vector(7 downto 0); 

signal d :std_logic_vector(0 to 7); 

begin 

 

-- Port A 

process(clk) 

begin 

if(rising_edge(clk)) then  

if(we_a = '1') then 

ram(conv_integer (addr_a)) := data_a; 

end if; 

a_output <= ram(conv_integer (addr_a)); 

end if; 

q_a <= a_output; 

end process; 

 

-- Port B 

process(clk) 

begin 

if(rising_edge(clk)) then 

if(we_b = '1') then 

ram(conv_integer (addr_b)) := data_b; 

end if; 

b_output <= ram(conv_integer (addr_b)); 

end if; 

q_b <= b_output; 

 

if (std_match(a_output(0),b_output(0) )) then 

d<= std_logic_vector(signed(addr_a(0))- signed (addr_b(0))); -----error The expression can not be converted to type signed. 

 

end if; 

distance <= d; 

 

 

 

end process; 

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

I have corrected your code. see below 

However you need to read each ram separately and you need distance to be output successively as a stream. 

i.e. you need to read location 0 first and keep it till all locations of ram2 are checked and so on. 

currently you are just reading on write address. 

 

you also need address to be converted to signed adding sign bit... 

 

library ieee; use ieee.std_logic_1164.all; --use ieee.std_logic_unsigned.all; use IEEE.numeric_std.all; entity test is port ( data_a : in std_logic_vector(7 downto 0); data_b : in std_logic_vector(7 downto 0); addr_a : in std_logic_vector(7 downto 0); addr_b : in std_logic_vector(7 downto 0); we_a : in std_logic := '1'; we_b : in std_logic := '1'; clk : in std_logic; q_a : out std_logic_vector(7 downto 0); q_b : out std_logic_vector(7 downto 0); distance : out std_logic_vector(7 downto 0) ); end test; architecture rtl of test is type memory_t is array(63 downto 0) of std_logic_vector(7 downto 0); signal ram1, ram2 : memory_t; signal q_a_int : std_logic_vector(7 downto 0); signal q_b_int : std_logic_vector(7 downto 0); begin -- Port A process(clk) begin if(rising_edge(clk)) then if(we_a = '1') then ram1(to_integer(unsigned(addr_a))) <= data_a; end if; q_a_int <= ram1(to_integer(unsigned(addr_a))); end if; end process; -- Port B process(clk) begin if(rising_edge(clk)) then if(we_b = '1') then ram2(to_integer(unsigned(addr_b))) <= data_b; end if; q_b_int <= ram2(to_integer(unsigned(addr_b))); end if; end process; process(clk) begin if(rising_edge(clk)) then if (std_match(q_a_int,q_b_int)) then distance <= std_logic_vector(unsigned(addr_a)- unsigned (addr_b)); end if; end if; end process; q_a <= q_a_int; q_b <= q_b_int; end rtl;
0 Kudos
Altera_Forum
Honored Contributor II
1,077 Views

---However you need to read each ram separately  

i correct the code to read from each ram,does it is correct?? 

--and you need distance to be output successively as a stream. 

how i can do that?? 

--- you need to read location 0 first and keep it till all locations of ram2 are checked and so on. 

may i can do that by using function ''='' for equality or std_match (i try to do that) , but it is the correct way?? 

in the code below 

library ieee; 

use ieee.std_logic_1164.all; 

--use ieee.std_logic_unsigned.all; 

use IEEE.numeric_std.all; 

 

 

entity test is 

port 

data_a : in std_logic_vector(7 downto 0); 

data_b : in std_logic_vector(7 downto 0); 

addr_a : in std_logic_vector(7 downto 0); 

addr_b : in std_logic_vector(7 downto 0); 

we_a : in std_logic := '1'; 

we_b : in std_logic := '1'; 

clk : in std_logic; 

Re_a :in std_logic := '1'; 

Re_b :in std_logic := '1'; 

q_a : out std_logic_vector(7 downto 0); 

q_b : out std_logic_vector(7 downto 0); 

distance : out std_logic_vector(7 downto 0) 

); 

 

end test; 

 

architecture rtl of test is 

 

type memory_t is array(63 downto 0) of std_logic_vector(7 downto 0); 

signal ram1, ram2 : memory_t; 

signal read_addr_a : std_logic_vector(7 downto 0); 

signal read_addr_b : std_logic_vector(7 downto 0); 

signal q_a_int : std_logic_vector(7 downto 0); 

signal q_b_int : std_logic_vector(7 downto 0); 

 

begin 

 

-- Port A 

----write to port A 

process(clk) 

begin 

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

if(we_a = '1') then 

ram1(to_integer(unsigned(addr_a))) <= data_a; 

end if; 

read_addr_a <= addr_a; 

end if; 

end process; 

---read from port A 

process(clk,Re_a) 

begin 

if (Re_a ='1') then 

q_a_int <= ram1(to_integer(unsigned(read_addr_a))); 

end if; 

end process; 

 

 

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

-- Port B 

--write to port B 

process(clk) 

begin 

if(rising_edge(clk)) then 

if(we_b = '1') then 

ram2(to_integer(unsigned(addr_b))) <= data_b; 

end if; 

read_addr_b <= addr_b; 

end if; 

end process; 

---read from port B 

process(clk,Re_b) 

begin 

if (Re_b = '1') then 

q_b_int <= ram2(to_integer(unsigned(read_addr_b))); 

end if; 

end process; 

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

process(clk) 

begin 

read_addr_a <= X"00"; --reset the address value for reading from memory location "0" 

process(clk) 

begin 

if(rising_edge(clk)) then 

if (std_match(q_a_int,q_b_int)) then 

distance <= std_logic_vector(unsigned(addr_a)- unsigned (addr_b));  

end if; 

end if; 

end process; 

 

q_a <= q_a_int; 

q_b <= q_b_int; 

 

end rtl; 

 

you also need address to be converted to signed adding sign bit.
0 Kudos
Altera_Forum
Honored Contributor II
1,077 Views

Ok you are getting there. Your read can be internal rather than inputs. 

 

I suggest state machine of s0,s1,s2 

s0: read ram1(address at 0) into ram1_data register, one clock,move to s1 

s1:read ram2(address 0~till equality) into ram2 register, several clocks, if equality found between ram1/ram2 data set ram2 address 

to zero, output (address difference), move to s2 

s2:set ram1 address to 1(increment),one clock, move to s0 

start again for ram1 address 1 and so on. 

 

by doing that you will output a stream of distance.  

Your design is no trivial and is good for practice.
0 Kudos
Altera_Forum
Honored Contributor II
1,077 Views

sorry kaz , could you help me to begin this state machine ,please  

really there is no body help me except you,so i will be thankful for you
0 Kudos
Altera_Forum
Honored Contributor II
1,077 Views

i should clearify some things . 

we will made mem1(consist of addresses for every data input ) i.e address from 1,2,3,4.... to end of the mem1 data input,ok  

mem2 (consist of addresses for every data input ) i.e address from 1,2,3,4.... t0 end of the mem2 data input,ok 

check if any of the data input from mem1 = any data input from mem2 .  

i.e the position of each element in mem1 and the position of the same element in mem2  

so the address to the same element will be different in the two mem 

the address difference will be the distance measure. 

thanks kaz ,i hope we finish this and help some others pepole at the same domine
0 Kudos
Altera_Forum
Honored Contributor II
1,077 Views

first you need to have a ram component. You can use inference as below or instantiate altera's ram 

it is simple dual (separate read addr/write addr) 

 

library ieee; use ieee.std_logic_1164.all; entity wr_rd_ram is port( clk : in std_logic; we : in std_logic; wr_data : in std_logic_vector(7 downto 0); wr_addr : in integer range 0 to 255; rd_addr : in integer range 0 to 255; rd_data : out std_logic_vector(7 downto 0) ); end entity; architecture rtl of wr_rd_ram is type mem is array(255 downto 0) of std_logic_vector(7 downto 0); signal ram : mem; begin process(clk) begin if(rising_edge(clk)) then if(we = '1') then ram(wr_addr) <= wr_data; end if; rd_data <= ram(rd_addr); end if; end process; end rtl;  

 

then top level can be something as below. This is not functionally accurate but should give you guidance. You need to simulate and 

adjust latency issues. 

 

library ieee; use ieee.std_logic_1164.all; entity test is port( rst : in std_logic; clk : in std_logic; we : in std_logic; wr_data1 : in std_logic_vector(7 downto 0); wr_data2 : in std_logic_vector(7 downto 0); wr_addr : in integer range 0 to 255; distance : out integer range 0 to 255; vout : out std_logic; no_match : out std_logic ); end entity; architecture rtl of test is signal rd_data1 : std_logic_vector(7 downto 0); signal rd_data2 : std_logic_vector(7 downto 0); signal rd_addr1 : integer range 0 to 255 := 0; signal rd_addr2 : integer range 0 to 255 := 0; type states is (s0,s1,s2); signal state: states; component wr_rd_ram port( clk : in std_logic; we : in std_logic; wr_data : in std_logic_vector(7 downto 0); wr_addr : in integer range 0 to 255; rd_addr : in integer range 0 to 255; rd_data : out std_logic_vector(7 downto 0) ); end component; begin ram1:wr_rd_ram port map( clk => clk, we => we, wr_data => wr_data1, wr_addr => wr_addr, rd_addr => rd_addr1, rd_data => rd_data1 ); ram2:wr_rd_ram port map( clk => clk, we => we, wr_data => wr_data2, wr_addr => wr_addr, rd_addr => rd_addr2, rd_data => rd_data2 ); process(rst,clk) begin if rst = '1' then state <= s0; vout <= '0'; no_match <= '0'; distance <= 0; elsif rising_edge(clk) then vout <= '0'; no_match <= '0'; case state is when s0 => rd_addr2 <= rd_addr2 + 1; if rd_data1 = rd_data2 then state <= s1; distance <= rd_addr1 - rd_addr2; vout <= '1'; elsif rd_addr2 = 255 then rd_addr2 <= 0; state <= s2; end if; when s1 => rd_addr1 <= rd_addr1 + 1; rd_addr2 <= 0; state <= s0; when s2 => no_match <= '1'; state <= s0; when others => null; end case; end if; end process; end rtl;
0 Kudos
Altera_Forum
Honored Contributor II
1,077 Views

rd_addr : in integer range 0 to 255;  

kaz,why rd_addr is input ,why isn't output such as rd_data
0 Kudos
Altera_Forum
Honored Contributor II
1,077 Views

and what is vout represent

0 Kudos
Altera_Forum
Honored Contributor II
1,077 Views

 

--- Quote Start ---  

rd_addr : in integer range 0 to 255;  

kaz,why rd_addr is input ,why isn't output such as rd_data 

--- Quote End ---  

 

 

we are talking here about RAM (not CAM) so any address is always input. Data can be either input(wr_data) or output(rd_data). 

 

vout(valid out) is a signal I added to flag that output is ready. 

 

so far you have been developing this design but without clear spec as what are your given inputs and what is your output format. 

I assume it is practice but you really should start from clear spec.
0 Kudos
Altera_Forum
Honored Contributor II
1,077 Views

i cam again , but with out any improvement in the state machine ,i try but it didn't give me the correct solution,i gave up

0 Kudos
Altera_Forum
Honored Contributor II
1,077 Views

i can't use it In that case, the easiest way is to calculate one distance value for every clock edge 

how can i do that??
0 Kudos
Altera_Forum
Honored Contributor II
1,077 Views

hi kaz, 

i want to thank y very match the design is run correct now the problem was in the simulator program,but now it run perfact . thanks again,you are my vhdl teacher 

if i want to sum the distance values.i should make distance in a signal then summation those values
0 Kudos
Altera_Forum
Honored Contributor II
1,077 Views

 

--- Quote Start ---  

hi kaz, 

i want to thank y very match the design is run correct now the problem was in the simulator program,but now it run perfact . thanks again,you are my vhdl teacher 

if i want to sum the distance values.i should make distance in a signal then summation those values 

--- Quote End ---  

 

 

Another satisfied customer. Thanks for the feedback. Though I am not used to the concept of distance between two data but I believe you mean it since address is normally given to places. I am still unclear about what/how you are given your inputs.
0 Kudos
Altera_Forum
Honored Contributor II
1,077 Views

when the user write on the keyboard there is a software program capture the data input and measure the trigraphs duration (time) then i will make a sorter to sort those trigraphs duration according thair times ,so i need their time for ordering them only, but trust me i don't know how i give the trigraphs to the fpga . i know the procedures but can't make it reall in fpga board. should you suggest me away to make it??  

another guestion my teacher . if i want to sum the distance values and the input may be 100 or 200 or any array i.e not certain number of input .how i can make it
0 Kudos
Altera_Forum
Honored Contributor II
1,077 Views

 

--- Quote Start ---  

when the user write on the keyboard there is a software program capture the data input and measure the trigraphs duration (time) then i will make a sorter to sort those trigraphs duration according thair times ,so i need their time for ordering them only, but trust me i don't know how i give the trigraphs to the fpga . i know the procedures but can't make it reall in fpga board. should you suggest me away to make it??  

another guestion my teacher . if i want to sum the distance values and the input may be 100 or 200 or any array i.e not certain number of input .how i can make it 

--- Quote End ---  

 

 

interfacing with PC is done commonly through nios. If you want a short cut then use realtime editable rams and update them with your new file. for that you need to instantiate rams and activate the realtime edit feature. 

 

for adding values of distance use accumulator(just feedback register). for each sum first clear it then sum up in the feedback loop till some 2^n samples so that at the end you truncate n LSBs and clear it for next update.
0 Kudos
Altera_Forum
Honored Contributor II
1,077 Views

 

--- Quote Start ---  

interfacing with PC is done commonly through nios. If you want a short cut then use realtime editable rams and update them with your new file. for that you need to instantiate rams and activate the realtime edit feature. 

 

for adding values of distance use accumulator(just feedback register). for each sum first clear it then sum up in the feedback loop till some 2^n samples so that at the end you truncate n LSBs and clear it for next update. 

--- Quote End ---  

 

 

my above note on truncation of n bits applies if you want the average. If you just want sum then read accumulator value at the end.
0 Kudos
Altera_Forum
Honored Contributor II
1,077 Views

yes y are right ,first i want to count the number of input samples,so i need a counter then when samples terminated and distances calculated i use the accumulator ,for example 

if distances are 1+3+6+3=7 and the number of samples be 4  

should i use another entity to make this ?
0 Kudos
Altera_Forum
Honored Contributor II
1,077 Views

 

--- Quote Start ---  

yes y are right ,first i want to count the number of input samples,so i need a counter then when samples terminated and distances calculated i use the accumulator ,for example 

if distances are 1+3+6+3=7 and the number of samples be 4  

should i use another entity to make this ? 

--- Quote End ---  

 

 

well just a clocked process will do. 

process(clk) begin if rising_edge(clk) then if clear = '1' then sum <= accum; accum <= (others => '0'); else accum <= accum +distance; end if; end if; end process;  

assuming distance is an incoming stream of samples, one per clock period. you control the clear signal using a counter for your samples.
0 Kudos
Altera_Forum
Honored Contributor II
1,077 Views

 

--- Quote Start ---  

well just a clocked process will do. 

process(clk) begin if rising_edge(clk) then if clear = '1' then sum <= accum; accum <= (others => '0'); else accum <= accum +distance; end if; end if; end process;  

assuming distance is an incoming stream of samples, one per clock period. you control the clear signal using a counter for your samples. 

--- Quote End ---  

 

 

sorry kaz . i didn't undersatand that .if you remember that distance is output ,i make a signal instead of output but it every clk increment the accum. 

could you plz illustrate.
0 Kudos
Reply