gpt4 book ai didi

arrays - 获取最后 512 个值中最大值的更节省资源的方法

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:55:53 26 4
gpt4 key购买 nike

我编写了一些 VHDL 代码,用于存储输入信号的最后 512 个值并计算存储值中的最大值。此代码有效,但使用了我的 FPGA 的大量 LUT 资源。代码的目的是计算最后 512 个样本的最大值,是否有更节省资源的方法来实现这一点? (重要的是它计算最后 512 个值中的最大值,而不是从该输入中观察到的最大值,后者可以很容易地通过存储单个数字来实现)。

或者,我是否可以通过某种方式编写 VHDL,以便合成器将阵列实现为 block RAM (BRAM) 而不是 LUT?

我使用的合成器是 LabVIEW FPGA(我相信它在内部使用 XilinX ISE 来编译/合成 VHDL)。

我目前的代码如下所示:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity RecentMax is
port (
clk : in std_logic;
reset : in std_logic;
InputSignal : in std_logic_vector(15 downto 0);
Max : out std_logic_vector(15 downto 0)
);
end RecentMax;

architecture RTL of RecentMax is
-- declarations
type Array512 is array(0 to 511) of signed(15 downto 0);
signal PastVals : Array512;
type Array256 is array(0 to 255) of signed(15 downto 0);
signal result : Array256;

signal CalculationState : unsigned(1 downto 0);
signal NLeftToCompute : unsigned(8 downto 0);
begin
-- behaviour
process(clk)
begin
if(rising_edge(clk)) then
if(reset = '1') then
-- reset values
for i in PastVals'low to PastVals'high loop
PastVals(i) <= (others => '0');
end loop;
for i in result'low to result'high loop
result(i) <= (others => '0');
end loop;
CalculationState <= to_unsigned(0, 2);
Max <= std_logic_vector(to_signed(0, 16));
NLeftToCompute <= to_unsigned(256, 9);
else
-- do stuff
case to_integer(CalculationState) is
when 0 =>
for i in PastVals'low to PastVals'high-1 loop
PastVals(i+1) <= PastVals(i);
end loop;
PastVals(0) <= signed(InputSignal);
Max <= std_logic_vector(result(0));
NLeftToCompute <= to_unsigned(256, 9);
CalculationState <= to_unsigned(1, 2);
when 1 =>
for i in 0 to 255 loop
if (i <= to_integer(NLeftToCompute)-1) then
if PastVals(i*2) > PastVals(i*2+1) then
result(i) <= PastVals(i*2);
else
result(i) <= PastVals(i*2+1);
end if;
end if;
end loop;
NLeftToCompute <= shift_right(NLeftToCompute, 1);
CalculationState <= to_unsigned(2, 2);
when 2 =>;
for i in 0 to 127 loop
if (i <= to_integer(NLeftToCompute)-1) then
if result(i*2) > result(i*2+1) then
result(i) <= result(i*2);
else
result(i) <= result(i*2+1);
end if;
end if;
end loop;
if NLeftToCompute > 2 then
NLeftToCompute <= shift_right(NLeftToCompute, 1);
else
CalculationState <= to_unsigned(0, 2);
end if;
when others =>
--- do nothing - shouldn't get here
end case;
end if;
end if;
end process;
end RTL;

最佳答案

你想要的有两种可能性。

首先您可以选择通过创建专用进程和数组来实例化 BRAM,以便合成器选择使用 block ram 而不是 512 luts。

CONSTANT DATA_WIDTH     : integer := 16;
CONSTANT ADD_WIDTH : integer := 9; -- 512 addresses
CONSTANT DPRAM_DEPTH : integer := 2**ADD_WIDTH; -- depth of the memory

TYPE dpram IS ARRAY (0 TO DPRAM_DEPTH - 1) OF std_logic_vector(DATA_WIDTH - 1 DOWNTO 0);
SIGNAL mem : dpram;

然后是过程:

dpram_gen_p : PROCESS (clk_i)
BEGIN
IF (rising_edge(clk_i)) THEN
IF (wr_req_i = '1') THEN
mem(wr_add_s) <= wr_data_i;
END IF;
rd_data_s <= mem(rd_add_s);
END IF;
END PROCESS;

对于主合成器,此语法将作为 block RAM 实现。然后,您需要使用 RAM 的数据端口,而不是您的 PastVals 信号。请注意读取周期,因为您需要一个时钟周期来更改读取接口(interface)的地址 (rd_add_s),并需要一个时钟周期来实际读取数据 (rd_data_s)。

第二个选项(对我来说这是最简单和最快的)只是实现一个 512 字大小的 fifo 存储器(您可以使用 Xilinx IP 核生成器)。

https://www.xilinx.com/support/documentation/ip_documentation/fifo_generator/v13_1/pg057-fifo-generator.pdf

然后您只需写入 fifo 直到它已满,最后逐字读取数据直到它为空并注册最高值,就像您在设计中所做的那样。

关于arrays - 获取最后 512 个值中最大值的更节省资源的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46175342/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com