VHDLの練習として4ビットCPU「CPU1738」(別府伸耕, トランジスタ技術2020年5月号)をMAX10 FPGAで作る

# 1. 概要
テキスト\(別府伸耕, 『[トランジスタ技術2020年5月号](https://toragi.cqpub.co.jp/post-445/)』\)はすべて基本ゲートを組み合わせて作り上げているが、とてもそんな真似はできないので、おおむね図34「CPUの全体接続図」(p.126)のモジュールごとにVHDLで記述して組み合わせる。またテキストはバスの選択にトライステートバッファーを使っているが、ここではマルチプレクサに置き換える。

クロックジェネレーターおよびROM (プログラムメモリー)は[CPUの創りかたのとき](https://qiita.com/cyq04000/items/45a4d53714183222c8cb#1%E6%A6%82%E8%A6%81)と同じく、メモリーブロックとして独立させる。使用したMAX10の評価ボードも[CPUの創りかたのとき](https://qiita.com/cyq04000/items/45a4d53714183222c8cb#1%E6%A6%82%E8%A6%81)と同じである。

# 2. モジュールごとに作る

## 2.1 CPU部を作る

### 2.1.1 ALUを作る
加減算のほかに、0出力、Aスルー、Bスルー、-Bスルーの各機能がある。
<details><summary>ソースコードを見る/隠す</summary><div>

```alu.vhdl
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity alu is
	generic(
		NUM_BITS: natural := 4
	);
	port(
		a: in std_logic_vector(NUM_BITS-1 downto 0);
		b: in std_logic_vector(NUM_BITS-1 downto 0);
		
		mux_a: in std_logic;
		mux_b: in std_logic;

		as        : in std_logic; -- when 0, add; when 1, sub;
		ld        : in std_logic;
		clk_inside: in std_logic;
		aclr_n    : in std_logic;
	
		add_sub: out std_logic_vector(NUM_BITS-1 downto 0);
		zero   : out std_logic;
		cout   : out std_logic
	);
end entity;

architecture rtl of alu is
	signal a_temp   : unsigned(NUM_BITS-1 downto 0);
	signal b_temp   : unsigned(NUM_BITS-1 downto 0);
	signal calc_temp: unsigned(NUM_BITS   downto 0);
begin

	a_temp <=
		(others => '0') when mux_a = '0' else -- mux_aが0ならオペランドaを強制的に0にし、
		unsigned(a);

	b_temp <=
		(others => '0') when mux_b = '0' else -- mux_bが0ならオペランドbを強制的に0にし、
		0-unsigned(b)   when as    = '1' else -- 引き算のときはオペランドbを2の補数にし、
		unsigned(b);
	
	calc_temp <= ('0' & a_temp) + b_temp; -- 1ビット拡張して和(差)を計算して、

	process(clk_inside)
	begin
		
		if aclr_n = '0' then
			-- 非同期クリアして、
			add_sub <= (others => '0');
		else
			-- 和(差)を非同期更新して、
			add_sub <= std_logic_vector(calc_temp)(NUM_BITS-1 downto 0);
		
			if rising_edge(clk_inside) then
				if ld then
					-- キャリーアウトを同期更新して、
					cout <= calc_temp(NUM_BITS);

					-- ゼロフラグを同期更新する。
					if calc_temp(NUM_BITS-1 downto 0) = 0 then
						zero <= '1';
					else
						zero <= '0';
					end if;

				end if;
			end if;

		end if;
	end process;
end architecture;
```
</div></details>



### 2.1.2 A、B、OUTの各レジスタおよびPCを作る
[CPUの創りかたのとき](https://qiita.com/cyq04000/items/45a4d53714183222c8cb#213-about%E3%81%AE%E5%90%84%E3%83%AC%E3%82%B8%E3%82%B9%E3%82%BF%E3%81%A8pc%E3%81%A8%E3%82%92%E4%BD%9C%E3%82%8B)と同じく、まず共通のカウンター兼レジスタを作っておいて、それを4つまとめて実体化する。

#### 2.1.2.1 共通のカウンター兼レジスタを作る
<details><summary>ソースコードを見る/隠す</summary><div>

```counter_register.vhdl
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity counter_register is
	generic(
		NUM_BITS: natural := 4
	);
	port(
		clk   : in std_logic;
		aclr_n: in std_logic;
		sload : in std_logic;
		d     : in std_logic_vector(NUM_BITS-1 downto 0);
		
		ena_count: in std_logic;
		
		q: out std_logic_vector(NUM_BITS-1 downto 0)
	);
end entity;

architecture rtl of counter_register is
	signal count: natural range 0 to 2**NUM_BITS-1; -- この信号をカウンターとして使う。
	constant COUNT_MAX: natural := 2**NUM_BITS-1;   -- カウンターのトップ値。
begin
	-- カウント値をそのまま出力する。
	q <= std_logic_vector(to_unsigned(count, NUM_BITS));
	
	process(all)
	begin

		-- !非同期リセット
		if aclr_n = '0' then
			count <= 0;

		elsif rising_edge(clk) then

			-- 同期ロード
			if sload then
				count <= to_integer(unsigned(d));

			-- 同期カウント
			elsif ena_count then
				if count >= COUNT_MAX then
					count <= 0;
				else
					count <= count + 1;
				end if;
			end if;
		end if;
	end process;
	
end architecture;
```
</div></details>


#### 2.1.2.2 それを4つ実体化して組み合わせる
<details><summary>ソースコードを見る/隠す</summary><div>

```registers.vhdl
library ieee;
use ieee.std_logic_1164.all;

entity registers is
	generic(
		NUM_BITS: natural := 4
	);
	port(
		inp: in std_logic_vector(NUM_BITS-1 downto 0);

		a_reg_ld: in std_logic;
		b_reg_ld: in std_logic;
		out_ld  : in std_logic;
		pc_ld   : in std_logic;
		
		clk_inside: in std_logic;
		aclr_n    : in std_logic;
		
		pc_up: in std_logic;

		a_reg  : out std_logic_vector(NUM_BITS-1 downto 0);
		b_reg  : out std_logic_vector(NUM_BITS-1 downto 0);
		out_reg: out std_logic_vector(NUM_BITS-1 downto 0);
		pc     : out std_logic_vector(NUM_BITS-1 downto 0)
	);
end entity;

architecture rtl of registers is
begin
	-- A_REGを実体化
	a_register: entity work.counter_register
		generic map(
			NUM_BITS => NUM_BITS
		)
		port map(
			clk       => clk_inside,
			aclr_n    => aclr_n,
			sload     => a_reg_ld,
			d         => inp,
			ena_count => '0', -- カウンターを無効化
			q         => a_reg
		);

	-- B_REGを実体化
	b_register: entity work.counter_register
		generic map(
			NUM_BITS => NUM_BITS
		)
		port map(
			clk       => clk_inside,
			aclr_n    => aclr_n,
			sload     => b_reg_ld,
			d         => inp,
			ena_count => '0',  -- カウンターを無効化
			q         => b_reg
		);

	-- OUT_REGを実体化
	out_register: entity work.counter_register
		generic map(
			NUM_BITS => NUM_BITS
		)
		port map(
			clk       => clk_inside,
			aclr_n    => aclr_n,
			sload     => out_ld,
			d         => inp,
			ena_count => '0',  -- カウンターを無効化
			q         => out_reg
		);

	-- PCを実体化
	program_counter: entity work.counter_register
		generic map(
			NUM_BITS => NUM_BITS
		)
		port map(
			clk       => clk_inside,
			aclr_n    => aclr_n,
			sload     => pc_ld,
			d         => inp,
			ena_count => pc_up,  -- カウンターを有効化
			q         => pc
		);

end architecture;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193936/644166e2-4ef9-5806-c42c-5e0c825037b7.png)
</div></details>


### 2.1.3 命令デコーダを作る
表10「命令デコーダの真理値表\(PC_LD以外\)」(p.124)、表11「"PC_LD=1"を出力するときの入力の組み合わせ」(p.124)の各表をそのまま書き写した。
<details><summary>ソースコードを見る/隠す</summary><div>

```instruction_decoder.vhdl
library ieee;
use ieee.std_logic_1164.all;

entity instruction_decoder is
	port(
		data: in std_logic_vector(7 downto 4);

		zero: in std_logic;
		cout: in std_logic;
		
		ld_en: in std_logic;
		
		a_reg_ld : out std_logic;
		b_reg_ld : out std_logic;
		b_reg_oe : out std_logic;
		rom_oe   : out std_logic;
		alu_as   : out std_logic;
		alu_oe   : out std_logic;
		alu_ld   : out std_logic;
		alu_mux_a: out std_logic;
		alu_mux_b: out std_logic;
		in_oe    : out std_logic;
		out_ld   : out std_logic;
		halt_n   : out std_logic;
		
		pc_ld: out std_logic
	);
end entity;

architecture rtl of instruction_decoder is
	subtype ascending_vect_t is std_logic_vector(0 to 11);
	signal truth_tbl: ascending_vect_t;
begin

	with data select
	truth_tbl <=
		ascending_vect_t'("100101001001") when 4d"0",  -- LD A, [Data]
		ascending_vect_t'("010101001001") when 4d"1",  -- LD B, [Data]
		ascending_vect_t'("101001001001") when 4d"2",  -- LD A, B
		ascending_vect_t'("01-001010001") when 4d"3",  -- LD B, A
		ascending_vect_t'("101001111001") when 4d"4",  -- ADD A, B
		ascending_vect_t'("101011111001") when 4d"5",  -- SUB A, B
		ascending_vect_t'("100101111001") when 4d"6",  -- ADD A, [Data]
		ascending_vect_t'("100111111001") when 4d"7",  -- SUB A, [Data]
		ascending_vect_t'("00-001010011") when 4d"8",  -- OUT A
		ascending_vect_t'("001001001011") when 4d"9",  -- OUT B
		ascending_vect_t'("000101001011") when 4d"10", -- OUT [Data]
		ascending_vect_t'("10-00000-101") when 4d"11", -- IN A
		ascending_vect_t'("000101001001") when 4d"12", -- JUMP [Address]
		ascending_vect_t'("000101001001") when 4d"13", -- JNC [Address]
		ascending_vect_t'("000101001001") when 4d"14", -- JNZ [Address]
		ascending_vect_t'("000-0-00-000") when 4d"15", -- HALT
		ascending_vect_t'(12b"0")         when others;

	a_reg_ld  <= truth_tbl(0) and ld_en;
	b_reg_ld  <= truth_tbl(1) and ld_en;
	b_reg_oe  <= truth_tbl(2);
	rom_oe    <= truth_tbl(3);
	alu_as    <= truth_tbl(4);
	alu_oe    <= truth_tbl(5);
	alu_ld    <= truth_tbl(6) and ld_en;
	alu_mux_a <= truth_tbl(7);
	alu_mux_b <= truth_tbl(8);
	in_oe     <= truth_tbl(9);
	out_ld    <= truth_tbl(10) and ld_en;
	halt_n    <= truth_tbl(11);

	pc_ld <=
		'1' when data = 4d"12"                else -- JUMP [Address]
		'1' when data = 4d"13" and cout = '0' else -- JNC [Address]
		'1' when data = 4d"14" and zero = '0' else -- JNZ [Address]
		'0';

end architecture;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193936/61f0cc0b-1636-deaf-cadb-5e54590f122e.png)
</div></details>

### 2.1.4 ステートマシンを作る
図29「ステート・マシンの内部ブロック図」(p.122)の接続図をそのままVHDLで表現した。
<details><summary>ソースコードを見る/隠す</summary><div>

```state_machine.vhdl
library ieee;
use ieee.std_logic_1164.all;

entity state_machine is
	port(
		halt_n    : in std_logic;
		pc_ld     : in std_logic;
		clk_inside: in std_logic;
		aclr_n    : in std_logic;

		clk_en: out std_logic;
		halt  : out std_logic;
		pc_up : out std_logic;
		ld_en : out std_logic
	);
end entity;

architecture rtl of state_machine is
	signal halt_temp : std_logic;
	signal pc_up_temp: std_logic;
begin
	process(all)
	begin

		halt_temp  <= halt_n nor pc_up; 
		pc_up_temp <= pc_ld  nor pc_up;

		if aclr_n = '0' then
			halt   <= '0';
			clk_en <= '1';
			pc_up  <= '0';
			ld_en  <= '1';

		elsif rising_edge(clk_inside) then
			halt   <=     halt_temp;
			clk_en <= not halt_temp;
			pc_up  <=     pc_up_temp;
			ld_en  <= not pc_up_temp;
		end if;

	end process;
end architecture;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193936/45063736-be57-f5e6-d332-001d557536c0.png)
</div></details>

### 2.1.5 CPUにまとめる
ここまで作ったモジュール同士を配線してCPUを作る。
<details><summary>ソースコードを見る/隠す</summary><div>

```cpu.vhdl
library ieee;
use ieee.std_logic_1164.all;

entity cpu is
	port(
		aclr_n : in std_logic;
		inp    : in std_logic_vector(3 downto 0);
		data   : in std_logic_vector(7 downto 0);
		clk    : in std_logic;

		halt   : out std_logic;
		a_reg  : out std_logic_vector(3 downto 0);
		b_reg  : out std_logic_vector(3 downto 0);
		address: out std_logic_vector(3 downto 0);
		outp   : out std_logic_vector(3 downto 0)
	);
end entity;

architecture rtl of cpu is

	signal alu_b     : std_logic_vector(3 downto 0);
	signal alu_mux_a : std_logic;
	signal alu_mux_b : std_logic;
	signal alu_as    : std_logic;
	signal alu_ld    : std_logic;
	signal clk_inside: std_logic;
	signal add_sub   : std_logic_vector(3 downto 0);
	signal zero      : std_logic;
	signal cout      : std_logic;
	
	signal ld_en    : std_logic;
	signal a_reg_ld : std_logic;
	signal b_reg_ld : std_logic;
	signal b_reg_oe : std_logic;
	signal rom_oe   : std_logic;
	signal alu_oe   : std_logic;
	signal in_oe    : std_logic;
	signal out_ld   : std_logic;
	signal halt_n   : std_logic;
	signal pc_ld    : std_logic;
	
	signal clk_en: std_logic;
	signal pc_up : std_logic;
	
	signal registers_in: std_logic_vector(3 downto 0);
	
	signal a_reg_inside: std_logic_vector(3 downto 0);

begin

	module_alu: entity work.alu
	port map(
		a          => a_reg_inside,
		b          => alu_b,
		mux_a      => alu_mux_a,
		mux_b      => alu_mux_b,
		as         => alu_as,  -- when 0, add; when 1, sub;
		ld         => alu_ld,
		clk_inside => clk_inside,
		aclr_n     => aclr_n, -- 外部へ接続
		add_sub    => add_sub,
		zero       => zero,
		cout       => cout
	);
	
	module_id:entity work.instruction_decoder
	port map(
		data      => data(7 downto 4), -- 外部へ配線
		zero      => zero,
		cout      => cout,
		ld_en     => ld_en ,
		a_reg_ld  => a_reg_ld,
		b_reg_ld  => b_reg_ld,
		b_reg_oe  => b_reg_oe,
		rom_oe    => rom_oe,
		alu_as    => alu_as,
		alu_oe    => alu_oe,
		alu_ld    => alu_ld,
		alu_mux_a => alu_mux_a,
		alu_mux_b => alu_mux_b,
		in_oe     => in_oe,
		out_ld    => out_ld,
		halt_n    => halt_n,
		pc_ld     => pc_ld
	);
	
	module_state_machine:entity work.state_machine
	port map(
		halt_n     => halt_n,
		pc_ld      => pc_ld,
		clk_inside => clk_inside,
		aclr_n     => aclr_n, -- 外部へ配線
		clk_en     => clk_en,
		halt       => halt, -- 外部へ配線
		pc_up      => pc_up,
		ld_en      => ld_en
	);

	module_registers:entity work.registers
	port map(
		inp        => registers_in,
		a_reg_ld   => a_reg_ld,
		b_reg_ld   => b_reg_ld,
		out_ld     => out_ld,
		pc_ld      => pc_ld,
		clk_inside => clk_inside,
		aclr_n     => aclr_n, -- 外部へ配線
		pc_up      => pc_up,
		a_reg      => a_reg_inside,
		b_reg      => b_reg,
		out_reg    => outp, -- 外部へ配線
		pc         => address  -- 外部へ配線
	);
	
	clk_inside <= clk_en and clk;
	
	-- これがトライステートバッファーから代えたマルチプレクサ
	-- ALUの出力かインポートかいずれかをレジスタ群へ渡す。
	registers_in <=
		add_sub when alu_oe else
		inp     when in_oe  else
		(others => '0');

	-- これもトライステートバッファーから代えたマルチプレクサ
	-- Bレジスタかプログラムメモリーに含まれるオペランドかいずれかをALUへ渡す。
	alu_b <=
		b_reg            when b_reg_oe else
		data(3 downto 0) when rom_oe   else
		(others => '0');

	-- A、Bレジスタも確認のため外へ出す。
	a_reg <= a_reg_inside;
	b_reg <= b_reg;
end architecture;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193936/2a4253a2-004d-d124-e963-3e5ba57764b7.png)
</div></details>


## 2.2 クロックジェネレーターを作る
[ここで作ったもの](https://qiita.com/cyq04000/items/45a4d53714183222c8cb#22-%E3%82%AF%E3%83%AD%E3%83%83%E3%82%AF%E3%82%B8%E3%82%A7%E3%83%8D%E3%83%AC%E3%83%BC%E3%82%BF%E3%83%BC%E3%82%92%E4%BD%9C%E3%82%8B)とまったく同じ。

## 2.3 ROM (プログラムメモリー)を作る
[ここで作ったもの](https://qiita.com/cyq04000/items/45a4d53714183222c8cb#23-rom-%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%83%A1%E3%83%A2%E3%83%AA%E3%83%BC%E3%82%92%E4%BD%9C%E3%82%8B)とまったく同じ。

## 2.4 全部組み合わせてCPU1738を完成させる
<details><summary>ソースコードを見る/隠す</summary><div>

```cpu1738.vhdl
library ieee;
use ieee.std_logic_1164.all;

entity cpu1738 is
	port(
		source_clk   : in std_logic;
		manual_clk_in: in std_logic;
		sel          : in std_logic_vector(1 downto 0);
		aclr_n       : in std_logic;
		inp          : in std_logic_vector(3 downto 0);

		halt   : out std_logic;
		a_reg  : out std_logic_vector(3 downto 0);
		b_reg  : out std_logic_vector(3 downto 0);
		outp   : out std_logic_vector(3 downto 0);
		clk_out: out std_logic
	);
end entity;

architecture rtl of cpu1738 is
	signal address      : std_logic_vector(3 downto 0);
	signal data         : std_logic_vector(7 downto 0);
	signal clk_inside   : std_logic;
	signal delayed_clk_0: std_logic;
	signal delayed_clk_1: std_logic;
begin
	module_cpu: entity work.cpu
	port map(
		aclr_n  => aclr_n, -- 外部へ配線
		inp     => inp, -- 外部へ配線
		data    => data,
		clk     => delayed_clk_1,
		halt    => halt, -- 外部へ配線
		a_reg   => a_reg, -- 外部へ配線
		b_reg   => b_reg, -- 外部へ配線
		address => address,
		outp    => outp -- 外部へ配線
	);
	
	module_clk_gen: entity work.clk_gen
	port map(
		clk           => source_clk,
		manual_clk_in => manual_clk_in,
		sel           => sel,
		clk_out       => clk_inside
	);
	
	module_rom: entity work.rom
	port map(
		clock   => clk_inside,
		address => address,
		q       => data
	);

	-- 確認のためクロックジェネレーターの出力を外へ出す。
	clk_out <= clk_inside;

	--『CPUの創りかた』のときと同じく、CPUへ与えるクロックを少し遅らせる。
	process(clk_out)
	begin
		if rising_edge(source_clk) then
			delayed_clk_0 <= clk_inside;
			delayed_clk_1 <= delayed_clk_0;
		end if;
	end process;
end architecture;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193936/1718cb8b-4940-b458-db4e-e02cf81c348b.png)
</div></details>

# 3. ROM (プログラムメモリー)の初期化ファイルを作る

初期化ファイル\(.mif\)を生成するためのアセンブラのようなものはPythonで作った。
<details><summary>ソースコードを見る/隠す</summary><div>

```example_div.py
def generate_mif(file_name, width, depth, rom):
    f = open(file_name, "w")
    f.write("WIDTH=%d;\n" % width)
    f.write("DEPTH=%d;\n" % depth)
    f.write("ADDRESS_RADIX=UNS;\n")
    f.write("DATA_RADIX=BIN;\n")
    f.write("CONTENT BEGIN\n")
    format_of_code = "0" + str(width) + "b"
    for i in range(depth):
        machine_code = format(rom[i], format_of_code)
        f.write("%10d   :   %s;\n" % (i, machine_code))
    f.write("END;\n")
    f.close()

def LD_A(Data)   : return ( 0 << 4)|(Data & 0xF)    # A ← [Data]
def LD_B(Data)   : return ( 1 << 4)|(Data & 0xF)    # B ← [Data]
def LD_AB()      : return ( 2 << 4)                 # A ← B
def LD_BA()      : return ( 3 << 4)                 # B ← A
def ADD_AB()     : return ( 4 << 4)                 # A ← A + B
def SUB_AB()     : return ( 5 << 4)                 # A ← A - B
def ADD_A(Data)  : return ( 6 << 4)|(Data & 0xF)    # A ← A + [Data]
def SUB_A(Data)  : return ( 7 << 4)|(Data & 0xF)    # A ← A - [Data]
def OUT_A()      : return ( 8 << 4)                 # OUT ← A
def OUT_B()      : return ( 9 << 4)                 # OUT ← B
def OUT(Data)    : return (10 << 4)|(Data & 0xF)    # OUT ← [Data]
def IN_A()       : return (11 << 4)                 # A ← IN
def JUMP(Address): return (12 << 4)|(Address & 0xF) # PC ← [Address]
def JNC(Address) : return (13 << 4)|(Address & 0xF) # PC ← [Address] if NOT Carry
def JNZ(Address) : return (14 << 4)|(Address & 0xF) # PC ← [Address] if NOT Zero
def HALT()       : return (15 << 4)                 # HALT

FILE_NAME = "rom_init.mif"
WIDTH =  8
DEPTH = 16
_ = [0] * DEPTH


# テキストのプログラム例(4)
# インポートとアウトポートとを直結しておく。
# 9/2=4(0100)余り1を計算する。
# 0111(9-2=7)、0101(9-2-2=5)、0011(9-2-2-2=3)、0001(9-2-2-2-2=1)の順に表示されたあと、
# 0100(9/2=4)と表示される。
_[0] = LD_A(9)  # 割られる数
_[1] = LD_B(0)  # 何回引き算ができたかの初期値
_[2] = SUB_A(2) # 割る数(引く数)
_[3] = JNC(10)  # 引いた結果が負なら、ループを抜けて10番地へ
_[4] = OUT_A()  # 今の引き算結果(すなわち余り)を出力して、
_[5] = LD_AB()  # 引き算できた回数をこの3行でインクリメントして、
_[6] = ADD_A(1)
_[7] = LD_BA()
_[8] = IN_A()   # 今の引き算結果(すなわち余り)(今OUTレジスタにある)を読み込んで、
_[9] = JUMP(2)  # 引き算を繰り返す。
_[10] = IN_A()  # (引いた結果が負なら3番地から)余り(今OUTレジスタにある)をAに格納し、
_[11] = OUT_B() # 商(何回引き算ができたか)を出力する。
_[12] = HALT()

generate_mif(FILE_NAME, WIDTH, DEPTH, _)
```
</div></details>

↓ これが、生成された.mifファイル。
<details><summary>ソースコードを見る/隠す</summary><div>

```rom_int.mif
WIDTH=8;
DEPTH=16;
ADDRESS_RADIX=UNS;
DATA_RADIX=BIN;
CONTENT BEGIN
         0   :   00001001;
         1   :   00010000;
         2   :   01110010;
         3   :   11011010;
         4   :   10000000;
         5   :   00100000;
         6   :   01100001;
         7   :   00110000;
         8   :   10110000;
         9   :   11000010;
        10   :   10110000;
        11   :   10010000;
        12   :   11110000;
        13   :   00000000;
        14   :   00000000;
        15   :   00000000;
END;
```
</div></details>


# 4. 動かしてみる
9/2=4余り1を計算する。右から4ビットずつ、Bレジスタ、Aレジスタ、一番左がOUTレジスタ。OUTレジスタに7、5、3、1の順に表示されて、最後に商4が表示される。余り1がAレジスタに表示される。    
<iframe width="560" height="315" src="https://www.youtube.com/embed/cUSa1gxck4o" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
 

# 5. ファイル一式
[https://github.com/ti-nspire/VHDL_for_Quartus_Prime/tree/main/CPU1738](https://github.com/ti-nspire/VHDL_for_Quartus_Prime/tree/main/CPU1738)


# 6. 参考

https://qiita.com/cyq04000/items/45a4d53714183222c8cb

https://qiita.com/cyq04000/items/db60e7e08929115f1d2e

https://qiita.com/cyq04000/items/95e58d333e22c308a5ec

https://qiita.com/cyq04000/items/5e2b45f0a34e5b3fc63b



# 補遺A.
[フルコンパイルせずに.mifファイルのデータだけを入れ換える方法](https://ti-nspire.hatenablog.com/entry/2021/09/17/135507)