在我的设计中,我有一个1024个整数的矩阵。在某些情况下,我需要在一个单位中增加其中一些整数的值。问题是,我不能使这个设计完成合成,我已经等了四个多小时,它仍然没有结束或返回一个错误。
以前,我有一个在几分钟内合成的代码,但是当我添加这个代码(实际上是一个非常相似的代码)时,他花了超过12个小时的时间进行合成,但始终没有完成。
我希望你能帮我,我正在完成我的学位工作,但由于这个问题,我一直未能完成它。
谢谢
设计如下:
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;```发布于 2020-01-08 16:48:38
你不会说你用什么工具来合成,甚至不知道目标设备是FPGA,ASIC还是其他什么。然而,简单的回答是,我认为您可能能够实现您想要做的事情--但我认为关键是找到一种将PHA_Array实现为内存的方法。
假设您的目标是FPGA,很可能您必须(至少)施加以下限制才能推断RAM:
PHA_Array条目(无论是读、写还是在每个地址都是)。之前至少注册1次整数。
目前,当您在重置期间并行清除整个PHA_Array时,就违反了第一个条件。当您在读取(并写入)整数的同一周期中立即增加整数时,将违反第二个条件。
对于如何解决这个问题,没有快速的答案,因为最好的答案取决于您的需求。但是,如果您可以保证永远不会在连续的时钟周期中断言Add_this_height,那么这将是一个很大的简化。如果是这样的话,那么您可以尝试这样的方法:
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;这是通过使用RAM端口"A“做读-修改-写部分,和RAM端口"B”做读出和清除在重置部分。
请再次注意,这假设Add_this_height是,而不是连续两个周期中的高。即使这个假设是不正确的,您也可以尝试合成这段代码。如果它的合成速度相对较快,那么这至少意味着推断RAM可能是一个很好的方法。
发布于 2020-01-08 08:26:59
您不仅有1024个32位宽寄存器,而且还有1024个32位加法器,用于递增加上一个要增加的条件。
这是一个很大的逻辑,我建议减少。这不太可能适合您的FPGA,即使它这样做,它可能会使用太多的资源。
第一个减法是:你真的需要能够数到2147483647吗?另外,你使用的是一个整数,它可以是负的,但我认为你不需要负的部分。因此,我建议您首先设置一个计数限制,并将计数器缩小为无符号类型的有限长度。
接下来是一次只递增一个条目。这将允许您用双端口内存替换整个数组。
从内存中读取一个条目,增加值,将它写回下一个时钟周期,但是检查下一个条目是否具有相同的索引,在这种情况下,您还没有(还)将它写回。
您的控制逻辑将更加复杂,因此需要更多的时间来开发和调试,但最终您应该能够将代码打包成当前大小的一小部分。您还可以返回到使用31位甚至更多位。
我必须承认,我不知道你想用你读的“号码”条目做什么。也是因为你的“号码”永远不会被重置。您可以通过双端口内存以双时钟速度运行来解决这个问题,使其成为一个四端口内存。或者你可以“在最后”(有结束了吗?)循环遍历内存,一次读出1024个条目。
https://stackoverflow.com/questions/59640145
复制相似问题