我必须在一个相当大的缓冲区中缓冲一些数据。它不是通常的移位寄存器或FIFO,因为我必须能够从缓冲区的中间读取数据。 我设法以某种方式实现它,所以我可以在需要时使用它。问题是,它确实使用了LUT,这在我的设计中占用了大量空间。我想改变我的设计,以便将缓冲区推断为Block RAM。使用ram_style" block"没有帮助。有什么想法或建议我怎么能做到这一点? 更新:buf_size在包中声明: 常量buf_size:natural:= 5;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity deriv_buffer is
generic(
NSAMPLES : natural := 16
);
port(
clk : in std_logic;
rst : in std_logic;
deriv_s : in t_deriv_array( NSAMPLES - 1 downto 0 );
deriv_buf : out t_deriv_array( buf_size * NSAMPLES - 1 downto 0 )
);
end deriv_buffer;
architecture Behavioral of deriv_buffer is
signal deriv_buf_s : t_deriv_array( (buf_size-1) * NSAMPLES - 1 downto 0 );
attribute ram_style : string;
attribute ram_style of deriv_buf_s : signal is "block";
begin
deriv_buf( buf_size * NSAMPLES - 1 downto (buf_size - 1) * NSAMPLES ) <= deriv_s;
buffer_p : process( rst, clk )
begin
if rst = '1' then
deriv_buf_s <= ( others => ( others => '0' ) );
elsif rising_edge( clk ) then
deriv_buf_s( (buf_size - 1) * NSAMPLES - 1 downto (buf_size - 2) * NSAMPLES ) <= deriv_s;
deriv_buf_s( (buf_size - 2) * NSAMPLES - 1 downto (buf_size - 3) * NSAMPLES ) <= deriv_buf_s( (buf_size - 1) * NSAMPLES - 1 downto (buf_size - 2) * NSAMPLES );
deriv_buf_s( (buf_size - 3) * NSAMPLES - 1 downto (buf_size - 4) * NSAMPLES ) <= deriv_buf_s( (buf_size - 2) * NSAMPLES - 1 downto (buf_size - 3) * NSAMPLES );
deriv_buf_s( (buf_size - 4) * NSAMPLES - 1 downto (buf_size - 5) * NSAMPLES ) <= deriv_buf_s( (buf_size - 3) * NSAMPLES - 1 downto (buf_size - 4) * NSAMPLES );
end if;
end process buffer_p;
deriv_buf( (buf_size-1)*NSAMPLES - 1 downto 0 ) <= deriv_buf_s;
end Behavioral;
答案 0 :(得分:1)
如果您想使用Block RAM,则需要考虑Block RAM只有2个端口。您无法自由查看RAM中的数据:您需要通过任一端口访问它。
此外,读取和/或写入需要一个时钟周期来处理。
因此,如果我们查看您的代码,它已经开始出现问题:
entity deriv_buffer is
[...]
port(
[...]
deriv_buf : out t_deriv_array( buf_size * NSAMPLES - 1 downto 0 )
您将整个RAM连接到输出端口!我不知道你在使用这个组件的实体中的内容做了什么,但正如我所说:你没有可以自由访问Block RAM的内容。您需要遵循适当的Block RAM设计指南。
例如,请参考Xilinx Synthesis User Guide进行正确的Block RAM实例化。 (第4章HDL编码技术,部分RAM HDL编码技术)
下一个问题:重置
if rst = '1' then
deriv_buf_s <= ( others => ( others => '0' ) );
无法重置RAM。如果确实想要清除RAM,则需要在每个单独的地址位置写一个(others=>'0')
。因此,您需要控制逻辑来执行此操作。但现在,使用此重置代码将不允许实例化块RAM。
然后在你的代码中你有部分
deriv_buf_s( (buf_size - 1) * NSAMPLES - 1 downto (buf_size - 2) * NSAMPLES ) <= deriv_s;
deriv_buf_s( (buf_size - 2) * NSAMPLES - 1 downto (buf_size - 3) * NSAMPLES ) <= deriv_buf_s( (buf_size - 1) * NSAMPLES - 1 downto (buf_size - 2) * NSAMPLES );
deriv_buf_s( (buf_size - 3) * NSAMPLES - 1 downto (buf_size - 4) * NSAMPLES ) <= deriv_buf_s( (buf_size - 2) * NSAMPLES - 1 downto (buf_size - 3) * NSAMPLES );
deriv_buf_s( (buf_size - 4) * NSAMPLES - 1 downto (buf_size - 5) * NSAMPLES ) <= deriv_buf_s( (buf_size - 3) * NSAMPLES - 1 downto (buf_size - 4) * NSAMPLES );
此代码有两个大问题:
您可以实现代码以使用4个块RAM实例。但是,这些Block RAM的所有端口仍将被占用。因此,没有任何端口可以随意访问RAM中的所有数据,如您所愿。
最后:我认为你应该重新考虑你的要求。您想要的是块RAM中不可能的。如果要使用Block RAM,则应更改算法。