目次

CPLDで車を動かす

 デジタル回路では、次のようにICの数が多くなっています。




 デジタル回路の機能を好きなように並べて
 封入することができるのは、CPLDかFPGA。

 CPLDに全回路を封入するとし、HDL
 で回路情報を記述します。

 HDLには、VerilogHDLとVHDLが双璧をなして
 いますが、VHDLを使います。

 シーケンサを実現するには、カウンタが必要です。
 カウンタは、次のように定義しました。

  -- sequencer
  process ( nRESET , CLOCK )
  begin
    if ( nRESET = '0' ) then
      iSEQ <= "00000" ;
    elsif rising_edge( CLOCK ) then
      if ( iSEQ = "11111" ) then
        iSEQ <= "00000" ;
      else
        iSEQ <= iSEQ + '1' ;
      end if ;
    end if ;
  end process ;

 シーケンサ用のカウンタができたなら
 センサー情報を記憶する回路を定義。

  -- latch sensor data
  process ( nRESET , CLOCK )
  begin
    if ( nRESET = '0' ) then
      iSDAT <= "11" ;
    elsif rising_edge( CLOCK ) then
      if ( iSEQ = "00011" ) then
        iSDAT <= SDAT ;
      end if ;
    end if ;
  end process ;

 ドライブ回路に、制御信号を渡すための
 回路を記述しておきます。

  -- generate drive signal
  iDRV(1) <= iSDAT(0) when ( conv_integer(iSEQ) > 4 ) else '1' ;
  iDRV(0) <= iSDAT(1) when ( conv_integer(iSEQ) > 4 ) else '1' ;

 VHDLでは、出力を束ねることができるので
 出力バッファを用意。

  -- output
  DRVOUT <= iDRV when ( ENA = '1' ) else "00" ;

 まとめると、以下。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity lfw is
  Port (
    -- system 
    nRESET : in  std_logic ; -- system reset
    CLOCK  : in  std_logic ; -- 100Hz
    -- sensor data
    SDAT   : in  std_logic_vector(1 downto 0) ;
    -- output control
    ENA    : in  std_logic ;
    -- output
    DRVOUT : out std_logic_vector(1 downto 0) --;
  );
end lfw;

architecture Behavioral of lfw is
  -- sequencer
  signal iSEQ : std_logic_vector(4 downto 0) ;
  -- sensor data
  signal iSDAT : std_logic_vector(1 downto 0) ;
  -- driver signals
  signal iDRV  : std_logic_vector(1 downto 0) ;

begin
  -- output
  DRVOUT <= iDRV when ( ENA = '1' ) else "00" ;

  -- latch sensor data
  process ( nRESET , CLOCK )
  begin
    if ( nRESET = '0' ) then
      iSDAT <= "11" ;
    elsif rising_edge( CLOCK ) then
      if ( iSEQ = "00011" ) then
        iSDAT <= SDAT ;
      end if ;
    end if ;
  end process ;

  -- sequencer
  process ( nRESET , CLOCK )
  begin
    if ( nRESET = '0' ) then
      iSEQ <= "00000" ;
    elsif rising_edge( CLOCK ) then
      if ( iSEQ = "11111" ) then
        iSEQ <= "00000" ;
      else
        iSEQ <= iSEQ + '1' ;
      end if ;
    end if ;
  end process ;

  -- generate drive signal
  iDRV(1) <= iSDAT(0) when ( conv_integer(iSEQ) > 4 ) else '1' ;
  iDRV(0) <= iSDAT(1) when ( conv_integer(iSEQ) > 4 ) else '1' ;

end Behavioral;

 どのピンに、何を信号として割当てるかを
 UCFファイルで指定。

# system
NET "nRESET" loc = "P39" ;
NET "CLOCK"  loc = "P5"  ;

# sensor 
NET "SDAT<0>" loc = "P2" ;
NET "SDAT<1>" loc = "P1" ;

# driver 
NET "DRVOUT<0>" loc = "P6" ;
NET "DRVOUT<1>" loc = "P7" ;
NET "ENA"       loc = "P9" ;

 実際に使う回路基板は、以下。




目次

inserted by FC2 system