FPGA活用回路&サンプル記述集(4) ―― 安定動作のための回路

小野 裕幸,森田 一

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

entity MAINSEQ is 
  port(
   RESETn            : in  std_logic;
   CLK               : in  std_logic;
   nCONFIG           : out std_logic;
   nSTATUS           : in  std_logic;
   CONF_DONE         : in  std_logic;
   INIT_DONE         : in  std_logic;
   FLASHIF_RESET     : out std_logic;
   SEL               : out std_logic;
   NIOSDOWNLOADFCOMP : in  std_logic;
   FPGA_RESET        : out std_logic;
   MSEQ              : out std_logic_vector(3 downto 0);
   START             : out std_logic;
   SEQSTOP           : out std_logic;
   CONFIG_ERR        : out std_logic
  );
end MAINSEQ;


architecture RTL of MAINSEQ is

------<> HEX to BIN
 constant x8usec         : std_logic_vector(27 downto 0)
                                           := X"0000190";
 constant x10usec        : std_logic_vector(27 downto 0)
                                           := X"00001F4";
 constant x1usec         : std_logic_vector(27 downto 0)
                                           := X"0000032";
 constant xFULL          : std_logic_vector(27 downto 0)
                                           := X"FFFFFFF";
 constant xNIOS128K      : std_logic_vector(23 downto 0)
                                            := X"FFFFFF";
------<> Signal
 signal MAINSEQ          : std_logic_vector( 3 downto 0);
 signal reset_p          : std_logic_vector( 3 downto 0);
 signal nconfig_p        : std_logic;
 signal flashifreset_n   : std_logic;
 signal fpgareset_n      : std_logic;
 signal countenable      : std_logic;
 signal countenable1     : std_logic;
 signal start_p          : std_logic;
 signal count            : std_logic_vector(11 downto 0)
                                               := X"000";
 signal count1           : std_logic_vector(27 downto 0)
                                           := X"0000000";
 signal timer1usec       : std_logic;
 signal timer8usec       : std_logic;
 signal timer10usec      : std_logic;
 signal timer1usec1      : std_logic;
 signal timer10usec1     : std_logic;
 signal timerfull        : std_logic;
 signal sel_p            : std_logic;
 signal err              : std_logic;
 signal configseq_stop   : std_logic;
 signal configseq_stop_p : std_logic_vector( 3 downto 0);
 signal seqstop_p        : std_logic;
 signal conf_done_p      : std_logic;
 signal comp             : std_logic;
 signal init             : std_logic;
 signal nioscountenable  : std_logic;
 signal nioscount        : std_logic_vector(23 downto 0)
                                            := X"000000";
 signal nioscount_full   : std_logic;


--/***********************
begin
------<> si_out_p
 process(CLK,RESETn)
 begin
  if (RESETn = '0') then
   reset_p         <= (others => '0');
  elsif (CLK 'event and CLK = '1') then
   reset_p(0)      <= RESETn;
   reset_p(1)      <= reset_p(0);
   reset_p(2)      <= reset_p(1);
   reset_p(3)      <= reset_p(2);
  end if;
 end process;

------<> count
 process(CLK,RESETn)
 begin
  if (RESETn = '0') then
   count         <= (others => '0');
  elsif (CLK 'event and CLK = '1') then
   if (countenable = '1') then
    count        <= count + 1;
   else
    count        <= (others => '0');
   end if;
  end if;
 end process;
 timer1usec      <= '1' when (count = x1usec) else '0';
 timer8usec      <= '1' when (count = x8usec) else '0';
 timer10usec     <= '1' when (count = x10usec) else '0';

------<> count1
 process(CLK,RESETn)
 begin
  if (RESETn = '0') then
   count1        <= (others => '0');
  elsif (CLK 'event and CLK = '1') then
   if (countenable1 = '1') then
    count1       <= count1 + 1;
   else
    count1       <= (others => '0');
   end if;
  end if;
 end process;
 timer1usec1     <= '1' when (count1 = x1usec) else '0';
 timer10usec1    <= '1' when (count1 = x10usec) else '0';
 timerfull       <= '1' when (count1 = xFULL) else '0';

------<> conf_done_p
 process(CLK,RESETn)
 begin
  if (RESETn = '0') then
   conf_done_p   <= '0';
  elsif (CLK 'event and CLK = '1') then
   conf_done_p   <= CONF_DONE;
  end if;
 end process;

------<> init
 process(CLK,RESETn)
 begin
  if (RESETn = '0') then
   init       <= '0';
  elsif (CLK 'event and CLK = '1') then
   init       <= INIT_DONE;
  end if;
 end process;

------<> nioscount
 process(CLK,RESETn)
 begin
  if (RESETn = '0') then
   nioscount    <= (others => '0');
  elsif (CLK 'event and CLK = '1') then
   if (nioscountenable = '1') then
    nioscount   <= nioscount + 1;
   else
    nioscount   <= (others => '0');
   end if;
  end if;
 end process;
 nioscount_full <= '1' when (nioscount = xNIOS128K)
                       else '0';

------<> MAINSEQ
 process(CLK,RESETn)
 begin
  if (RESETn = '0') then
   configseq_stop     <= '0';
   countenable        <= '0';
   countenable1       <= '0';
   nioscountenable    <= '0';
   nconfig_p          <= '1';
   flashifreset_n     <= '0';
   fpgareset_n        <= '0';
   start_p            <= '0';
   sel_p              <= '0';
   err                <= '0';
   MAINSEQ            <= x"0";
  elsif (CLK 'event and CLK = '1') 
                               then
   case MAINSEQ is
    when x"0" =>
     configseq_stop   <= '0';
     countenable      <= '0';
     countenable1     <= '0';
     nconfig_p        <= '1';
     flashifreset_n   <= '0';
     fpgareset_n      <= '0';
     start_p          <= '0';
     sel_p            <= '0';
     err              <= '0';
     nioscountenable  <= '0';
     if (reset_p(3)  = '1') then
      countenable     <= '1';
      MAINSEQ         <= x"1";
     else
      MAINSEQ         <= x"0";
     end if;
    when x"1" =>
     if (timer1usec = '1') then
      countenable     <= '0';
      MAINSEQ         <= x"2";
     else
      MAINSEQ         <= x"1";
     end if;
    when x"2" =>
     nconfig_p        <= '0';
     countenable      <= '1';
     MAINSEQ          <= x"3";
    when x"3" =>
     if (nSTATUS  = '0') then
      countenable1    <= '1';
      MAINSEQ         <= x"4";
     else
      if (timer8usec = '1') then
       countenable    <= '0';
       countenable1   <= '0';
       err            <= '1';
       MAINSEQ        <= x"F";
      else
       MAINSEQ        <= x"3";
      end if;
     end if;
    when x"4" =>
     if (timer8usec = '1') then
      countenable     <= '0';
      nconfig_p       <= '1';
     else
     end if;
     if (timer10usec1 = '1') then
      countenable1    <= '0';
      MAINSEQ         <= x"5";
     else
      MAINSEQ         <= x"4";
     end if;
    when x"5" =>
     if (nSTATUS  = '1') then
      countenable     <= '1';
      MAINSEQ         <= x"7";
     else
      countenable1    <= '1';
      MAINSEQ         <= x"6";
     end if;
    when x"6" =>
     if (timer1usec1 = '1') then
      if (nSTATUS  = '1') then
       countenable    <= '1';
       MAINSEQ        <= x"7";
      else
       MAINSEQ        <= x"6";
      end if;
     elsif (timerfull = '1') then
      if (nSTATUS  = '1') then
       countenable    <= '1';
       MAINSEQ        <= x"7";
      else
       countenable    <= '0';
       countenable1   <= '0';
       err            <= '1';
       MAINSEQ        <= x"F";
      end if;
     else
      MAINSEQ         <= x"6";
     end if;
    when x"7" =>
     if (timer1usec = '1') then
      start_p         <= '1';
      countenable     <= '0';
      MAINSEQ         <= x"8";
     else
      MAINSEQ         <= x"7";
     end if;
    when x"8" =>
     start_p          <= '0';
     MAINSEQ          <= x"9";
    when x"9" =>
     MAINSEQ          <= x"A";
    when x"A" =>
     if (timerfull = '0')
       and (conf_done_p = '1') then
      configseq_stop  <= '1';
      start_p         <= '0';
      countenable1    <= '0';
      countenable     <= '1';
      MAINSEQ         <= x"B";
     elsif (timerfull = '1') then
      countenable     <= '0';
      countenable1    <= '0';
      err             <= '1';
      MAINSEQ         <= x"F";
     else
      MAINSEQ         <= x"A";
     end if;
    when x"B" =>
     if (init = '1') then
      sel_p <= '1';
      flashifreset_n  <= '1';
      countenable     <= '0';
      configseq_stop  <= '0';
      nioscountenable <= '1';
      MAINSEQ         <= x"C";
     else
      MAINSEQ         <= x"B";
     end if;
    when x"C" =>
     if (nioscount_full = '1') then
      nioscountenable <= '0';
      fpgareset_n     <= '1';
      MAINSEQ         <= x"D";
     else
      MAINSEQ         <= x"C";
     end if;
    when x"D" =>
     fpgareset_n      <= '1';
     MAINSEQ          <= x"D";
    when x"F" =>
     sel_p            <= '1';
     flashifreset_n   <= '1';
     countenable      <= '0';
     configseq_stop   <= '0';
     MAINSEQ          <= x"F";
    when others => null;
   end case;
  end if;
 end process ;

------<> configseq_stop_p
 process(CLK,RESETn)
 begin
  if (RESETn = '0') then
   configseq_stop_p <= (others => '0');
  elsif (CLK 'event and CLK = '1') 
                               then
   configseq_stop_p(0)
            <= configseq_stop;
   configseq_stop_p(1)
            <= configseq_stop_p(0);
   configseq_stop_p(2)
            <= configseq_stop_p(1);
   configseq_stop_p(3)
            <= configseq_stop_p(2);
  end if;
 end process;

------<> seqstop
 process(CLK,RESETn)
 begin
  if (RESETn = '0') then
   seqstop_p    <= '0';
  elsif (CLK 'event and CLK = '1') 
                               then
   if (configseq_stop = '1') then
    seqstop_p   <= '1';
   elsif (configseq_stop_p(3) = 
                          '1') then
    seqstop_p   <= '1';
   else
    seqstop_p   <= seqstop_p;
   end if;
  end if;
 end process;

 nCONFIG        <= nconfig_p;
 FLASHIF_RESET  <= flashifreset_n;
 FPGA_RESET     <= fpgareset_n;
 START          <= start_p;
 CONFIG_ERR     <= err;
 SEL            <= sel_p;
 SEQSTOP        <= seqstop_p;
 MSEQ           <= MAINSEQ;
end RTL;

リスト1-1 MAX IIを利用してStratix IIをコンフィグレーションするためのVHDL記述

組み込みキャッチアップ

お知らせ 一覧を見る

電子書籍の最新刊! FPGAマガジン No.12『ARMコアFPGA×Linux初体験』好評発売中

FPGAマガジン No.11『性能UP! アルゴリズム×手仕上げHDL』好評発売中! PDF版もあります

PICK UP用語

EV(電気自動車)

関連記事

EnOcean

関連記事

Android

関連記事

ニュース 一覧を見る
Tech Villageブログ

渡辺のぼるのロボコン・プロモータ日記

2年ぶりのブログ更新w

2016年10月 9日

Hamana Project

Hamana-8最終打ち上げ報告(その2)

2012年6月26日