我有一个2048位的数组,我想存储 在时钟周期的每个上升沿,在FPGA中进入时,按0到2047的输入位按升序排列。
例如:
array[0] <= 1st bit
array[1] <= 2nd bit
...
..
array[2047] <= 2048 th bit.
我知道可以通过像
这样的数组索引在VHDL中完成array(index) <= incoming_bit.
然而,还有其他更好的方法,比如使用按位运算(移位)来实现这一目标。 (没有数组索引方法),因此最终降低了FPGA中的路由复杂性。
答案 0 :(得分:3)
Block RAM
在您描述的情况下,克服路由问题的最有效方法可能是将该位存储在块ram中。
如果您使用以正确方式编写的代码使用您描述的数组,那么它可能已经是合成器为您提供的。
但是如果你在代码中使用了一个复位来加载所有'0'的数组,那么合成器将无法推断出一个BlockRAM,从而产生可能效率不高的东西。
<强> FIFO 强>
如果您总是一个接一个地使用这些位,并且之后不使用它,则可以使用FIFO(可能由合成器使用BlockRAM实现)。
这些位将在FIFO进入时存储在FIFO中,并且只有最旧的尚未处理的位将在FIFO的输出处呈现给您。
如果位的位置很重要,那么每次从fifo读取一个位时,都可以有一个11位计数器递增,因此它总是反映从FIFO中取出的位的位置。
希望这有帮助。
答案 1 :(得分:1)
如果在加载2048完成之前不需要访问数据,那么在verilog中你可以暗示一个桶形移位器。每个时钟周期数据都向下移动1个位置。在2048位结束时,每件事都会在正确的位置。
reg [2048-1:0] arr;
always @( posedge clk or negedge rst_n) begin
if (~rst_n) begin
arr <= 'b0;
end
else begin
arr[2048-1:0] <= {data_in, arr[2048-1:1]}
end
end
如果在加载完整的2048位之前需要访问第一位,则RAM是理想的选择。 RAM通常无法在1个时钟周期内初始化,无异步复位。因此,您只能从已写入的位置读取数据。您可以指定FPGA的初始条件,我相信FPGA启动路由可以为您初始化它。但是一旦运行就没有简单的方法来清除它。
input data_in;
input [10:0] wr_addr;
reg [2048-1:0] arr;
always @( posedge clk ) begin
arr[wr_addr] <= data_in;
end
// Optional FPGA initialisation
integer i;
initial begin
for(i=0; i<2048; i=i+1) begin
arr[i] <= 'b0;
end
end
答案 2 :(得分:0)
从根本上说,如果您需要同时访问所有位,那么您对路由复杂性的处理并不多 - 输入和输出都必须始终存在。
如果(另一方面)你一次获得一个输入位(或者只需要一次访问它们),那么你可以将它们存储在一个内存块中,这将减少资源的使用。 / p>