- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
---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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
rd_addr : in integer range 0 to 255;
kaz,why rd_addr is input ,why isn't output such as rd_data- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
and what is vout represent
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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??- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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 ?- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page