Hello everyone, i am doing image processing on fgpa.Actually i want to browse the ram content for every row of the image, and whenever the content of the adress is not updated i need to register this adress. I placed the read statement in a for loop but if for example i have 5 adresses that their contents are not updated the output register only the last one. Is there a possible way to register the multiple adresses.
Actually i'm doing this project using VHDL as a description language. Here's my code
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use ieee.std_logic_signed.all; use ieee.math_real.all; library std; entity active_tag is generic ( DATA_WIDTH : natural ); port ( clk : in std_logic; addr_a : in std_logic_vector(2 downto 0); addr_b : in std_logic_vector(2 downto 0); data_a : in integer; we_a,rd_en : in std_logic := '1'; we_b : in std_logic := '1'; q : out integer; q_a : out std_logic_vector(DatA_WIDTH-1 downto 0); q_b : out std_logic_vector(Data_WIDTH-1 downto 0) ); end active_tag; architecture rtl of active_tag is signal data1: std_logic_vector((DATA_WIDTH-1) downto 0); signal add_a,add_b : integer range 0 to 7; -- Build a 2-D array type for the RAM subtype word_t is std_logic_vector((DATA_WIDTH-1) downto 0); type memory_t is array(7 downto 0) of word_t; -- Declare the RAM shared variable ram : memory_t; begin add_a<=to_integer(unsigned(addr_a)); data1<=std_logic_vector(to_unsigned(data_a,data1'length)); -- Port A process(clk) variable i : integer:=1 ; begin if(rising_edge(clk)) then if(we_a = '1') then ram(add_a) := data1; end if; if rd_en='1' then for add_a in 0 to 7 loop if (ram(add_a)=(y-1 mod 3)) then q_a<=std_logic_vector(to_unsigned(add_a,q_a'length)); end if; end loop; end if; end if; end process; -- Port B process(clk) begin if(rising_edge(clk)) then if(we_b = '1') then ram(add_b) := "000"; q_b <= addr_b; end if; end if; end process; end rtl;the entry data_a represent y mod 3 . For every row of the image i need to check all the ram content so whnever data_a is not changed i need to read this adress. To detect whether the entry is changed or not i compare it to y-1 mod 3 as you can see in the code. But the problem is that if there's multiple adresses that their contents are is not updated i get only the last adress it's like it is the only one that its content it is not changed.
This code will not work in an FPGA. You can only access a single ram element per clock cycle. So this design will be implemented in logic.Using a loop the way you have is NOT good practice. For example, here, if two addresses are a match, then it is the last one that will output to q_a. Do you know what circuit you expect from this code? have you got a diagram of it?
Yes i know this circuit is implemented in logic but i thought this the only way i can check the ram content. Is there a possible way to browse ram content and get multiple adresses as output without using a for loop? knowing that it's not necessary to get all this adresses in just one clock cycle.
--- Quote Start --- Yes i know this circuit is implemented in logic but i thought this the only way i can check the ram content. Is there a possible way to browse ram content and get multiple adresses as output without using a for loop? knowing that it's not necessary to get all this adresses in just one clock cycle. --- Quote End --- Yes Provide the addresses sequentially over several clock cycles using a counter.
The adresses are not incremented like this, actually they are ouputs from another block so it's like that they are random adresses. I can't tell when they are generated neither their value.
It sounds like you are trying to make CAM - content addressable ram. This is not easy in an FPGA.Also, your code looks like software rather than hardware. for loops in HDL are unrolled to make parallel or sequential logic. In your case, it is create 8 comparators and a 8-1 mux to select the correct ram register (because it is not a ram, its a load of registers) to use. because you are muxing 8-1, comparing then muxing the result again in a single clock cycle, your Fmax is going to be very slow.
Thank you so much for your help. I will try to read about the CAM and hope for understanding it, because for the code i published i used 8 elements just for simplification but in my project i have 640 elements.
--- Quote Start --- Thank you so much for your help. I will try to read about the CAM and hope for understanding it, because for the code i published i used 8 elements just for simplification but in my project i have 640 elements. --- Quote End --- With what you are doing, you will need to use ram blocks - and CAM are really not well suited to FPGAs- they can only be emulated and they have a huge latency.
Actually i found a vhdl code in this forum about cam on cyclone iii (as i need) it is emulated and uses ram blocks. But the number of the output pins are greater then the available ones. I think about using virtual pins but can this affect my code when i will implement it on my fpga?
--- Quote Start --- Actually i found a vhdl code in this forum about cam on cyclone iii (as i need) it is emulated and uses ram blocks. But the number of the output pins are greater then the available ones. I think about using virtual pins but can this affect my code when i will implement it on my fpga? --- Quote End --- That sounds like you're trying to implement the design directly to the pins. That wont be possible - how do you expect to connect it to the outside world? Virtual pins are just a way to test a block in your design for resource usage. They have no use in a real design. You need to think about whats on your chip and how you interface to this CAM from outside the FPGA (or inside, if you're connecting to another block). You would never just connect the CAM to the FPGA pins.
Hello again.I want to understand something about CAM. Actually i'm using cyclone iii which have M9K memory blocks. So for my project as i described before, i firstly use a ram to store data. The addresses goes from 0 to 639 and my data is only 2 bits length. I reached to code a CAM but i have this two questions : 1) The output of CAM is one-hot so to get the encoded address 639 do i need a CAM of the size 640x2 ??? I'm really confused, because to store data i only used one block M9K why would i need more than that to get the address?? ( I need the encoded address not the one-hot one ) 2) For my project it might be more than one address storing the same data but i got only the last one, so the CAM didn't solve my problem, because for my project many addresses will store the same data. So how to pass from one match to multi-match please?
1. I dont really understand the question. A CAM would return the address of the requested data, and which address returned on a multiple match would be down to the implementation of the CAM.2. Then you'll have to build a custom module that returns all of the addresses containing your 2 bit value.
For my first question, i just want to know how to choose the size of my CAM, knowing that the output of CAM is a one-hot output and the addresses are in the range of 0 to 639.
As i read the CAM return one-hot output for example if the matched address is 001 then the one-hot output is 00..010 if it is 010 then the one-hot output is 000..00100 if it is 011 the one-hot output is 00...01000 etc. Then we encode this output to get the address number.