Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronic Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

What the best way to store data of size ( 90,000 * 32) bit (taken from a text file) using VHDL?

MSAKARIM

Full Member level 2
Joined
Jun 2, 2015
Messages
132
Helped
1
Reputation
2
Reaction score
4
Trophy points
18
Activity points
1,069
What the best way to store data of size ( 90,000 * 32) bit (taken from a text file)?

I have a database (in a text file )of size ( 90,000 * 32), I want to know, what is the most effective way to store them, and then I compare this database with some input data to check if there is any matching.
I tried to solve this by storing them inside 14 RAMs instead of one, but it takes a very long time while synthesis (more than 24 hours) is that normal or my code has a problem.

Code:
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;
 

FlyingDutch

Full Member level 5
Joined
Dec 16, 2017
Messages
301
Helped
39
Reputation
78
Reaction score
38
Trophy points
28
Location
Bydgoszcz - Poland
Activity points
3,101
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"
 
Last edited:

FvM

Super Moderator
Staff member
Joined
Jan 22, 2008
Messages
48,215
Helped
14,210
Reputation
28,679
Reaction score
12,904
Trophy points
1,393
Location
Bochum, Germany
Activity points
279,308
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.
 

FlyingDutch

Full Member level 5
Joined
Dec 16, 2017
Messages
301
Helped
39
Reputation
78
Reaction score
38
Trophy points
28
Location
Bydgoszcz - Poland
Activity points
3,101

MSAKARIM

Full Member level 2
Joined
Jun 2, 2015
Messages
132
Helped
1
Reputation
2
Reaction score
4
Trophy points
18
Activity points
1,069
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.

Like this?

Code:
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;
--- Updated ---

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"

Okay, I will try the "Binary Search"
 

FlyingDutch

Full Member level 5
Joined
Dec 16, 2017
Messages
301
Helped
39
Reputation
78
Reaction score
38
Trophy points
28
Location
Bydgoszcz - Poland
Activity points
3,101
Hello,

I have a question related to this thread: If one is using "for loop" in process in how much clock cycles it is performed? Always this was unclear for me. I know that "process" is parallel task in VHDL (as 5 different parallel instructions). I also read about deltas (in parallel instructions) and the way of delineating circuit state. Could someone to clarify this to me?

Thanks in advance and Regards
--- Updated ---

Hello,

I probably found the answer. Here it is in these two links:

https://www.reddit.com/r/FPGA/comments/9glfbu

It follows that for loop is synthesized in as many hardware parts as is the range of for loop. Hence it follows such big synthesis time and resources consumption in @MSAKARIM project.

Best Regards
 
Last edited:

niciki

Full Member level 2
Joined
Apr 11, 2018
Messages
139
Helped
31
Reputation
62
Reaction score
33
Trophy points
38
Location
Gdańsk, Poland
Activity points
957
In the for loop there is 3872 assignments to dout:
Code:
for i in 0 to 3871 loop
  ...
  dout <= Ram(i);
end loop;
That means there is 3872 drivers for signal dout. Signals shouldn't have multiple drivers - synthesiser for this example have to resolve 3872 equations of resolver functions to figure out what will be a value of dout, which can be demanding.
 
Last edited:

TrickyDicky

Advanced Member level 5
Joined
Jun 7, 2010
Messages
7,055
Helped
2,075
Reputation
4,167
Reaction score
2,028
Trophy points
1,393
Activity points
39,020
@niciki The for loop will not create multiple drivers. for a signal assignment inside a process, the last assignment "wins". In this case, dout will always be Ram(3871).
 

FvM

Super Moderator
Staff member
Joined
Jan 22, 2008
Messages
48,215
Helped
14,210
Reputation
28,679
Reaction score
12,904
Trophy points
1,393
Location
Bochum, Germany
Activity points
279,308
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.
 

MSAKARIM

Full Member level 2
Joined
Jun 2, 2015
Messages
132
Helped
1
Reputation
2
Reaction score
4
Trophy points
18
Activity points
1,069
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.

By this "but logic to set and increase addr must be added." do you mean adding some counter to the addr until it reaches the last values?

BTW, after synthesizing this part using ISE14.7 it gives me the following:
1-
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?

2-
Minimum period: No path found
Minimum input arrival time before clock: 4.890ns
Maximum output required time after clock: 0.511ns
Maximum combinational path delay: No path found

Why it gives "No path found" ?
 

FvM

Super Moderator
Staff member
Joined
Jan 22, 2008
Messages
48,215
Helped
14,210
Reputation
28,679
Reaction score
12,904
Trophy points
1,393
Location
Bochum, Germany
Activity points
279,308
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?
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.
 

MSAKARIM

Full Member level 2
Joined
Jun 2, 2015
Messages
132
Helped
1
Reputation
2
Reaction score
4
Trophy points
18
Activity points
1,069
I tried this code, but it doesn't work properly. What does it miss?

Code:
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;
 

dpaul

Advanced Member level 4
Joined
Jan 16, 2008
Messages
1,465
Helped
306
Reputation
612
Reaction score
301
Trophy points
1,373
Location
Germany
Activity points
10,977

TrickyDicky

Advanced Member level 5
Joined
Jun 7, 2010
Messages
7,055
Helped
2,075
Reputation
4,167
Reaction score
2,028
Trophy points
1,393
Activity points
39,020
@MSAKARIM

Please define what "doesn't work properly" means. Did you get an error? did it not behave as expected? What behaviour did you expect?
 

MSAKARIM

Full Member level 2
Joined
Jun 2, 2015
Messages
132
Helped
1
Reputation
2
Reaction score
4
Trophy points
18
Activity points
1,069
It doesnt behave as expected, it gives "Match ='0' " in two cases (matching and not matching)
 

MSAKARIM

Full Member level 2
Joined
Jun 2, 2015
Messages
132
Helped
1
Reputation
2
Reaction score
4
Trophy points
18
Activity points
1,069
@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...

Okay, it very helpful.
--- Updated ---

Then that implies there is no match. You then need to debug as to why (usually using the waveform).

I used a value from the already stored values and it also gives me "No matching"
 

ads-ee

Super Moderator
Staff member
Joined
Sep 10, 2013
Messages
7,789
Helped
1,806
Reputation
3,622
Reaction score
1,764
Trophy points
1,393
Location
USA
Activity points
58,771
As you are trying to read a file and store those values in a RAM you should not be trying to implement RAM you should be looking at the synthesis inference of ROM memory.
 

MSAKARIM

Full Member level 2
Joined
Jun 2, 2015
Messages
132
Helped
1
Reputation
2
Reaction score
4
Trophy points
18
Activity points
1,069
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

I tried to describe the Binary Search algorithm as follows, and it also takes a very long time while the synthesis. Is there any advice in the way of describing the code?

Code:
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;
 

TrickyDicky

Advanced Member level 5
Joined
Jun 7, 2010
Messages
7,055
Helped
2,075
Reputation
4,167
Reaction score
2,028
Trophy points
1,393
Activity points
39,020
The problem is yyou are trying to search the entire "ram" (this cannot now actually be a ram) in a single clock cycle. I suggest you draw out your intended circuit before you write any code for this. VHDL is not like writing software.
 

LaTeX Commands Quick-Menu:

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top