【问题标题】:Combinational way of implementing a CAM in verilog在verilog中实现CAM的组合方式
【发布时间】:2022-01-11 21:59:17
【问题描述】:

我正在尝试在 SystemVerilog 中实现缓存和索引查找内存。这是一个简单的 CAM + 循环缓冲区。界面为:

input rst_n;
input clk;
input [WORD_BITS-1:0] inp;
input rd_en;
input wr_en;
output logic [DEPTH_BITS-1:0] index;
output logic index_valid;

reg [WORD_BITS-1:0] buffer[$pow(2, DEPTH_BITS)];
reg [DEPTH_BITS-1:0] next;

有基本的异步重置代码。有一个同步块将inp 存储在缓冲区中,并在wr_en 为高电平时推进next

现在我正在尝试提出一种有效且易读的方法来在rd_en 很高时查找inp 的索引。似乎这可能是完全组合的,除非将结果输入index 输出。我在脑海中将其可视化的方式是对所有缓冲区位置进行 xor inp(它将相当小,可能是 64 个条目),然后如果它等于 0,则找到该条目。然后是一个块来任意选择一个值为 0 的索引。这就是与传统 CAM 不同的地方,可能有多个条目具有相同的值,但我真的只需要其中一个的索引,哪个并不重要。

对如何在 System Verilog (2012) 中执行此操作有任何想法吗?我知道我可以同步遍历所有内存位置并节省一堆区域,但我宁愿它快而不是小。我的目标是FPGA。 (最初便宜的 Lattice 和可能是 Xilinx 部件)我知道一些 Lattice 部件实际上有 CAM 块,但这是针对不可用的情况。

【问题讨论】:

    标签: verilog system-verilog fpga


    【解决方案1】:

    根据另一个论坛的建议,以下似乎效果很好。

            always_comb begin
                    index_valid = 0;
                    for (int i=0; i < 64; i=i+1) begin
                            if (rd_en) begin
                                    if (inp == buffer[i]) begin
                                            index = i;
                                            index_valid = 1'b1;
                                    end
                            end
                    end
            end
    

    【讨论】:

    • 我不得不硬编码深度,因为至少 Icarus 不喜欢在 for 循环中为 always_comb 使用 localparam。
    • 这看起来不错。您可能还想为index 指定一个默认分配(在index_valid = 0; 旁边),即使它是由index_valid 限定的。这样可以避免合成中的闩锁。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-13
    • 2021-03-03
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多