这里的数组总是@(my_array)块上的数组索引(在Verilog中实现寄存器冒泡)

问题描述 投票:1回答:1

我正在学习Verilog,并尝试实现CD54HC40105 chip。使我绊倒​​的部分是冒泡的逻辑。

[基本上,这是一个FIFO芯片,通过将单词通过存储器起泡来工作。每个单词一位用于跟踪该插槽中是否存在一个单词。

这是我需要实现的逻辑:在任何时候,如果某个单词存在于某个插槽i中(表示ctrl[i] == 1),而下一个插槽[ctrl[i + 1] == 0)中没有任何单词,则移动插槽i中的字与下一个插槽i+1以及控制信号。

它可能看起来像这样:

// Empty word next to B, it will shift right
+---+---+---+---+
| 1 | 1 | 0 | 0 |
+---+---+---+---+
| A | B |   |   |
+---+---+---+---+

// Empty word next to B and A, they will both shift right
+---+---+---+---+
| 1 | 0 | 1 | 0 |
+---+---+---+---+
| A |   | B |   |
+---+---+---+---+

// Empty word next to A, it will shift right
+---+---+---+---+
| 0 | 1 | 0 | 1 |
+---+---+---+---+
|   | A |   | B |
+---+---+---+---+

// No empty words
+---+---+---+---+
| 0 | 0 | 1 | 1 |
+---+---+---+---+
|   |   | A | B |
+---+---+---+---+

现在,该芯片没有时钟输入,框图中也没有任何内部时钟。因此,所有这些操作都使用可以在某种always块中实现的某种逻辑来完成。

我最初的直觉是,这将位于对always寄存器的更改敏感的ctrl块中。

reg[15:0] ctrl;
// ...
always @(ctrl) begin
    for (i = 0; i < 15; i = i + 1) begin
        if (ctrl[i] == 1 && ctrl[i + 1] == 0) begin
            ctrl[i + 1] <= 1;
            mem[i + 1] <= mem[i];
            ctrl[i] <= 0;
        end
    end
end

但是我得到了错误Array ctrl needs an array index here.,我明白了为什么会这样,但是我仍然不知道如何否则会这样做。

理想情况下,我需要一些语法可以完成此伪语法的工作:

// for all i's
always @(posedge ctrl[i]) begin
    // there are 16 slots, so we can never bubble the last index
    if (i != 15 && ctrl[i + 1] == 0) begin
        // ...
    end
end

编辑

我意识到上述伪解决方案将不起作用,因为当值移出并导致ctrl[15]变为0时,它将无法执行任何操作。那我该怎么办?

谢谢,

verilog hdl
1个回答
0
投票

我会使用一个generate循环。以下是一些入门知识(仅显示数据路径):

reg [0:16] ctrl;
reg [3:0] mem [0:16];

assign ctrl[0] = si_s;
assign mem[0] = d;

for (genvar i = 1; i <= 16; i++) begin : gen_loop
  always @(*) begin
    if (ctrl[i] && ctrl[i-1]) begin
      mem[i] = mem[i-1];
    end 
  end
end

assign q = mem[16];

如果可以使用SystemVerilog,则可能要使用always_latch关键字来显示意图。

© www.soinside.com 2019 - 2024. All rights reserved.