http://d.hatena.ne.jp/ryuk/20040824#p4/さんのVHDL
XC9572 に4コ入るみたいですけど。なんか違うのかな。あと、これ何も検証していません。
オリジナルソースは http://web.maizuru-ct.ac.jp/control/machida/asic/maigi1.htm
まずいかなあ。変更点は
- carry のロジックを外した(どうせボローがないから使えない)
- エンコーダーカウンターを4bit -> 8bit
- 4回路にした (確かfor文で作れた気がする)
- rd, sel[1..0], dat[7..0] でCPUバスに接続するようにした
Fiter のレポートによると、Macrosel (60/72), Pterms (324/360), Register(60/72), Pin (21/34), function Block Input (117/144) まあちょうどいい位の量ですね。
---------------------------------------------------- -- VHDL code generated by Visual HDL -- Root of Design: -- --------------- -- Unit Name : recnt -- Library Name : updn8 ---------------------------------------------------- -- Library Name : updn8 -- Unit Name : rotary -- Unit Type : Text Unit ---------------------------------------------------- library ieee; use ieee.std_logic_1164.all; entity rotary is port (y,z,clk,A,B : in std_logic ; ud : out std_logic); end; architecture rotary of rotary is begin process (clk) begin if (clk'event and clk = '1') then if ((a = '0' and b = '1' and y = '0' and z = '0') or (a = '1' and b = '1' and y = '0' and z = '1') or (a = '1' and b = '0' and y = '1' and z = '1') or (a = '0' and b = '0' and y = '1' and z = '0')) then ud <= '0'; elsif ((a = '1' and b = '0' and y = '0' and z = '0') or (a = '1' and b = '1' and y = '1' and z = '0') or (a = '0' and b = '1' and y = '1' and z = '1') or (a = '0' and b = '0' and y = '0' and z = '1')) then ud <= '1'; end if; end if; end process; end rotary; ---------------------------------------------------- -- Library Name : updn8 -- Unit Name : mem -- Unit Type : Text Unit ---------------------------------------------------- library ieee; use ieee.std_logic_1164.all; entity mem is port (y,z : out std_logic ; A,B,clk : in std_logic ); end; architecture RTL of mem is begin process (clk) begin if(clk'event and clk='1') then y<=A; z<=B; end if; end process; end RTL; ---------------------------------------------------- -- Library Name : updn8 -- Unit Name : rot -- Unit Type : Block Diagram ---------------------------------------------------- library ieee; use ieee.std_logic_1164.all; entity rot is port (a,b,clk : in std_logic; ud : out std_logic ); end rot; architecture rot of rot is signal y,z : std_logic; component mem port ( y,z : out std_logic; a,b,clk : in std_logic ); end component; component rotary port (y,z,clk,a,b : in std_logic; ud : out std_logic ); end component; begin inst_mem: mem port map (y=>y,z=>z,b=>b,a=>a,clk=>clk); inst_rotary: rotary port map (y=>y,z=>z,clk=>clk,ud=>ud,a=>a,b=>b); end rot; ---------------------------------------------------- -- Library Name : updn8 -- Unit Name : udcnt8 -- Unit Type : Text Unit ---------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity udcnt8 is port (rst,ud,enb,clk : in std_logic ; q : out std_logic_vector (7 downto 0)); end; architecture RTL of udcnt8 is signal cnt : std_logic_vector(7 downto 0); signal tmp : std_logic_vector(7 downto 0); begin tmp <= cnt; q<=cnt; process (clk) begin if(clk'event and clk='1') then if(rst='1') then cnt<="00000000"; elsif(enb='1') then if(ud='1') then if (tmp = "11111111") then else cnt <= cnt+'1'; end if; else if (tmp = "00000000") then else cnt <= cnt-'1'; end if; end if; end if; end if; end process; end RTL; ---------------------------------------------------- -- Library Name : updn8 -- Unit Name : DFFR -- Unit Type : Text Unit ---------------------------------------------------- library ieee; use ieee.std_logic_1164.all; entity DFFR is port(CLK,D : in std_logic; Q,QN :out std_logic); end DFFR; architecture RTL of DFFR is signal Q_IN : std_logic; begin Q<=Q_IN; QN<=not Q_IN; process(CLK) begin if(CLK'event and CLK='1') then Q_IN <= D; end if; end process; end RTL; ---------------------------------------------------- -- Library Name : updn8 -- Unit Name : syncup -- Unit Type : Text Unit ---------------------------------------------------- library ieee; use ieee.std_logic_1164.all; entity syncup is port (A,clk : in std_logic ; enb : out std_logic ); end; architecture RTL of syncup is component DFFR port(CLK,D : in std_logic; Q,QN : out std_logic); end component; signal Q1,Q1N,Q2 :std_logic; begin U0:DFFR port map(clk,A,Q1,Q1N); U1:DFFR port map(clk,Q1,Q2); enb <= Q1N nor Q2; end RTL; ---------------------------------------------------- -- Library Name : updn8 -- Unit Name : recnt -- Unit Type : Block Diagram ---------------------------------------------------- library ieee; use ieee.std_logic_1164.all; entity recnt is port (clk,rst : in std_logic; a1, b1 : in std_logic; a2, b2 : in std_logic; a3, b3 : in std_logic; a4, b4 : in std_logic; rd : in std_logic; sel: in std_logic_vector(1 downto 0); dat: out std_logic_vector(7 downto 0) ); end recnt; architecture recent of recnt is signal enb1,ud1 : std_logic; signal enb2,ud2 : std_logic; signal enb3,ud3 : std_logic; signal enb4,ud4 : std_logic; signal q1 : std_logic_vector(7 downto 0 ); signal q2 : std_logic_vector(7 downto 0 ); signal q3 : std_logic_vector(7 downto 0 ); signal q4 : std_logic_vector(7 downto 0 ); signal tmp: std_logic_vector(7 downto 0); component syncup port (a,clk : in std_logic; enb : out std_logic ); end component; component udcnt8 port (rst,ud,enb,clk : in std_logic; q : out std_logic_vector(7 downto 0 ) ); end component; component rot port (a,b,clk : in std_logic; ud : out std_logic ); end component; begin process(rd) begin if (rd'event and rd='0') then case sel is when "00" => tmp <= q1; when "01" => tmp <= q2; when "10" => tmp <= q3; when others => tmp <= q4; end case; end if; end process; dat <= tmp when rd = '0' else "ZZZZZZZZ"; inst_syncup1: syncup port map (a=>a1,enb=>enb1,clk=>clk); inst_udcnt81: udcnt8 port map (rst=>rst,ud=>ud1,enb=>enb1,clk=>clk,q=>q1(7 downto 0)); inst_rot1: rot port map (a=>a1,b=>b1,clk=>clk,ud=>ud1); inst_syncup2: syncup port map (a=>a2,enb=>enb2,clk=>clk); inst_udcnt82: udcnt8 port map (rst=>rst,ud=>ud2,enb=>enb2,clk=>clk,q=>q2(7 downto 0)); inst_rot2: rot port map (a=>a2,b=>b2,clk=>clk,ud=>ud2); inst_syncup3: syncup port map (a=>a3,enb=>enb3,clk=>clk); inst_udcnt83: udcnt8 port map (rst=>rst,ud=>ud3,enb=>enb3,clk=>clk,q=>q3(7 downto 0)); inst_rot3: rot port map (a=>a3,b=>b3,clk=>clk,ud=>ud3); inst_syncup4: syncup port map (a=>a4,enb=>enb4,clk=>clk); inst_udcnt84: udcnt8 port map (rst=>rst,ud=>ud4,enb=>enb4,clk=>clk,q=>q4(7 downto 0)); inst_rot4: rot port map (a=>a4,b=>b4,clk=>clk,ud=>ud4); end recent;