MSAKARIM
Full Member level 3
- Joined
- Jun 2, 2015
- Messages
- 154
- Helped
- 1
- Reputation
- 2
- Reaction score
- 4
- Trophy points
- 1,298
- Activity points
- 2,528
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.STD_LOGIC_TEXTIO.ALL;
USE STD.TEXTIO.ALL;
entity List_0 is
Port ( clk : in STD_LOGIC;
din : in STD_LOGIC_VECTOR (31 downto 0);
dout : out STD_LOGIC_VECTOR (31 downto 0);
Match : out STD_LOGIC);
end List_0;
architecture Behavioral of List_0 is
type TRam is array(0 to 3871) of std_logic_vector(31 downto 0);
impure function init_bram (ram_file_name : in string) return TRam is
file ramfile : text ;
variable line_read : line;
variable ram_to_return : TRam;
begin
file_open(ramfile,"F:\RAM_0.txt",READ_MODE);
--while not endfile(ramfile) loop
for i in TRam'range loop
readline(ramfile, line_read);
hread(line_read, ram_to_return(i));
end loop;
--end loop;
return ram_to_return;
end function;
signal Ram : TRam := init_bram("F:\RAM_0.txt");
begin
process (clk)
begin
if (clk'event and clk = '1') then
for i in 0 to 3871 loop
if (din = Ram(i))then
match <= '1';
report "Matching Happened!";
exit;
else
match <= '0';
end if;
dout <= Ram(i);
end loop;
end if;
end process;
end Behavioral;
process (clk)
begin
if (clk'event and clk = '1') then
for i in 0 to 3871 loop
if (din = Ram(i))then
match <= '1';
report "Matching Happened!";
exit;
else
match <= '0';
end if;
dout <= Ram(i);
end loop;
end if;
end process;
The problem with your design is that can't be synthesized as block RAM, because you are reading multiple memory locations in one clock cyccle. Need to perform the compare sequentially, one address per clock cycle.
process (clk)
begin
--for i in 0 to 3871 loop
if (clk'event and clk = '1') then
if (din = Ram(conv_integer(addr)))then
match <= '1';
report "Matching Happened!";
-- exit;
else
match <= '0';
end if;
dout <= Ram(conv_integer(addr));
end if;
--end loop;
end process;
Hello,
I don't know if idea giving by me is not in contradiction to assumptions of your project. Maybe better use SoC (hard processor+ FPGA) and have small SQL database (for example "SQL Lite") and ask this database using TCP/IP network (program on hard CPU). In code that you attached to this post you are doing matching in process in for loop which is performed sequentially - if I am wrong let one of more experienced users correct me:
Code:process (clk) begin if (clk'event and clk = '1') then for i in 0 to 3871 loop if (din = Ram(i))then match <= '1'; report "Matching Happened!"; exit; else match <= '0'; end if; dout <= Ram(i); end loop; end if; end process;
If you use SOC for this project -for example ZYNQ-7010 you can run Linux and install "SQL Lite" database with ease and write program querying database also under Linux. The second solution that comes into my mind is to use ANN running on FPGA - then you will have very parallelized serching of your database.
Best Regards
--- Updated ---
BTW: if it is just looking for one value maybe then it is better use of different algorithm - for example "Binary Search"
for i in 0 to 3871 loop
...
dout <= Ram(i);
end loop;
In the original code, dout is either the content of ram(3871) or the ram value before a match exits the loop. I'm not sure if this is the intended purpose but it's legal (and basically meaningful) VHDL. As stated, it synthesizes to a huge (> 100k) core register array, not to block RAM.
Iteration statements in sequential code synthesize as parallel logic similar to an iterated generate construct. That's often used for smaller ranges, e.g. individual bits of a vector.
A synthesizable version of the compare action could look similar to post #5, but logic to set and increase addr must be added.
Not sure which design you have compiled. Not getting block RAM happens because requirements for block RAM inference are not fulfilled. Review vendor synthesis manual.Macro Statistics
# RAMs : 1
3872x32-bit single-port distributed Read Only RAM : 1
# Registers : 33
Flip-Flops : 33
# Comparators : 1
32-bit comparator equal : 1
How can I synthesize my code as BRAM not distributed RAM?
process (clk)
Variable addr : integer range 0 to 3871;
begin
if (clk'event and clk = '1') then
if (Ram(addr)=din)then
match <= '1';
report "Matching Happened!";
else
match <= '0';
report "NOOOOO Matching Happened!";
end if;
addr:= addr+1;
if (addr = 3871) then
addr:=0;
end if;
end if;
end process;
end Behavioral;
It doesnt behave as expected, it gives "Match ='0' " in two cases (matching and not matching)
@MSAKARIM ,
Did you read the RAM inference guide as mentioned by FvM above?
See Chapter 7: https://www.xilinx.com/support/documentation/sw_manuals/xilinx14_3/xst_v6s6.pdf
Just copy and paste from that document to avoid surprises...
Then that implies there is no match. You then need to debug as to why (usually using the waveform).
Yes, I think similiar to @FvM you are doing your search sequentialy - what has no sense to use FPGA, better is CPU. If you are seeking for one value better is sort your data from database and use "Binary search". See "binary search" from Wikipedia:
https://en.wikipedia.org/wiki/Binary_search_algorithm
https://www.khanacademy.org/computing/computer-science/algorithms/binary-search/a/binary-search
Best regrdas
Function Binary_Search (A:TRam; N: integer; T: std_logic_vector)
return integer is
Variable L : integer :=0;
Variable R : integer :=3871;
Variable M : integer;
begin
while (L <= R) loop
M:= integer((L+R)/2);
if(A(M) < T) then
L:= M+1;
elsif ( A(M) > T) then
R:= M-1;
else
return M;
report "Matching Happend !";
end if;
end LOOp;
return -1;
report "No Matching";
end Binary_Search;
begin
process (clk)
begin
if (clk'event and clk = '1') then
Location<=Binary_Search(Ram,3872,din);
end if;
end process;
end Behavioral;
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?