個人的によく使うベンダー(Xilinx, Intel)依存のHDL attribute

自分が良く使うattributeを列挙する。一応、説明らしきものも併記する。
XilinxとIntelのデバイスしか知らないのでその二つだけ。

Xilinxは、[ug901 合成(日本語pdf)](https://japan.xilinx.com/support/documentation/sw_manuals_j/xilinx2019_1/ug901-vivado-synthesis.pdf)を参考に、Intelは[Settings File Reference Manual](https://www.intel.com/content/www/us/en/programmable/documentation/eca1490998903550.html)を参考にする。
(Intelはqsfファイルから設定させたいみたいだが、今回紹介するattributeは実装に直結するので無理やりhdlに埋め込む)


書いてる人はVHDLの人なので、VerilogHDLは間違ってるかも。


# メタステーブル対策

自作のシンクロナイザを使用する場合は必須のもの(と思っている)。


## Xilinx `ASYNC_REG`

>このプロパティが指定されていると、配置ツールで同期チェーンに含まれるフリップフロップどうしが近くに配置され、MTBFを最長にできます。

ということらしい。

```verilog
(* ASYNC_REG = "TRUE" *) reg sig;
```

```vhdl
attribute ASYNC_REG : string;
attribute ASYNC_REG of sig : signal is "TRUE";
```

これをつけておくようにするとcdc_reportで意図しない非同期箇所が検出出来て幸せになれる。


## Intel `SYNCHRONIZER_IDENTIFICATION`

ほぼXilinxと同じ。

> If this option is set to 'Forced if Asynchronous', the TimeQuest Timing Analyzer identifies synchronization register chains if the software detects an asynchronous signal transfer, even if there is combinational logic or only one register in the chain.
... 中略
> If a synchronization register chain is identified with the 'Forced' or 'Forced if Asynchronous' option, then the TimeQuest Timing Analyzer reports the metastability MTBF for the chain.

```verilog
(* ALTERA_ATTRIBUTE = "-name SYNCHRONIZER_IDENTIFICATION FORCED_IF_ASYNCHRONOUS" *) reg sig;
```

```vhdl
attribute ALTERA_ATTRIBUTE : string;
attribute ALTERA_ATTRIBUTE of sig : signal is "-name SYNCHRONIZER_IDENTIFICATION ""FORCED IF ASYNCHRONOUS""";
```


# シフトレジスタ抑制

IOの制限などで物理配置が遠い場合、パイプラインレジスタを実装したつもりなのにシフトレジスタのプリミティブに推論されてしまうことがあるのを防止する。
個人的な経験では、Intelのほうが結構むりやりシフトレジスタに推論しがち。

## Xilinx `SRL_STYLE`

> `SRL_STYLE`属性は、SRLメモリの推論方法を指定します。有効な値は次のとおりです。
>
> * `register`: SRLは推論されず、レジスタのみが使用されます。
> * `srl`: 前後のレジスタなしでSRLが推論されます。
> * `srl_reg`: SRLが推論され、SRLの後にレジスタが1つ残されます。
> * `reg_srl`: SRLが推論され、SRLの前にレジスタが1つ残されます。
> * `reg_srl_reg`: SRLが推論され、SRLの前後にレジスタが1つずつ残されます。
> * `block`: ブロックRAM内にSRLが推論されます。

```verilog
(* SRL_STYLE = "register" *) reg sig;
```

```vhdl
attribute SRL_STYLE : string;
attribute SRL_STYLE of sig : signal is "register";  -- "register" "srl" "srl_reg" "reg_srl" "reg_srl_reg"
```

## Intel `AUTO_SHIFT_REGISTER_RECOGNITION`

にっくき(?)`altshift_taps`をやめていただく。

> Allows the Compiler to find a group of shift registers of the same length that can be replaced with the altshift_taps megafunction.

```verilog
(* ALTERA_ATTRIBUTE = "-name AUTO_SHIFT_REGISTER_RECOGNITION OFF" *) reg sig;
```

```vhdl
attribute ALTERA_ATTRIBUTE : string;
attribute ALTERA_ATTRIBUTE of sig : signal is "-name AUTO_SHIFT_REGISTER_RECOGNITION OFF";
```


# メモリ推論

レジスタにしたいのにブロックRAMになっちゃったり、以上に大きい分散RAMができたりするのを防ぐ。

## Xilinx `RAM_STYLE`

> `RAM_STYLE`は、合成でのメモリの推論方法を指定します。有効な値は次のとおりです。
>
> * `block` : RAMBタイプのコンポーネントが推論されるよう指定します。
> * `distributed` : LUTRAMが推論されるよう指定します。
> * `register` : RAMではなくレジスタが推論されるよう指定します。
> * `ultra` : UltraScale+™URAMプリミティブが使用されるよう指定します。

```verilog
(* RAM_STYLE = "registers" *) reg sig;
```

```vhdl
attribute RAM_STYLE : string;
attribute RAM_STYLE of sig : signal is "registers";
```

## Intel `RAMSTYLE`

> Sets the ramstyle attribute of a shift register, RAM, or ROM.  
>
> 中略  
>
> * M10K
> * M144K
> * M20K
> * M4K
> * M512
> * M9K
> * MEGARAM
> * MLAB
> * auto
> * logic


```verilog
(* RAMSTYLE = "registers" *) reg sig;
```

```vhdl
attribute RAMSTYLE : string;
attribute RAMSTYLE of sig : signal is "registers";
```

# その他

Intelの場合、自分だけかもしれないが(呪われている？)、合成でレジスタが消えて実機だけバグることがよくあるので、`PRESERVE`をつけることが多い。


```verilog
(* PRESERVE *) reg sig;
```

```vhdl
attribute PRESERVE : boolean;
attribute PRESERVE of sig : signal is TRUE;
```