FPGA MAX10(7)-モジュールのインスタンス化

前回は、DE10-Lite評価ボードを使用して、24時間をカウントする機能を改良しまじた。機能的には問題ないと思いますが、1カウンタ早く処理をするように改善したいので改良を行いました。

前回の内容は下記を参照してください

FPGA MAX10(6)-24時間カウンタ回路②

前回の内容ですが、7セグメントの出力部分が、出力先と条件以外はほぼ同じような記述がされています。この部分を関数のように処理ができると思うので前回作成した24時間カウンタ機能のVHDLファイルを改良したいと思います。

24時間カウンタ機能の仕様は下記の通りです。

  • DE10-Liteには、7セグメントが6個用意されています。
  • その中の2個ずつを、秒、分、時に割り当てます。
  • Resetボタンを押すと、00時00分00秒になります。
  • 24時間になった場合、00時00分00秒になります。

それでは、改良していきたいと思います。前回のプロジェクトファイルを開いて、新規VHDLファイルを追加、下記のようにコードを記述して、7セグメントに数値を表示するモジュールを作成しました。

FPGA MAX10(6)-24時間カウンタ回路②

前回に、DE10-Lite評価ボードを使用して、4時間をカウントする機能を作成しました。前回の内容は下記を参照してください。

FPGA MAX10(5)-24時間カウンタ回路①

24時間カウンタ機能の仕様は下記の通りです。

  • DE10-Liteには、7セグメントが6個用意されています。
  • その中の2個ずつを、秒、分、時に割り当てます。
  • Resetボタンを押すと、00時00分00秒になります。
  • 24時間になった場合、00時00分00秒になります。

今回は、DE10-Lite評価ボードを使用して、24時間をカウントする機能を改良していきたいと思います。今回も使用する言語は、VHDLです。前回述べたのように、機能的には問題ないと思いますが、カウンタのズレが発生していると思います。

例えば、7セグメントに信号を送る処理をprocess処理のcase文で行っていますが、ここもカウンタが更新されて1クロック遅れて更新されていると思いわれます。下記のように回路図でみるとレジスタから出力されています。そのため、1クロック遅れていると思います。

今回は、ここらへん内容を改良していきたいと思います。それでは、改良していきたいと思います。

前回のプロジェクトファイルを開いて、下記のようにVHDLファイルを改良しました。

FPGA MAX10(5)-24時間カウンタ回路①

前回に、DE10-Lite評価ボードを使用して、LEDの点灯をシフトする機能を作成しました。前々回の内容は下記を参照してください。

FPGA MAX10(4)-LEDシフト点灯回路

今回は、DE10-Lite評価ボードを使用して、24時間をカウントする機能を
構築したいと思います。今回も使用する言語は、VHDLです。

24時間カウンタ機能の仕様は下記の通りです。

  • DE10-Liteには、7セグメントが6個用意されています。その中の2個ずつを、秒、分、時に割り当てます。
  • Resetボタンを押すと、00時00分00秒になります。
  • 24時間になった場合、00時00分00秒になります。

それでは、機能を構築していきたいと思います。前回使用したプロジェクトをコピーして使用します。前回の内容は、下記のリンクを参考にしてください。PLLファイルの生成なども行っています。

FPGA MAX10(4)-LEDシフト点灯回路

クロックはPLLで生成した「10MHz」を使用します。VHDLファイルに動作内容を記述していきます。下記のように記述しました。

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.std_logic_arith.all;

entity sec_counter_top is	-- Output pin
	port(
		CLK			: in  std_logic;  -- 50MHz Clock
		RST_N			: in  std_logic;
		LED_OUT		: out std_logic_vector(9 downto 0);
		SEG7_0_OUT	: out std_logic_vector(7 downto 0);
		SEG7_1_OUT	: out std_logic_vector(7 downto 0);
		SEG7_2_OUT	: out std_logic_vector(7 downto 0);
		SEG7_3_OUT	: out std_logic_vector(7 downto 0);
		SEG7_4_OUT	: out std_logic_vector(7 downto 0);
		SEG7_5_OUT	: out std_logic_vector(7 downto 0)
	);
end sec_counter_top;

architecture rtl of sec_counter_top is -- Internal process

	component pll is -- pll
		port(
			inclk0	: in  std_logic;	-- 50MHz Clock
			c0			: out std_logic	-- 10MHz Clock
		);
	end component;

	signal s_clk			: std_logic;	-- 10MHz Clock signal
	signal en_sec_1     	: std_logic;
	signal en_min_1     	: std_logic;
	signal en_hour_1    	: std_logic;
	signal en_sec_10    	: std_logic;
	signal en_min_10    	: std_logic;
	signal en_hour_10   	: std_logic;
	signal en_hour_flg  	: std_logic_vector(3 downto 0);
	signal cnt 				: std_logic_vector(23 downto 0);
	signal sec_1_cnt 		: std_logic_vector(3 downto 0);
	signal min_1_cnt 		: std_logic_vector(3 downto 0);
	signal hour_1_cnt 	: std_logic_vector(3 downto 0);
	signal min_10_cnt 	: std_logic_vector(3 downto 0);
	signal sec_10_cnt 	: std_logic_vector(3 downto 0);
	signal hour_10_cnt 	: std_logic_vector(3 downto 0);
	signal counter_led	: std_logic_vector(9 downto 0);

	begin

		u0_pll : pll
			port map(
				inclk0	=> CLK, --in  std_logic(50MHz)
				c0			=> s_clk --out std_logic(10MHz)
			);
		
		-- 1 sec
--		en_sec_1 <= '1' when (cnt = X"AD9") else '0'; -- 1 / 3600 sec
		en_sec_1 <= '1' when (cnt = X"989659") else '0'; -- 1 sec

		process(s_clk, RST_N) -- s_clkに変化があった時
			begin
				if(RST_N = '0')then
					cnt <= (others=>'0');
				elsif(s_clk'event and s_clk = '1')then -- s_clk 変化有り 且つ s_clk = 1の時 →クロックの立ち上がりエッジ
					if(en_sec_1 = '1')then
						cnt <= (others=>'0');
					else
						cnt <= cnt + '1';
					end if;
				end if;
		end process;
		
		process(s_clk, RST_N)
			begin
				if(RST_N = '0')then
					sec_1_cnt <= X"0";
				elsif(s_clk'event and s_clk = '1')then -- s_clk 変化有り 且つ s_clk = 1の時 →クロックの立ち上がりエッジ
					if(en_sec_1 = '1')then
						sec_1_cnt <= sec_1_cnt + '1';
					else
						if(sec_1_cnt = X"A")then
							sec_1_cnt <= X"0";
						end if;
					end if;
				end if;
		end process;
		
		process(s_clk, RST_N)
			begin
				if(RST_N = '0')then
					SEG7_0_OUT <= "11000000"; 
				elsif(s_clk'event and s_clk = '1')then -- s_clk 変化有り 且つ s_clk = 1の時 →クロックの立ち上がりエッジ
					case sec_1_cnt is
						when X"1" =>
							SEG7_0_OUT <= "11111001";
						when X"2" =>
							SEG7_0_OUT <= "10100100";
						when X"3" =>
							SEG7_0_OUT <= "10110000";
						when X"4" =>
							SEG7_0_OUT <= "10011001";
						when X"5" =>
							SEG7_0_OUT <= "10010010";
						when X"6" =>
							SEG7_0_OUT <= "10000010";
						when X"7" =>
							SEG7_0_OUT <= "11011000";
						when X"8" =>
							SEG7_0_OUT <= "10000000";
						when X"9" =>
							SEG7_0_OUT <= "10011000"; 
						when others =>
							SEG7_0_OUT <= "11000000"; 
					end case;
				end if;
		end process;
		
		-- 10 sec
		en_sec_10 <= '1' when (sec_1_cnt = X"A") else '0'; -- 10 sec	

		process(s_clk, RST_N)
			begin
				if(RST_N = '0')then
--					sec_10_cnt <= X"5";
					sec_10_cnt <= X"0";
				elsif(s_clk'event and s_clk = '1')then -- s_clk 変化有り 且つ s_clk = 1の時 →クロックの立ち上がりエッジ
					if(en_sec_10 = '1')then
						sec_10_cnt <= sec_10_cnt + '1';
					else
						if(sec_10_cnt = X"6")then
							sec_10_cnt <= X"0";
						end if;
					end if;
				end if;
		end process;

		process(s_clk, RST_N)
			begin
				if(RST_N = '0')then
--					SEG7_1_OUT <= "10010010"; 
					SEG7_1_OUT <= "11000000"; 
				elsif(s_clk'event and s_clk = '1')then -- s_clk 変化有り 且つ s_clk = 1の時 →クロックの立ち上がりエッジ
					case sec_10_cnt is
						when X"1" =>
							SEG7_1_OUT <= "11111001";
						when X"2" =>
							SEG7_1_OUT <= "10100100";
						when X"3" =>
							SEG7_1_OUT <= "10110000";
						when X"4" =>
							SEG7_1_OUT <= "10011001";
						when X"5" =>
							SEG7_1_OUT <= "10010010"; 
						when others =>
							SEG7_1_OUT <= "11000000"; 
					end case;
				end if;
		end process;
		
		
		-- 1 min
		en_min_1 <= '1' when (sec_10_cnt = X"6") else '0'; -- 1 min
		
		process(s_clk, RST_N)
			begin
				if(RST_N = '0')then
--					min_1_cnt <= X"9";
					min_1_cnt <= X"0";
				elsif(s_clk'event and s_clk = '1')then -- s_clk 変化有り 且つ s_clk = 1の時 →クロックの立ち上がりエッジ
					if(en_min_1 = '1')then
						min_1_cnt <= min_1_cnt + '1';
					else
						if(min_1_cnt = X"A")then
							min_1_cnt <= X"0";
						end if;
					end if;
				end if;
		end process;

		process(s_clk, RST_N)
			begin
				if(RST_N = '0')then
--					SEG7_2_OUT <= "10011000"; 
					SEG7_2_OUT <= "11000000"; 
				elsif(s_clk'event and s_clk = '1')then -- s_clk 変化有り 且つ s_clk = 1の時 →クロックの立ち上がりエッジ
					case min_1_cnt is
						when X"1" =>
							SEG7_2_OUT <= "11111001";
						when X"2" =>
							SEG7_2_OUT <= "10100100";
						when X"3" =>
							SEG7_2_OUT <= "10110000";
						when X"4" =>
							SEG7_2_OUT <= "10011001";
						when X"5" =>
							SEG7_2_OUT <= "10010010";
						when X"6" =>
							SEG7_2_OUT <= "10000010";
						when X"7" =>
							SEG7_2_OUT <= "11011000";
						when X"8" =>
							SEG7_2_OUT <= "10000000";
						when X"9" =>
							SEG7_2_OUT <= "10011000"; 	
						when others =>
							SEG7_2_OUT <= "11000000"; 
					end case;
				end if;
		end process;
		
		-- 10 min
		en_min_10 <= '1' when (min_1_cnt = X"A") else '0'; -- 10 min
		
		process(s_clk, RST_N)
			begin
				if(RST_N = '0')then
--					min_10_cnt <= X"5";
					min_10_cnt <= X"0";
				elsif(s_clk'event and s_clk = '1')then -- s_clk 変化有り 且つ s_clk = 1の時 →クロックの立ち上がりエッジ
					if(en_min_10 = '1')then
						min_10_cnt <= min_10_cnt + '1';
					else
						if(min_10_cnt = X"6")then
							min_10_cnt <= X"0";
						end if;
					end if;
				end if;
		end process;

		process(s_clk, RST_N)
			begin
				if(RST_N = '0')then
--					SEG7_3_OUT <= "10010010"; 
					SEG7_3_OUT <= "11000000"; 
				elsif(s_clk'event and s_clk = '1')then -- s_clk 変化有り 且つ s_clk = 1の時 →クロックの立ち上がりエッジ
					case min_10_cnt is
						when X"1" =>
							SEG7_3_OUT <= "11111001";
						when X"2" =>
							SEG7_3_OUT <= "10100100";
						when X"3" =>
							SEG7_3_OUT <= "10110000";
						when X"4" =>
							SEG7_3_OUT <= "10011001";
						when X"5" =>
							SEG7_3_OUT <= "10010010";
						when others =>
							SEG7_3_OUT <= "11000000"; 
					end case;
				end if;
		end process;
		
		-- 1 hour
		en_hour_1 <= '1' when (min_10_cnt = X"6") else '0'; -- 1 hour
		
		process(s_clk, RST_N)
			begin
				if(RST_N = '0')then
--					hour_1_cnt <= X"9";
					hour_1_cnt <= X"0";
					en_hour_flg <= X"F";
				elsif(s_clk'event and s_clk = '1')then -- s_clk 変化有り 且つ s_clk = 1の時 →クロックの立ち上がりエッジ
					if(en_hour_1 = '1')then
						hour_1_cnt <= hour_1_cnt + '1';
						en_hour_flg <= X"E";
					elsif(en_hour_flg = X"E")then
						if(hour_10_cnt = X"2")then
							if(hour_1_cnt = X"4")then
								en_hour_flg <= X"4";
							end if;
						else
							if(hour_1_cnt = X"A")then
								en_hour_flg <= X"A";
							end if;
						end if;
					else
						if(en_hour_flg = X"4")then
							hour_1_cnt <= X"0";
							en_hour_flg <= X"F";
						elsif(en_hour_flg = X"A")then
							hour_1_cnt <= X"0";
							en_hour_flg <= X"F";
						end if;
					end if;
				end if;
		end process;

		process(s_clk, RST_N)
			begin
				if(RST_N = '0')then
--					SEG7_4_OUT <= "10011000"; 
					SEG7_4_OUT <= "11000000"; 
				elsif(s_clk'event and s_clk = '1')then -- s_clk 変化有り 且つ s_clk = 1の時 →クロックの立ち上がりエッジ
					case hour_1_cnt is
						when X"1" =>
							SEG7_4_OUT <= "11111001";
						when X"2" =>
							SEG7_4_OUT <= "10100100";
						when X"3" =>
							SEG7_4_OUT <= "10110000";
						when X"4" =>
							SEG7_4_OUT <= "10011001";
						when X"5" =>
							SEG7_4_OUT <= "10010010";
						when X"6" =>
							SEG7_4_OUT <= "10000010";
						when X"7" =>
							SEG7_4_OUT <= "11011000";
						when X"8" =>
							SEG7_4_OUT <= "10000000";
						when X"9" =>
							SEG7_4_OUT <= "10011000"; 
						when others =>
							SEG7_4_OUT <= "11000000"; 
					end case;
				end if;
		end process;	
		
		-- 10 hour
		en_hour_10 <= '1' when (hour_1_cnt = en_hour_flg) else '0'; -- 10 hour

		process(s_clk, RST_N)
			begin
				if(RST_N = '0')then
--					hour_10_cnt <= X"1";
					hour_10_cnt <= X"0";
				elsif(s_clk'event and s_clk = '1')then -- s_clk 変化有り 且つ s_clk = 1の時 →クロックの立ち上がりエッジ
					if(en_hour_10 = '1')then
						hour_10_cnt <= hour_10_cnt + '1';
					else
						if(hour_10_cnt = X"3")then
							hour_10_cnt <= X"0";
						end if;
					end if;
				end if;
		end process;

		process(s_clk, RST_N)
			begin
				if(RST_N = '0')then
--					SEG7_5_OUT <= "11111001"; 
					SEG7_5_OUT <= "11000000"; 
				elsif(s_clk'event and s_clk = '1')then -- s_clk 変化有り 且つ s_clk = 1の時 →クロックの立ち上がりエッジ
					case hour_10_cnt is
						when X"1" =>
							SEG7_5_OUT <= "11111001";
						when X"2" =>
							SEG7_5_OUT <= "10100100"; 
						when others =>
							SEG7_5_OUT <= "11000000"; 
					end case;
				end if;
		end process;
		
		-- 1sec blink led
		process(s_clk, RST_N)
			begin
				if(RST_N = '0')then
					counter_led <= "0000000001";
				elsif(s_clk'event and s_clk = '1')then -- s_clk 変化有り 且つ s_clk = 1の時 →クロックの立ち上がりエッジ
					if(en_sec_1 = '1')then
						counter_led(1) <= counter_led(0);
						counter_led(2) <= counter_led(1);
						counter_led(3) <= counter_led(2);
						counter_led(4) <= counter_led(3);
						counter_led(5) <= counter_led(4);
						counter_led(6) <= counter_led(5);
						counter_led(7) <= counter_led(6);
						counter_led(8) <= counter_led(7);
						counter_led(9) <= counter_led(8);
						counter_led(0) <= counter_led(9);
					end if;
				end if;
		end process;
		
		LED_OUT <= counter_led;
		
end rtl;

次に、Tasksから「Compile Design」をダブルクリックして実行します。(「Analysis & Synthesis」のみ実行してもよいと思います。)

「Compile Design」が成功したら、ピンの設定をします。メニューから「Assignments」→「Pin Planner」を選択します。ピンの設定を行う画面が表示されるので、下記のようにピンを設定します。

その他に関しては、下記のサイトと同様です。

FPGA MAX10(4)-LEDシフト点灯回路

それでは、再度、Tasksから「Compile Design」をダブルクリックして実行します。「Compile Design」が成功したら、書き込みを行い、実行します。書き込み方法は下記のサイト参考にしてください。

FPGA MAX10(4)-LEDシフト点灯回路

書き込みを行い、実行すると7セグメントが動作していています。動作確認をするにあたって24時間DE10-Liteを見るのはつらいので、KEY0ボタンを押した時のリセット値や1秒間のカウンタの値を調整して動作確認をしました。

例えば、下記のようにすれば、時間の7セグメントを1秒間隔で動作することができます。

今回、24時間カウンタを作成しましたが、目視では確認できないですが、カウンタのズレが発生していると思います。例えば下記の部分がそうです。

24時間経過後に、00時間になりますが、時間の1の位が2クロック遅れて、0になります。秒の部分がズレてはいないので、全体的に遅れが生じることはないと思いますが、うーんって感じです。もう少し遅れが生じないような仕組みを考えたいところです。

また、7セグメントに信号を送る処理をprocess処理のcase文で行っていますが、ここもカウンタが更新されて1クロック遅れて更新されていると思いわれます。下記のように回路図でみるとレジスタから出力されています。そのため、1クロック遅れていると思います。

目視でみて問題ないような内容ではありますが、ここも見直したいと思います

FPGA MAX10(4)-LEDシフト点灯回路

前々回に、下記のFPGA(MAX10)基板を使用して、LEDの点滅回路を作成しました。

マルツ MAX10-FB(FPGA)基板 全実装版 【MTG-MAX10-FB-F】

新品価格
¥8,445から
(2021/2/13 23:06時点)

マルツ MAX10-JB(JTAG)基板 全実装版 【MTG-MAX10-JB-F】

新品価格
¥4,210から
(2021/2/13 23:07時点)

前々回の内容は下記を参照してください。

FPGA MAX10(2)-LED点滅回路

今回は、DE10-Lite評価ボードを使用して、LEDの点灯をシフトする機能を作成しようと思います。前々回はVerilog HDL言語を使用していましたが、今回はVHDL言語を使用したいと思います。

LED点灯シフト機能の使用は下記の通りで、シンプルです。

  • DE10-Liteには、赤色LEDが10個(LED0~LED9)が用意されています。 1秒経過するごとに、LED0→LED1→・・・→LED8→LED9→LED0→・・・変化させます。
  • DE10-LiteにはPushSwitchが2個(KEY0、KEY1)が用意されています。KEY0ボタンを押すと、LED0が点灯するようなリセット動作をします。
  • クロックカウンタもリセットさせます。

それでは、機能を構築していきたいと思います。まずは、新規プロジェクトを作成します。メニューから「File」→「New Project Wizard」を選択します。

下記のような画面が表示されるので、プロジェクトの保存先、プロジェクト名、トップエンティティ名をを入力して、「Next」ボタンを押します。

下記のような画面が表示されるので、プロジェクトタイプを選択します。今回は、Empty projectを選択して、「Next」ボタンを押します。

下記のような画面が表示されるので、追加したいファイルを選択します。今回は追加ファイルはないので、そのまま「Next」ボタンを押します。

下記のような画面が表示されるので、使用するFPGAを選びます。DE10-Liteには、「10M50DAF484C7G」が搭載されているので、「Available devices:」から選択して、「Next」ボタンを押します。

下記のような画面が表示されるので、EDAツールの設定を行います。今回はとくに設定は行わないので、そのまま「Next」ボタンを押します。

下記のような画面が表示されるので、設定した内容を確認して問題なければ、「Finish」ボタンを押します。

これでプロジェクトファイルの作成が完了したので、次にVHDLファイルを追加します。メニューから「File」→「New」を選択します。

下記のようが画面が表示されるので、「VHDL File」を選択して、「OK」ボタンを押します。

VHDLファイルが作成できたので、ファイルから「File」→「Save As」を選択して、名前を付け保存します。

ファイル名を入力(任意名)して、「保存」ボタンを押します。

クロックの設定を行っていきます。DE10-Liteのクロックは下記のようになっています。クロックジェネレータから生成されたクロックがMAX10に供給されています。今回、P11に供給されるクロックを使用しようと思います。50MHzになりますが、今回は、PLLで10MHzを生成して使用しようと思います。

今度は、IPを使用して、PLLを追加します。IP Catalogから「Installed IP」→「Library」→「Basic Functions」→「Clocks; PLLs and Resets」→「PLL」→「ATLPLL」を選択します。

下記のような画面が表示されるので、生成されるIPのファイル名を設定します。ファイルタイプは「VHDL」を選択してOKボタンを押します。

ALTPLLのウィーザードが表示されました。ウィザードに従って設定をしていきます。「What’s the frequency of the inclk0 input?」に「50.000MHz」を入力して、「Next」ボタンを押します。

「Create an ‘areset’ input to asynchronously reset the PLL」にチェックを入れて「Next」ボタンを押します。

「Output Clocks」のタブになるまで「Next」ボタンを押していきます。c0の設定画面が開かれたら、「Use this clock」にチェックを入れて、c0を有効にします。「Enter output clock frequency」にチェックを入れて、「10.000MHz」を入力して、「Next」ボタンを押します。

「Summary」のタブになるまで「Next」ボタンを押していきます。「Summary」が開かれたら、「pll.cmp」「pll_inst.vhd」を選択して「Finish」ボタンを押します。

プロジェクトにIPを追加したいですかと問われているので、「Yes」ボタンを押します。

これでPLLが追加されたので、それでは、先程新規作成したVHDLファイルに動作内容を記述していきます。下記のように記述しました。

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.std_logic_arith.all;

entity de10lite_blink_top is	-- Output pin
	port(
		CLK		: in  std_logic;  -- 50MHz Clock
		RST_N		: in  std_logic;
		LED_OUT	: out std_logic_vector(9 downto 0)
	);
end de10lite_blink_top;

architecture rtl of de10lite_blink_top is -- Internal process

	component pll is -- pll
		port(
			inclk0	: in  std_logic;	-- 50MHz Clock
			c0			: out std_logic	-- 10MHz Clock
		);
	end component;

	signal s_clk			: std_logic;	-- 10MHz Clock signal
	signal en     			: std_logic;
	signal cnt 				: std_logic_vector(23 downto 0);
	signal counter_led	: std_logic_vector(9 downto 0);

	begin

		u0_pll : pll
			port map(
				inclk0	=> CLK, --in  std_logic(50MHz)
				c0			=> s_clk --out std_logic(10MHz)
			);
		
		en <= '1' when (cnt = X"989680") else '0'; -- 1sec

		process(s_clk, RST_N) -- s_clkに変化があった時
			begin
				if(RST_N = '0')then
					cnt <= (others=>'0'); -- cnt全部「0」※othersはそれ以外の意
				elsif(s_clk'event and s_clk = '1')then -- s_clk 変化有り 且つ s_clk = 1の時 →クロックの立ち上がりエッジ
					if(en = '1')then	-- 1msec
						cnt <= (others=>'0'); -- cnt全部「0」※othersはそれ以外の意
					else
						cnt <= cnt + '1';
					end if;
				end if;
		end process;
		
		process(s_clk, RST_N)
			begin
				if(RST_N = '0')then
					counter_led <= "0000000001";
				elsif(s_clk'event and s_clk = '1')then -- s_clk 変化有り 且つ s_clk = 1の時 →クロックの立ち上がりエッジ
					if(en = '1')then
						counter_led(1) <= counter_led(0);
						counter_led(2) <= counter_led(1);
						counter_led(3) <= counter_led(2);
						counter_led(4) <= counter_led(3);
						counter_led(5) <= counter_led(4);
						counter_led(6) <= counter_led(5);
						counter_led(7) <= counter_led(6);
						counter_led(8) <= counter_led(7);
						counter_led(9) <= counter_led(8);
						counter_led(0) <= counter_led(9);
					end if;
				end if;
		end process;
		
		LED_OUT <= counter_led;

		
end rtl;

次に、Tasksから「Compile Design」をダブルクリックして実行します。(「Analysis & Synthesis」のみ実行してもよいと思います。)

「Compile Design」が成功したら、ピンの設定をします。メニューから「Assignments」→「Pin Planner」を選択します。ピンの設定を行う画面が表示されるので、下記のようにピンを設定します

それでは、再度、Tasksから「Compile Design」をダブルクリックして実行します。「Compile Design」が成功したら、書き込みを行います。メニューから「Tools」→「Programmer」を選択します。下記のような画面が表示されるので、「Hardware Setup」ボタンを押します。

「Currently selected hardware」より「USB-Blaster[USB-*」を選択します。選択したら「Close」ボタンを押します。

「Start」ボタンを押して書き込みを行います。

1秒経過するごとに、LED0→LED1→・・・→LED8→LED9→LED0→・・・とLEDがシフトして点灯しています。KEY0ボタンを押すと、LED0が点灯しました。

FPGA MAX10(3)-SignalTapⅡ

SignalTapⅡはロジック・アナライザ機能です。Quartus PrimeはFPGA内部の信号を観測してデバックする為のロジック・アナライザ機能としてSignalTapⅡを提供しています。

それでは、早速使用してみます。まずは、TalkBack機能を有効にします。Tools→optionsよりoptions画面を表示します。options画面のInternet Connectivityを選択して、画面よりTalkBack Optionsを選択すると、Quartus Prime TalkBack画面が表示されます。Enable sending TalkBack data to Alteraチェックボックスにチェックを入れて有効にします。

前回、作成したLED点滅回路のcounter_1sec[31:0]とcounter_led[2:0]を見てみようと思います。SignalTapⅡの無償版では、観測する信号の選択やトリガ条件を変更する際には、フルコンパイルが必要です。tools→SignalTapⅡ Logic Analyzerを選択して、SignalTapⅡをを起動します。

Setupタブ内の空白部分をダブルクリックして、Node Finder画面を表示します。Namedにキーワードを入れて、Listを選択すると、Matching Nodesにキーワードに一致したものが表示されます。counter_1secとcounter_ledをNodes Foundに設定します。

SignalTapⅡの画面に戻り、Signal Configurationを設定します。Clockはclkを指定、Storage qualiferのTypeをContinuousを指定、TriggerをAuto、Sequential、Pre trigger position、Triggerを指定、conditionsを1指定、Trigger in、Trigger outのチェックボックスを無効にする。

Start Compilaiton(三角を90度回転したマーク)を選択して、フルコンパイルを実行します。

フルコンパイルが完了したら、JTAG Chain Configurationを設定します。SOF Managerで、作成したsofファイル(FPGA.sof)を指定します。Run Analysisボタンを選択すると、波形が表示されます。

FPGA MAX10(2)-LED点滅回路

前回、FPGA MAX10搭載基板と書き込み器製作用プリント基板の初期セットアップが完了したので、今回はLEDチカチカ回路を作ってみようと思います。

まずは、Quartus Primeを実行します。Windowsのスタートメニューの中から実行できます。

新規プロジェクトを作成します。作成ディレクトリは任意で構いませんが、日本語は使用しない方がよさそうです。プロジェクト名はFPGAにしました。私の使用しているデバイスは「10M08SAE144C8GES」のようです。シミュレーション・ツール形式は「Verilog HDL」に設定しておきます。

次にVerilog HDL Fileを作成します。そして下記のようにハードウェア言語「Verilog HDL」を入力します。

続きを読む

FPGA MAX10(1)-MAX10について調べてみる

FPGAはfield-programmable gate arrayの略です。FPGAはマイコンとは違います。PICはソフトウェアで処理を行うのに対して、FPGAはハードウェアで処理をします。PICは論理回路が決まっておりますが、FPGAは論理回路設計からする事ができます。今回はFPGAを試してみるために、MAX10を使ってみたいと思います。

まずは、FPGA MAX10を用意する必要があります。私は下記の3点を購入しました。

(1).FPGAの書籍です。FPGA MAX10搭載基板や書き込み器製作用プリント基板、ソフトウェア一式が付いてきます。あくまで基盤なので、搭載部品をはんだで取り付ける必要があります。

(1)MAX10(2)ライタ(3)DVD付き! FPGA電子工作スーパーキット (トライアルシリーズ)

新品価格
¥4,950から
(2021/2/13 23:05時点)

(2).FPGA MAX10搭載基板に必要な部品を取り付けてある完成品です。こちらに関しては、必要なところをはんだでショートする必要があります。

マルツ MAX10-FB(FPGA)基板 全実装版 【MTG-MAX10-FB-F】

新品価格
¥8,445から
(2021/2/13 23:06時点)

(3).書き込み器製作用プリント基板に必要な部品を取り付けてある完成品です。

マルツ MAX10-JB(JTAG)基板 全実装版 【MTG-MAX10-JB-F】

新品価格
¥4,210から
(2021/2/13 23:07時点)

(1)に取り付ける部品のセットも販売しています。こちらを使用してもよいと思います。

マルツ JB基板仕上げ部品セット 【MTG-MAX10-JC-S】

新品価格
¥2,032から
(2021/2/13 23:07時点)

次回から論理回路設計やプログラムを使用して動作させていきたいと思います。

2021年2月13日 | カテゴリー : FPGA | タグ : , | 投稿者 : prog