目次
前
Step Sequencer
アナログシンセサイザーで使われる Step Sequencer があります。
回路は、以下。
タイミングチャートは、次のようになっています。
回路とタイミングチャートから、カウンタとデコーダ
を組み合わせると、電圧を可変させる部分を除いては
CPLDの中に封入できると判断しました。
CPLDの中に入れる回路は、以下。
外部で可変クロックを生成しカウンタとデコーダは
ジョンソンカウンタにランダムロジックで実現。
クロックは、可変抵抗器のトリマーを回すことで
調整すればよいとして、次の回路で対応。
出力から作成していきますが、ジョンソンカウンタで
8ステートを作れていると、デコーダは、次のように
定義。
signal iSREG : std_logic_vector(3 downto 0) ;
signal iQout : std_logic_vector(7 downto 0) ;
iQout(0) <= '1' when ( iSREG = "0000" ) else '0' ;
iQout(1) <= '1' when ( iSREG = "0001" ) else '0' ;
iQout(2) <= '1' when ( iSREG = "0011" ) else '0' ;
iQout(3) <= '1' when ( iSREG = "0111" ) else '0' ;
iQout(4) <= '1' when ( iSREG = "1111" ) else '0' ;
iQout(5) <= '1' when ( iSREG = "1110" ) else '0' ;
iQout(6) <= '1' when ( iSREG = "1100" ) else '0' ;
iQout(7) <= '1' when ( iSREG = "1000" ) else '0' ;
出力は、外部から制御できるようにした方が
動作をテストしやすいので、制御信号で出力
をすべて'0'とできるようにします。
Qout <= iQout when ( ENA = '1' ) else X"00" ;
カウンタは、8ステートのジョンソンカウンタと
しておけばよいので、4ビットのシフトレジスタ
で実現。
process (nRESET,CLOCK)
begin
if ( nRESET = '0' ) then
iSREG <= "0000" ;
elsif rising_edge(CLOCK) then
case iSEQ is
-- 0 -> 1
when "0000" => iSREG <= "0001" ;
-- 1 -> 2
when "0001" => iSREG <= "0011" ;
-- 2 -> 3
when "0011" => iSREG <= "0111" ;
-- 3 -> 4
when "0111" => iSREG <= "1111" ;
-- 4 -> 5
when "1111" => iSREG <= "1110" ;
-- 5 -> 6
when "1110" => iSREG <= "1100" ;
-- 6 -> 7
when "1100" => iSREG <= "1000" ;
-- 7 -> 0
when "1000" => iSREG <= "0000" ;
-- default
when others => iSREG <= "0000" ;
end case ;
end if ;
end process ;
まとめます。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity sxseq is
port (
-- system
nRESET : in std_logic ;
CLOCK : in std_logic ;
-- output control
ENA : in std_logic ;
-- output
Qout : out std_logic_vector(7 downto 0) -- ;
);
end sxseq ;
architecture Behavioral of lfsr is
-- register
signal iQout : std_logic_vector(7 downto 0) ;
-- counter
signal iSREG : std_logic_vector(3 downto 0) ;
begin
-- output
Qout <= iQout when ( ENA = '1' ) else X"00" ;
-- decoder
iQout(0) <= '1' when ( iSREG = "0000" ) else '0' ;
iQout(1) <= '1' when ( iSREG = "0001" ) else '0' ;
iQout(2) <= '1' when ( iSREG = "0011" ) else '0' ;
iQout(3) <= '1' when ( iSREG = "0111" ) else '0' ;
iQout(4) <= '1' when ( iSREG = "1111" ) else '0' ;
iQout(5) <= '1' when ( iSREG = "1110" ) else '0' ;
iQout(6) <= '1' when ( iSREG = "1100" ) else '0' ;
iQout(7) <= '1' when ( iSREG = "1000" ) else '0' ;
-- Johnson counter
process (nRESET,CLOCK)
begin
if ( nRESET = '0' ) then
iSREG <= "0000" ;
elsif rising_edge(CLOCK) then
case iSEQ is
-- 0 -> 1
when "0000" => iSREG <= "0001" ;
-- 1 -> 2
when "0001" => iSREG <= "0011" ;
-- 2 -> 3
when "0011" => iSREG <= "0111" ;
-- 3 -> 4
when "0111" => iSREG <= "1111" ;
-- 4 -> 5
when "1111" => iSREG <= "1110" ;
-- 5 -> 6
when "1110" => iSREG <= "1100" ;
-- 6 -> 7
when "1100" => iSREG <= "1000" ;
-- 7 -> 0
when "1000" => iSREG <= "0000" ;
-- default
when others => iSREG <= "0000" ;
end case ;
end if ;
end process ;
end Behavioral;
XC9572に回路を入れるとして、ピンアサインを
次のように定義。
# system
NET "nRESET" loc = "P39" ;
NET "CLOCK" loc = "P5" ;
# step sequence
NET "Qout<0>" loc = "P1" ;
NET "Qout<1>" loc = "P2" ;
NET "Qout<2>" loc = "P3" ;
NET "Qout<3>" loc = "P4" ;
NET "Qout<4>" loc = "P6" ;
NET "Qout<5>" loc = "P7" ;
NET "Qout<6>" loc = "P8" ;
NET "Qout<7>" loc = "P9" ;
# enable
NET "ENA" loc = "P11" ;
LEDは可変抵抗器とは別に、CPLDからの
制御信号を出力するとすれば、以下。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity sxseq is
port (
-- system
nRESET : in std_logic ;
CLOCK : in std_logic ;
-- output control
ENA : in std_logic ;
-- LED output
Lout : out std_logic_vector(7 downto 0) ;
-- output
Qout : out std_logic_vector(7 downto 0) -- ;
);
end sxseq ;
architecture Behavioral of lfsr is
-- register
signal iQout : std_logic_vector(7 downto 0) ;
-- counter
signal iSREG : std_logic_vector(3 downto 0) ;
begin
-- output
Lout <= not iQout when ( ENA = '1' ) else X"FF" ;
Qout <= iQout when ( ENA = '1' ) else X"00" ;
-- decoder
iQout(0) <= '1' when ( iSREG = "0000" ) else '0' ;
iQout(1) <= '1' when ( iSREG = "0001" ) else '0' ;
iQout(2) <= '1' when ( iSREG = "0011" ) else '0' ;
iQout(3) <= '1' when ( iSREG = "0111" ) else '0' ;
iQout(4) <= '1' when ( iSREG = "1111" ) else '0' ;
iQout(5) <= '1' when ( iSREG = "1110" ) else '0' ;
iQout(6) <= '1' when ( iSREG = "1100" ) else '0' ;
iQout(7) <= '1' when ( iSREG = "1000" ) else '0' ;
-- Johnson counter
process (nRESET,CLOCK)
begin
if ( nRESET = '0' ) then
iSREG <= "0000" ;
elsif rising_edge(CLOCK) then
case iSEQ is
-- 0 -> 1
when "0000" => iSREG <= "0001" ;
-- 1 -> 2
when "0001" => iSREG <= "0011" ;
-- 2 -> 3
when "0011" => iSREG <= "0111" ;
-- 3 -> 4
when "0111" => iSREG <= "1111" ;
-- 4 -> 5
when "1111" => iSREG <= "1110" ;
-- 5 -> 6
when "1110" => iSREG <= "1100" ;
-- 6 -> 7
when "1100" => iSREG <= "1000" ;
-- 7 -> 0
when "1000" => iSREG <= "0000" ;
-- default
when others => iSREG <= "0000" ;
end case ;
end if ;
end process ;
end Behavioral;
ピンアサインは、以下。
# system
NET "nRESET" loc = "P39" ;
NET "CLOCK" loc = "P5" ;
# step sequence
NET "Qout<0>" loc = "P1" ;
NET "Qout<1>" loc = "P2" ;
NET "Qout<2>" loc = "P3" ;
NET "Qout<3>" loc = "P4" ;
NET "Qout<4>" loc = "P6" ;
NET "Qout<5>" loc = "P7" ;
NET "Qout<6>" loc = "P8" ;
NET "Qout<7>" loc = "P9" ;
# enable
NET "ENA" loc = "P11" ;
# LED control
NET "Lout<0>" loc = "P24" ;
NET "Lout<1>" loc = "P25" ;
NET "Lout<2>" loc = "P26" ;
NET "Lout<3>" loc = "P27" ;
NET "Lout<4>" loc = "P28" ;
NET "Lout<5>" loc = "P29" ;
NET "Lout<6>" loc = "P33" ;
NET "Lout<7>" loc = "P34" ;
目次
前