我正在尝试在硬件(使用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中实现它。
答案 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