散歩師・漫画居士のくだらなクラブ日記

ども、散歩師・漫画居士っす。散歩したり実働模型作ったりが趣味なんで、その時に思いついたこととか書くッス

VerilogHDLのマクロのヤバイとこ発見

// VerilogHDLでは、Cと同様にマクロが使えます
// Cの乱暴は変換に対して、VerilogHDLではマクロ変換に「'」をつけることで、
// 暴発変換防止が効いてます。
// = たとえば、
--
`define slice(xx,n,W)  xx[(n)*(W)+:(W)]

wire [15:0]  Datss ;
wire [3:0] Dats_s [0:3] ;
assign Dats_s[0] = `slice(Datss,0,4);
assign Dats_s[1] = `slice(Datss,1,4);
assign Dats_s[2] = `slice(Datss,2,4);
assign Dats_s[3] = `slice(Datss,3,4);
--
//の様にすれば、1次元<->2次元bit列の変換が簡単になります。
//Vanilla VerilogHDLでは、入出力ポートに2次元以上のbit列を使えませんが、
//矩形でよければ、これで問題を感じなくなりました。

--さらに
`define gen generate
`define gv genvar
`define fori(i,N) for(i=0;i<N;i=i+1)
`define egen endgenerate
`define eegen `e `egen
`b begin
`e end
`gen`gv gi ; `fori(gi,4) `b:g `a Dats_s[gi] = `slice(DATss,gi,4); `eegen 
--
--さらに
`define ga_arr(A,B,N,W) `gen`gv gi; `fori(N) `b:g `w[(N)-1:0] A[0:(W)-1];`w[(N)*(W)-1:0]B;`a A[gi]=`slice(B,gi,N); `eegen 
`ga_arr(Dsts_s,DATss,4,4)
--
//まで簡略化できますね。
//マクロのセットは ”`define.vh”におさめ、`inlude"./define.vh"して使ってます。


// = しかし、以下の様な表記では、大問題が発生します。
--
`define b begin
`define e end
`define COPY(x,y) `b y<=x; `e
`define exch(a,b) `COPY(b,a) `COPY(a,b) `e

always@(posedge CK)
    `exch(AA,BB)
--
//これは
--//目論見
    begin a<=b;b<=a; end
--
--//実際
  begin a<=begin;begin<=a; end
--
変換しないはずのbを`bと見誤って beginに変換してしまいます。

// = 回避は
 --
`define exch(a,B) `b a<=B;B<=a; `e
--
// しか思いついてないです。
// Quartus( Intel/Altera のFPGAコンパイラ)でも
// modelsim_alteraでも起きるので、
// VerilogHDLの言語仕様かなぁ?と


--2022-12-06tu 色々コードにミスがあったので修正