In my design I have a matrix of 1024 integers. Under certain circumstances, I need to increase the value of some of these integers in a unit. The problem is that I cannot make this design finish synthesizing, I have waited more than four hours and it still does not end or returns an error.
Previously I had a code that synthesized in a few minutes, but when I added this (actually a very similar one), he spent more than 12 hours synthesizing and never finished.
I hope you can help me, I am finishing my degree work and I have not been able to finish it because of this problem.
Thank you
The design is as follows:
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity Proof_Array is
Port (
reset : in std_logic;
Peak_height_detected_1 : in std_logic_vector(9 downto 0);
Add_this_height : in std_logic;
S_clk_ADC_15MHz : in std_logic;
S_Out : out std_logic_vector(31 downto 0));
end Proof_Array;
architecture Behavioral of Proof_Array is
type PHA_Array_Type is array (0 to 1023) of integer;
signal PHA_Array: PHA_Array_Type;
signal number: integer range 0 to 1023;
signal Peak_height_detected_1_int: integer range 0 to 1023;
begin
Peak_height_detected_1_int <= to_integer(unsigned(Peak_height_detected_1));
S_Out <= std_logic_vector(to_unsigned(PHA_Array(number), S_Out'length));
process(reset, S_clk_ADC_15MHz)
begin
if reset = '1' then
for k in 0 to 1023 loop
PHA_Array(k) <= 0;
end loop;
elsif rising_edge(S_clk_ADC_15MHz) then
if Add_this_height = '1' then
PHA_Array(Peak_height_detected_1_int) <= PHA_Array(Peak_height_detected_1_int) + 1;
end if;
if number > 1022 then
number <= 0;
else
number <= number + 1;
end if;
end if;
end process;```
You don't say what tool you are using for synthesis, or even whether the target device is an FPGA, ASIC or something else. However, the short answer is that I think you will probably be able to achieve what you are trying to do - but I think the key will be finding a way to implement PHA_Array
as a RAM.
Assuming you are targeting an FPGA, it is likely that you must impose (at least) the following restrictions in order to infer a RAM:
PHA_Array
simultaneously (whether reading, writing or both, at each address).Currently, the 1st condition is violated when you clear the whole of PHA_Array
in parallel during reset. The 2nd condition is violated when you immediately increment the integer in the same cycle that it is read (and written back).
There is no quick answer to how to fix this, as the best answer depends on your requirements. However, a huge simplification would be if you could guarantee that Add_this_height
is never asserted on consecutive clock cycles. If this is the case, then you might try something like this:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity Proof_Array is
Port (
reset : in std_logic;
Peak_height_detected_1 : in std_logic_vector(9 downto 0);
Add_this_height : in std_logic;
S_clk_ADC_15MHz : in std_logic;
S_Out : out std_logic_vector(31 downto 0));
end Proof_Array;
architecture Behavioral of Proof_Array is
type PHA_Array_Type is array (0 to 1023) of integer;
signal PHA_Array: PHA_Array_Type;
signal Add_this_height_r : std_logic;
signal RamWrEnA : std_logic;
signal RamAddrA : unsigned(9 downto 0);
signal RamOutA : integer;
signal RamWrEnB : std_logic;
signal RamAddrB : unsigned(9 downto 0) := (others => '0');
signal RamOutB : integer;
begin
PortA_proc : process(S_clk_ADC_15MHz)
begin
if rising_edge(S_clk_ADC_15MHz) then
-- Cycle 1 - Record which address to update
Add_this_height_r <= Add_this_height;
if Add_this_height = '1' then
RamAddrA <= unsigned(Peak_height_detected_1);
end if;
-- Cycle 2 - Read from RAM
RamWrEnA <= Add_this_height_r;
RamOutA <= PHA_Array(to_integer(RamAddrA));
-- Cycle 3 - Write to RAM (assuming RamAddrA hasn't changed)
if RamWrEnA = '1' then
PHA_Array(to_integer(RamAddrA)) <= RamOutA + 1;
end if;
end if;
end process;
-- Assuming reset is synchronized to S_clk_ADC_15MHz
RamWrEnB <= reset;
PortB_proc : process(S_clk_ADC_15MHz)
begin
if rising_edge(S_clk_ADC_15MHz) then
-- Always loop this address
RamAddrB <= RamAddrB + 1;
-- Clear in reset
if RamWrEnB = '1' then
PHA_Array(to_integer(RamAddrB)) <= 0;
end if;
-- Read to output
RamOutB <= PHA_Array(to_integer(RamAddrB));
end if;
end process;
S_Out <= std_logic_vector(to_unsigned(RamOutB, S_Out'length));
end Behavioral;
This works by using RAM port "A" to do the Read-Modify-Write part, and RAM port "B" to do the reading out and clearing in reset parts.
Note again that this assumes Add_this_height
is never high on 2 consecutive cycles. Even if this assumption is incorrect, you could try synthesizing this code. If it synthesizes relatively quickly, then that at least implies that inferring a RAM may be a good way forward.