This is turning out to be a very fun experiment. In about 150 lines of Python code, I have put together a very nice tool for Verilog code generation. If there is interest in the source code, please send me an e-mail.
On an unrelated note, I recently stumbled upon the following website: http://regex101.com/#python. It is a wonderfully written online regex tester, 5/5 stars and highly recommended.
Here is the template code :
top.v.mako :
<%! from vmako import connect, ev,instance,log2 %>
module top;
bit clk = 0;
## instantiate 2x 'w'-bit wide barrel shifters
% for i in range(0, 2):
## define local variable inst
<% inst = 'u{}_bshf_{}'.format(i,w) %>
${instance('$HOME/raid/vmako/templates/bshift.v.mako',
inst,
w=w
)}
## connect dest <- src
${connect((inst, 'clk'), ('', 'clk'))}
% endfor
## example connect statement between modules
${connect(('u1_bshf_'+str(w), 'in'), ('u0_bshf_'+str(w), 'out'))}
endmodule
bshift.v.mako :
<%! from vmako import connect,ev,instance,log2 %>
module bshift_${w} (
input clk,
input [${ev(w-1)}:0] in,
input [${ev(log2(w)-1)}:0] cnt,
output reg [${ev(w-1)}:0] out
);
% for i in range(1, w):
wire [${ev(w-1)}:0] out_${i} = {in[${ev(w-i-1)}:0], in[${ev(w-1)}:${ev(w-i)}]};
% endfor
always @(*)
case (cnt)
% for i in range(1, w):
${i}: out = out_${i};
% endfor
default: out = in;
endcase
${instance('$HOME/raid/vmako/templates/dff.v.mako',
"u_dff",
w=w
)}
endmodule
dff.v.mako :
<%! from vmako import ev,log2 %>
module dff_${w} (
input clk,
input [${ev(w-1)}:0] d,
output reg [${ev(w-1)}:0] q
);
always @(posedge clk)
q <= d;
endmodule
Here is the generated code :
top.v :
module top;
bit clk = 0;
// ---- instance:u0_bshf_4 [begin] ----
wire u0_bshf_4_clk;
wire [3:0] u0_bshf_4_in;
wire [1:0] u0_bshf_4_cnt;
wire [3:0] u0_bshf_4_out;
bshift_4 u0_bshf_4 (
.clk(u0_bshf_4_clk)
,.in(u0_bshf_4_in)
,.cnt(u0_bshf_4_cnt)
,.out(u0_bshf_4_out)
);
// ---- instance:u0_bshf_4 [end] ----
// connect:dest=('u0_bshf_4', 'clk') src=('', 'clk')
assign u0_bshf_4_clk = clk;
// ---- instance:u1_bshf_4 [begin] ----
wire u1_bshf_4_clk;
wire [3:0] u1_bshf_4_in;
wire [1:0] u1_bshf_4_cnt;
wire [3:0] u1_bshf_4_out;
bshift_4 u1_bshf_4 (
.clk(u1_bshf_4_clk)
,.in(u1_bshf_4_in)
,.cnt(u1_bshf_4_cnt)
,.out(u1_bshf_4_out)
);
// ---- instance:u1_bshf_4 [end] ----
// connect:dest=('u1_bshf_4', 'clk') src=('', 'clk')
assign u1_bshf_4_clk = clk;
// connect:dest=('u1_bshf_4', 'in') src=('u0_bshf_4', 'out')
assign u1_bshf_4_in = u0_bshf_4_out;
endmodule
bshift.v :
module bshift_4 (
input clk,
input [3:0] in,
input [1:0] cnt,
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 @(*)
case (cnt)
1: out = out_1;
2: out = out_2;
3: out = out_3;
default: out = in;
endcase
// ---- instance:u_dff [begin] ----
wire u_dff_clk;
wire [3:0] u_dff_d;
wire [3:0] u_dff_q;
dff_4 u_dff (
.clk(u_dff_clk)
,.d(u_dff_d)
,.q(u_dff_q)
);
// ---- instance:u_dff [end] ----
endmodule
dff.v :
module dff_4 (
input clk,
input [3:0] d,
output reg [3:0] q
);
always @(posedge clk)
q <= d;
endmodule
Wednesday, October 29, 2014
Wednesday Night Hack #7 - More Experiments with Mako for Verilog
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):
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
Subscribe to:
Posts (Atom)