去年発見した verilisp。使うのは簡単。
(module test ( (output a) (inout (2 b c)) (input d e) ) (display b c d e) ) (module test2 () (wire a b0 b1 d_ c0 c1 e) (test a (cat b0 b1) (name d d_) (name c (cat c0 c1)) e ) (display 2) ) (module clock ( (output clk) ) (always () (= clk (! clk)) ) )
これを verilisp にかけるとあらふしぎ
module test(a, b, c, d, e); output a; inout [1 : 0] b; inout [1 : 0] c; input d; input e; $display(b, c, d, e); endmodule module test2(); wire a; wire b0; wire b1; wire d_; wire c0; wire c1; wire e; test anon_0 (a, {b0, b1}, .d(d_), .c({c0, c1}), e); $display(2); endmodule module clock(clk); output clk; always begin clk = (!clk); end endmodule
これだけなら単なるコンバータだ。lisp なので defmacro が使える。
(defmacro make-test-macro (WORDSIZE) `(progn (module test_macro () (wire (,WORDSIZE sum_out) c_out) (reg (,(l_- WORDSIZE 1) sum_in) (,WORDSIZE b) a0 a1 c_in) ))) (make-test-macro 4)
これが
module test_macro(); wire [3 : 0] sum_out; wire c_out; reg [2 : 0] sum_in; reg [3 : 0] b; reg a0; reg a1; reg c_in; endmodule
こうなる。まぁ、これでもまだ。コンバータだ。もうちょいましな macro を作らないとなぁ。