0
votes

I'm trying to implement in hardware (using Verilog) the function described by this pseudo code:

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 is a boolean value, while output, b and c are 64 bits long. X and Y change at runtime so they can't be Verilog variables. The value of X changes with A:

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

while Y is read from a 6 bit register so it can be any number from 0 to 63.

So for both cases of A all 64 bits of output will be assigned. I know bit masking and mux selection with A is required but it is a bit complex and I can't quite get a clear picture on how to implement this in Verilog.

1
Why don't you use the concatenation operator { } for this? - vipin

1 Answers

0
votes

The runtime dependent bit selection can be implemented with shift(<<), variable bit selection(a[k+:8]), a smartly designed for loop(a[i] = condition ? b:c) or a completely expressed case. And all of them should have similar synthesis result. Based on experience, the case implementation should have best area performance.

Here is an example (with testbench) for shift implementation:

`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