Wednesday, October 15, 2014

Wednesday Night Hack #6 - Verilog Code Generation using Python and Mako

I spent some time this evening playing with Python and Mako for the purposes of Verilog code generation.  The combination of tools is pretty sweet if you ask me.  Here is a worked out example for a parameterizable barrel shifter.

Mako template:

<%!
import math
def log2(x): return int(math.log(x, 2))
def e(x): return eval(str(x))
%>
module bshift_w${w} (
  input [${e(w-1)}:0] in,
  input [${e(log2(w)-1)}:0] shift,
  output reg [${e(w-1)}:0] out
);

% for i in range(1, w):

  wire [${e(w-1)}:0] out_${i} = {in[${e(w-i-1)}:0], in[${e(w-1)}:${e(w-i)}]};
% endfor

  always @* begin

    out = in;
    case (shift)
% for i in range(1, w):
      ${i}: out = out_${i};
% endfor
    endcase
  end

endmodule


Verilog output (w=4):

module bshift_w4 (
  input [3:0] in,
  input [1:0] shift,
  output reg [3:0] out
);

  wire [3:0] out_1 = {in[2:0], in[3:3]};
  wire [3:0] out_2 = {in[1:0], in[3:2]};
  wire [3:0] out_3 = {in[0:0], in[3:1]};

  always @* begin
    out = in;
    case (shift)
      1: out = out_1;
      2: out = out_2;
      3: out = out_3;
    endcase
  end

endmodule