【问题标题】:variable width assignment from 2 wires in a new wire with bit masking [VERILOG]使用位掩码 [VERILOG] 新线中的 2 根线的可变宽度分配
【发布时间】:2017-11-01 16:07:52
【问题描述】:

我正在尝试在硬件中(使用 Verilog)实现此伪代码所描述的功能:

if A then
      output [63:0] = b[63:56], c[X-1:0], b[Y-1:0]
else  output [63:0] = c[X-1:0], b[Y-1:0]

A 是一个布尔值,而输出 b 和 c 是 64 位长。 X 和 Y 在运行时发生变化,因此它们不能是 Verilog 变量。 X的值随着A的变化而变化:

if A then
      X = 56 - Y
else  X = 63 - Y

而 Y 是从 6 位寄存器中读取的,因此它可以是 0 到 63 之间的任何数字。

所以对于 A 的两种情况,所有 64 位输出都将被分配。 我知道需要使用 A 进行位掩码和多路复用器选择,但它有点复杂,我不太清楚如何在 Verilog 中实现这一点。

【问题讨论】:

  • 为什么不使用连接运算符 { } 呢?

标签: verilog selection bit masking


【解决方案1】:

运行时依赖的位选择可以通过shift(、可变位选择(a[k+:8])来实现,这是一个设计巧妙的 for loop(a[i] = condition ? b:c) 或完全表达的case。并且它们都应该具有相似的合成结果。根据经验,案例实施应该具有最佳的区域性能。

以下是班次实施的示例(带有测试台):

`timescale 1ns/1ps
module example(
    input A,
    input [5:0] Y,
    input [63:0] b, c,
    output [63:0] result
);

reg [63:0] o_a, o_abar;

assign result = A ? o_a : o_abar;
wire [5:0] X = A ? (56-Y) : (63-Y);

reg [63:0] c1_tmp, b1_tmp, mask;
always@(*)begin
    c1_tmp = (c << Y) & {8'd0, {56{1'b1}}};
    mask = (({64{1'b1}}>>X) << Y) | ({64{1'b1}} >> (64-Y));
    b1_tmp = mask & b;
    o_a = c1_tmp | b1_tmp;
end

reg [63:0] c2_tmp, b2_tmp;
always@(*)begin
    c2_tmp = c << Y;
    b2_tmp = b & ({64{1'b1}} >> Y);
    o_abar = c2_tmp | b2_tmp;
end
endmodule

module test;
    reg A;
    reg [5:0] Y;
    reg [63:0] b, c;
    wire [63:0] result;
    example ex(.A(A), .Y(Y), .b(b), .c(c), .result(result));
    initial begin
        A = 1;
        Y = 6;
        c = -1;
        b = 0;
        #10
        $display("%b", result);
        $finish;
    end
endmodule

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-19
    • 2021-11-29
    相关资源
    最近更新 更多