I am trying to implement a simple processor that should support shifts. I did not find anything helpful in the documentary of BitVector or Bits so I checked how other people do this (e.g., here or here). The trick seems to be to unpack the BitVector and then use the Int to do the shifting.
I created this Clash code
shifter :: BitVector 16 -> BitVector 16 -> BitVector 16
shifter a b = shiftL a $ unpack $ extend b
which gives me the following verilog code
module shifter
( // Inputs
input wire [15:0] a
, input wire [15:0] b
// Outputs
, output wire [15:0] result
);
wire [63:0] eta;
wire signed [63:0] ds;
wire signed [63:0] c$ds_app_arg;
assign eta = {48'b000000000000000000000000000000000000000000000000,b};
assign ds = $signed(c$ds_app_arg);
assign c$ds_app_arg = $unsigned(eta[0+:64]);
assign result = a << (ds);
endmodule
Now this seems to be very wasteful (i.e., having a 64 bit eta intermediate value).
I made the following black box to make things less wasteful
{-# ANN myShiftL (InlineYamlPrimitive [Verilog] [__i|
BlackBox:
name: myShiftL
kind: Expression
type: 'myShiftL :: BitVector 16 -> BitVector 16 -> BitVector 16'
template: ~ARG[0] << ~ARG[1]|]) #-}
{-# OPAQUE myShiftL #-}
That does generate the expected code (note that myShiftL is wrapped in the function t (random name) as otherwise the black box wasn’t used but the Clash code was synthesized instead):
module t
( // Inputs
input wire [15:0] c$arg
, input wire [15:0] c$arg_0
// Outputs
, output wire [15:0] result
);
assign result = c$arg << c$arg_0;
endmodule
I am not the first person that wants to do some dynamic shifting and I do not think that it is that uncommon. Yet, I haven’t seen anyone using a solution such as the black box presented above. Am I missing some pitfall here?
I do not have Vivado available to check the test bench I wrote. Verilator failed to create a binary from the generated test bench .v. I will try to get Vivado up and running before fiddling with Verilator.
Please let me know if my solution is fine or help me come up with another solution.