首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >设计4小时后不完成合成

设计4小时后不完成合成
EN

Stack Overflow用户
提问于 2020-01-08 05:57:18
回答 2查看 91关注 0票数 1

在我的设计中,我有一个1024个整数的矩阵。在某些情况下,我需要在一个单位中增加其中一些整数的值。问题是,我不能使这个设计完成合成,我已经等了四个多小时,它仍然没有结束或返回一个错误。

以前,我有一个在几分钟内合成的代码,但是当我添加这个代码(实际上是一个非常相似的代码)时,他花了超过12个小时的时间进行合成,但始终没有完成。

我希望你能帮我,我正在完成我的学位工作,但由于这个问题,我一直未能完成它。

谢谢

设计如下:

代码语言:javascript
复制
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;```
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-01-08 16:48:38

你不会说你用什么工具来合成,甚至不知道目标设备是FPGA,ASIC还是其他什么。然而,简单的回答是,我认为您可能能够实现您想要做的事情--但我认为关键是找到一种将PHA_Array实现为内存的方法。

假设您的目标是FPGA,很可能您必须(至少)施加以下限制才能推断RAM:

  1. 同时寻址最多2个PHA_Array条目(无论是读、写还是在每个地址都是)。
  2. 在读取时,必须在修改(+1).

之前至少注册1次整数。

目前,当您在重置期间并行清除整个PHA_Array时,就违反了第一个条件。当您在读取(并写入)整数的同一周期中立即增加整数时,将违反第二个条件。

对于如何解决这个问题,没有快速的答案,因为最好的答案取决于您的需求。但是,如果您可以保证永远不会在连续的时钟周期中断言Add_this_height,那么这将是一个很大的简化。如果是这样的话,那么您可以尝试这样的方法:

代码语言:javascript
复制
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可能是一个很好的方法。

票数 0
EN

Stack Overflow用户

发布于 2020-01-08 08:26:59

您不仅有1024个32位宽寄存器,而且还有1024个32位加法器,用于递增加上一个要增加的条件。

这是一个很大的逻辑,我建议减少。这不太可能适合您的FPGA,即使它这样做,它可能会使用太多的资源。

第一个减法是:你真的需要能够数到2147483647吗?另外,你使用的是一个整数,它可以是负的,但我认为你不需要负的部分。因此,我建议您首先设置一个计数限制,并将计数器缩小为无符号类型的有限长度。

接下来是一次只递增一个条目。这将允许您用双端口内存替换整个数组。

从内存中读取一个条目,增加值,将它写回下一个时钟周期,但是检查下一个条目是否具有相同的索引,在这种情况下,您还没有(还)将它写回。

您的控制逻辑将更加复杂,因此需要更多的时间来开发和调试,但最终您应该能够将代码打包成当前大小的一小部分。您还可以返回到使用31位甚至更多位。

我必须承认,我不知道你想用你读的“号码”条目做什么。也是因为你的“号码”永远不会被重置。您可以通过双端口内存以双时钟速度运行来解决这个问题,使其成为一个四端口内存。或者你可以“在最后”(有结束了吗?)循环遍历内存,一次读出1024个条目。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59640145

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档