読者です 読者をやめる 読者になる 読者になる

verilog書く人

自称ASIC設計者です。どなたかkaggle一緒に出ましょう。

Veriloggenを使ってみた、そしてVerilogメタプログラミングの新地平を見た

以前から気になっていたshtaxxx氏作Veriloggenを実際に使ってみた。

これは…熱い!

 

 

私が書いてみたコード↓

 

import sys
import os
from veriloggen import *

def CKDIV():

def gen_divided_clk(m, clk):
div_clk = m.Reg(clk.name + "_divided", 1)
m.Always(Posedge(clk))(
If(rst)(
div_clk(0)
).Else(
div_clk(div_clk + 1)
)
)
return div_clk

m = Module('CLK_DIVIDER')
clk = m.Input('CLK')
rst = m.Input('RST')

clk_temp = clk
for i in range(3):
clk_temp = gen_divided_clk(m, clk_temp)

return m

if __name__ == '__main__':
ckdiv = CKDIV()
print(ckdiv.to_verilog())

for文の中でクロック分周を繰り返しているのが肝。

生成されたverilog↓

module CLK_DIVIDER
(
input [0:0] CLK,
input [0:0] RST

);
reg [(1 - 1):0] CLK_divided;
reg [(1 - 1):0] CLK_divided_divided;
reg [(1 - 1):0] CLK_divided_divided_divided;
always @(posedge CLK)
begin
if(RST) begin
CLK_divided <= 0;
end
else begin
CLK_divided <= (CLK_divided + 1);
end
end
always @(posedge CLK_divided)
begin
if(RST) begin
CLK_divided_divided <= 0;
end
else begin
CLK_divided_divided <= (CLK_divided_divided + 1);
end
end
always @(posedge CLK_divided_divided)
begin
if(RST) begin
CLK_divided_divided_divided <= 0;
end
else begin
CLK_divided_divided_divided <= (CLK_divided_divided_divided + 1);
end
end
endmodule

 

うは!意図通りできてる!!!

for文に入れるだけで三回クロックが分周できてる!!!

 

これは、楽しいです。

 

私が考えたveriloggenのメリットとしては、

・verilogのダサい文法が回避できる(begin - endとか)

・柔軟にメタプログラミング的なことが出来る。genvarでもある程度できるが、規則的にレジスタ名を生成するようなことはできない。

・抽象レベルでの回路定義。なんかちょっとパラメータ入れたらおっきいコード吐くみたいな。

 

今後機能がたくさん追加されるようなので、おっかけとくことにします。