Forum Discussion
51 Replies
- Altera_Forum
Honored Contributor
--- 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) - Altera_Forum
Honored Contributor
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; - Altera_Forum
Honored Contributor
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; - Altera_Forum
Honored Contributor
---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. - Altera_Forum
Honored Contributor
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. - Altera_Forum
Honored Contributor
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 - Altera_Forum
Honored Contributor
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 - Altera_Forum
Honored Contributor
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)
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 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;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; - Altera_Forum
Honored Contributor
rd_addr : in integer range 0 to 255;
kaz,why rd_addr is input ,why isn't output such as rd_data - Altera_Forum
Honored Contributor
and what is vout represent