具有位屏蔽功能的新线中2线的可变宽度分配[VERILOG]

时间:2017-10-26 18:28:28

标签: verilog selection bit masking

我正在尝试在硬件(使用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

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

因此,对于A的两种情况,将分配所有64位输出。 我知道A掩码和多路复用选择是必需的,但它有点复杂,我无法清楚地了解如何在Verilog中实现它。

1 个答案:

答案 0 :(得分:0)

运行时相关位选择可以通过 shift(&lt;&lt;&lt;&lt;&lt;&lt;&gt;)可变位选择(a [k +:8])来实现,这是一个设计巧妙的< strong> for循环(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