ずっとFPGA初心者（その６：組み合わせ回路）

# 複数回路の組み合わせ（コンポーネント化）
今回のお題はある回路（親）から別の回路（子）を呼び出すもの。いつものように環境は[その１](https://qiita.com/infinite1oop/items/4b0f03b97ed859fbd954)と同じ。

## 構成図

ボタン押下によりLED点灯する。TwoFilesという親回路内で、連結した「onlypass」子回路と連結した「toggle」子回路を呼び出す。最終出力（LED4, LED6）だけではなく、連結途中出力の結果も外部出力する（LED0, LED2）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/64b72471-a30f-af4c-3c1b-304acb69fcee.png)

## 子回路「onlypass」
```vhdl:onlypass.vhd
library ieee;
use ieee.std_logic_1164.all;

entity onlypass is
  port (SIG_IN:   in std_logic;
        SIG_OUT: 	out std_logic);
end onlypass;

architecture RTL of onlypass is
begin
  SIG_OUT <= SIG_IN;
end RTL;
```
入力信号をそのまま出力信号とするのみである。

## 子回路「toggle」
```vhdl:toggle.vhd
library ieee;
use ieee.std_logic_1164.all;

entity toggle is
  port (SIG_IN:   in std_logic;
        SIG_OUT: 	out std_logic);
end toggle;

architecture RTL of toggle is
signal Q: std_logic:='1'; -- Init value is necessary for simulation.

begin
  SIG_OUT <= Q;
  
  process (SIG_IN)
  begin
	 if (SIG_IN'event and SIG_IN='0') then
		Q <= not Q;
    end if;
  end process; 
end RTL;
```

NOT回路。ただし、入力信号の状態を記憶し（内部信号「Q」の利用）、外部信号へとつなげる。また、入力信号が「0」へと変化した時に反転（NOT）させる。

## 親回路
```vhdl:TwoFiles.vhd
library ieee;
use ieee.std_logic_1164.all;

entity TwoFiles is
  port (BTN:	in std_logic;
        LED0: 	out std_logic;
		LED2: 	out std_logic;
		LED4: 	out std_logic;
		LED6:	out std_logic);
end TwoFiles;

architecture RTL of TwoFiles is
component onlypass
  port (SIG_IN:   in std_logic;
        SIG_OUT: 	out std_logic);
end component;

component toggle
  port (SIG_IN:   in std_logic;
        SIG_OUT: 	out std_logic);
end component;

signal P, Q, R, S: std_logic:='1'; -- Off: Init value is not necessary for similuation.

begin
	LED0 <= P;
	LED2 <= Q;
	LED4 <= R;
	LED6 <= S;
	
	U00: onlypass port map(SIG_IN => BTN, SIG_OUT => P);
	U01: onlypass port map(SIG_IN => P, SIG_OUT => R);
	
	U10: toggle port map(SIG_IN => BTN, SIG_OUT => Q);
	U11: toggle port map(SIG_IN => Q, SIG_OUT => S);
end RTL;
```

- 入力信号：BTN
- 出力信号：LED0, LED2, LED4, LED6
- 適切な名前をつけて（U00, U01, U10, U11）、子回路（「onlypass」と「toggle」）を呼び出し
- 内部信号と子回路の信号のマッピングに、「port map」を利用
- 内部信号：P（LED0および次の回路の入力信号にマッピング）
- 内部信号：Q（LED2および次の回路の入力信号にマッピング）
- 内部信号：R（LED4にマッピング）
- 内部信号：S（LED6にマッピング）


## Quartusでの複数ファイルのハンドリング
同一ディレクトリ内に上記VHDLファイルがあれば大丈夫のようだ（Buildの際に）。
![ディレクトリ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/fa6fc6af-802c-0142-9239-173429f70aea.png)
おそらく、下記メニューでもVHDLファイルを追加できると思われる。
![AddFiles.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/0b647092-5620-568d-e96d-260db15cbdcb.png)

## 実験
### シミュレーション
```vhdl:testsim.vhd
library ieee;
use ieee.std_logic_1164.all;

entity testsim is
end testsim;

architecture sim of testsim is 
constant t : time := 1 ps;

component TwoFiles
  port (
    BTN  : in  std_logic;
    LED0 : out std_logic;
    LED2 : out std_logic;
    LED4 : out std_logic;
    LED6 : out std_logic);
end component;

signal BUTTON, LED00, LED22, LED44, LED66: std_logic;

begin
  u100:TwoFiles port map (BTN=>BUTTON, LED0=>LED00, LED2=>LED22, LED4=>LED44, LED6=>LED66);

  process begin
    for N in 1 to 10 loop
      BUTTON <= '0'; wait for t * 10;
      BUTTON <= '1'; wait for t * 10;
  end loop;
  wait;
  end process;
end sim;
```

10psごとに「0」と「1」に変化、、を10回繰り返す。結果は下記のとおり。
![Simiulation.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/c13aa1a8-d0c4-32b1-1ae6-85ec6cafe89c.png)

### 実動作
（ピンアサインは本内容とあまり関連しないので省略。）

ボタンもLEDも負論理となる。ボタンが押されてない初期状態（High）では、いずれのLEDも点灯しない。子回路「onlypass」の出力結果となるLED0とLED4とは、ボタン押下時に点灯し、非ボタン押下時には非点灯。子回路「toggle」の出力結果となるLED2とLED6とは、入力信号変化時かつLow（0）時に点灯と非点灯とを繰り返す。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/e844e610-e9a0-b269-f34f-3e5567595092.png", width=80%>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/d914b310-84e7-592c-8c91-02a25f3d0c98.png", width=80%>