2019.6.12
前へ
次へ
ホームページトップへ戻る

[新連載]CPLD入門!
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
いつか使うことになるだろうと思ってはいたのですが。
何を今頃になって、というようなものですが。
ようやく本気で、CPLDと四つに取り組みます。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜



[第65回]


●VGAIF+CRTIF(80字表示/40字表示切換)VHDLプログラムリスト

前回に続いて今回はVGAIF+CRTIF(80字表示/40字表示切換)VHDLプログラムリストです。
すでに出来上がっていたVGAIF+CRTIF(80字表示/40字表示切換)VHDLプログラムのVGAIF部分も修正しました。
やっと完成です。

--vga controller 18/12/22 12/23 12/24 12/25 12/26 12/27
--19/1/12 1/13 1/29 3/24 3/25 3/26 3/27
--5/4 5/5 5/6
--5/7 vga & crt from vgac2j
--5/8
--5/9 80/40 5/10
--5/11 vga & crt
-- 6/4 6/10
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
library ARITHMETIC;
use ARITHMETIC.std_logic_arith.all;

entity vgacrt2c is
        PORT (
                        AHout:out std_logic_vector(7 downto 0);
                        ALout:out std_logic_vector(2 downto 0);
                        AHin:in std_logic_vector(7 downto 0);
                        ALin:in std_logic_vector(2 downto 0);
                        ROMadrs:out std_logic_vector(2 downto 0);
                        ROMDATA:in std_logic_vector(7 downto 0);
                        A11_15:in std_logic_vector(4 downto 0);
                        IOWR:in std_logic;
                        IORD:in std_logic;
                        MREQ:in std_logic;
                        MWR:in std_logic;
                        VRAMWR:out std_logic;
                        VRAMS:out std_logic;
                        D0IN:in std_logic;
                        D1IN:in std_logic;
                        D7OUT:out std_logic;
                        RGB_ROUT:out std_logic;
                        RGB_GOUT:out std_logic;
                        RGB_BOUT:out std_logic;
                        HSYNC:out std_logic;
                        VSYNC:out std_logic;
                        CRTVHSYNC:out std_logic;
                        CRTDSP:out std_logic;
                        Notused58:in std_logic;
                        Notused73:in std_logic;
                        Notused74:in std_logic;
                        SW80_40:in std_logic;
                        SWVGACRT:in std_logic;
                        Resetin:in std_logic;
                        CKIN1 :in std_logic;
                        CKIN2 :in std_logic);

end vgacrt2c;

architecture rtl of vgacrt2c is
        signal cntr0:std_logic;
        signal cntr1:std_logic_vector(3 downto 0);
        signal cntr2:std_logic_vector(6 downto 0);
        signal cntr3:std_logic_vector(8 downto 0);
        signal ramadrswk:std_logic_vector(7 downto 0);
        signal ramadrswk0:std_logic_vector(7 downto 0);
        signal sftrgstr:std_logic_vector(7 downto 0);
        signal hblnkwk:std_logic;
        signal hblnkwk2:std_logic;
        signal cntr3wk:std_logic;
        signal vblnkwk:std_logic;
        signal vrams2:std_logic;
        signal vactive:std_logic;
        signal rgbout:std_logic;
        signal hsyncwk:std_logic;
        signal vsyncwk:std_logic;
        signal cntr1_2:std_logic;
        
        
begin
--clock select
process(CKIN1,CKIN2)
begin
        if SWVGACRT='1' then
                cntr0<=CKIN1;
        elsif SW80_40='1' then
                cntr0<=CKIN2;
        elsif CKIN2'event and CKIN2='0' then
                cntr0<=cntr0+'1';
        end if;
end process;
--cntr1 & sftrgstr
process(cntr0)
begin
        if cntr0'event and cntr0='0' then
                if cntr1="0111" then
                        sftrgstr<=ROMDATA;
                        cntr1<="0000";
                else         
                        cntr1<=cntr1+"0001";
                        sftrgstr<=sftrgstr(6 downto 0) & '1';
                end if;
   end if;
end process;
--
--cntr2
cntr1_2<=cntr1(2);
process(cntr1_2)        
begin
        if cntr1_2'event and cntr1_2 = '0' then
                if SWVGACRT='1' and cntr2="1100011" then 
                cntr2<="0000000";
                elsif SW80_40='1' and cntr2="1101111" then 
                cntr2<="0000000";
                elsif SW80_40='0' and cntr2="0110111" then
                        cntr2<="0000000";
                else
                cntr2 <= cntr2 +"0000001";
                end if;
        end if;
end process;

--hblnk,hsync
--hblnkwk
process(cntr2)
begin
        if cntr2="0000000" then
                hblnkwk<='1';
        elsif SWVGACRT='1' and cntr2="1010000" then
                hblnkwk<='0';
        elsif SW80_40='1' and cntr2="1010000" then
                hblnkwk<='0';
        elsif SW80_40='0' and cntr2="0101000" then
                hblnkwk<='0';
        end if;
end process;
--
--hblnkwk2
process(cntr2)
begin
        if cntr2="0000001" then
                hblnkwk2<='1';
        elsif SWVGACRT='1' and cntr2="1010001" then
                hblnkwk2<='0';
        elsif SW80_40='1' and cntr2="1010001" then
                hblnkwk2<='0';
        elsif SW80_40='0' and cntr2="0101001" then
                hblnkwk2<='0';
        end if;
end process;
--
--hsynkwk
process(cntr2)
begin
        if SWVGACRT='1' then
        if cntr2="1010011" then
                        hsyncwk<='0';
                elsif cntr2="1011111" then
                        hsyncwk<='1';
                end if;
        elsif SW80_40='1' then
        if cntr2="1011001" then
                        hsyncwk<='0';
                elsif cntr2="1100000" then
                        hsyncwk<='1';
                end if;
        else
                if cntr2="0101101" then
                        hsyncwk<='0';
                elsif cntr2="0110000" then
                        hsyncwk<='1';
                end if;
        end if;
end process;
--
--cntr3
process(hblnkwk)
begin
        if hblnkwk'event and hblnkwk = '1' then
                if SWVGACRT='1' and cntr3="111000000" then
                        cntr3<="000000000";
                else
                        cntr3 <= cntr3 +"000000001";
                end if;
        end if;
end process;

-- vblnk,vsync
--vblnkwk
process(cntr3)
begin
        if SWVGACRT='1' then
                if cntr3(8)='0' then 
                        vblnkwk<='1';
                elsif cntr3(8 downto 4)="11001" then
                        vblnkwk<='0';
                end if;         
        elsif cntr3(7)='0' then 
                vblnkwk<='1';
        elsif cntr3(7 downto 3)="11001" then
                vblnkwk<='0';
        end if;
end process;
--vsyncwk
process(cntr3)
begin
        if SWVGACRT='1' then
                if cntr3="110011100" then
                        vsyncwk<='0';
                elsif cntr3="110011110" then
                        vsyncwk<='1';
                end if;
        elsif cntr3(7 downto 3)="11011" then
                vsyncwk<='0';
        elsif cntr3(7 downto 4)="1110" then
                vsyncwk<='1';
        end if;
end process;
                
--ramadrs
process(cntr1_2)
begin
        if cntr1_2'event and cntr1_2='0' then
                if vblnkwk='0' then
                        ramadrswk<="00000000";  
                        ramadrswk0<="00000000";
                elsif SWVGACRT='1' then
                        if cntr3(3 downto 0)="1111" and hblnkwk = '0' then
                        ramadrswk0 <= ramadrswk;
                        elsif cntr2="1010000" then
                        ramadrswk <= ramadrswk0;
                        elsif cntr2(2 downto 0)="111" and hblnkwk='1' then
                                ramadrswk<=ramadrswk+"00000001";
                        end if;
                elsif cntr3(2 downto 0)="111" and hblnkwk = '0' then
                ramadrswk0 <= ramadrswk;
                elsif SW80_40='1' and cntr2="1010000" then
                ramadrswk <= ramadrswk0;
                elsif SW80_40='0' and cntr2="0101000" then
                ramadrswk <= ramadrswk0;
                elsif cntr2(2 downto 0)="111" and hblnkwk='1' then
                        ramadrswk<=ramadrswk+"00000001";        
                end if;
        end if;
end process;                    
-- address select
-- vrams
process(MREQ,MWR)
begin
        if MREQ='0' and MWR='0' and A11_15="11111" and vrams2='0' then
                VRAMS<='0';
                AHout<=AHin;
                ALout<=ALin;
                VRAMWR<=MWR;                            
        else 
                VRAMS<='1';
                AHout<=ramadrswk;
                ALout<=cntr2(2 downto 0);
                VRAMWR<='1';
        end if;
end process;

-- vblnk read
-- i/o active vrams vactive     
process(Resetin,AHin,ALin,IOWR)
begin
        if Resetin='0' then
                vrams2<='1';
                vactive<='1';
        elsif  AHin(4 downto 0)="11010" and ALin(2)='0' and IOWR='0' then
                vrams2<=not D0IN;
                vactive<=not D1IN;
        end if;
end process;
--
process(AHin,ALin,IORD)
begin
        if AHin(4 downto 0)="11010" and ALin(2)='0' and IORD='0' and vblnkwk='0' then
                D7OUT<='0';
        else 
                D7OUT<='Z';
        end if;
end process;
--                              
        Hsync<=hsyncwk;
        Vsync<=vsyncwk;
        rgbout<=sftrgstr(7) and hblnkwk2 and vblnkwk and vactive;
        RGB_ROUT<=rgbout;
        RGB_GOUT<=rgbout;
        RGB_BOUT<=rgbout;
--
process(cntr3)
begin
        if SWVGACRT='1' then
                ROMadrs<=cntr3( 3 downto 1);
        elsif SWVGACRT='0' then
                ROMadrs<=cntr3(2 downto 0);
        end if;
end process;

--crt out
process(rgbout)
begin
                if rgbout='0' then
                        CRTDSP<='0';
                else
                        CRTDSP<='Z';
                end if;
end process;

process(hsyncwk,vsyncwk)
begin
        if hsyncwk='0' or vsyncwk='0' then
                CRTVHSYNC<='0';
        else
                CRTVHSYNC<='Z';
        end if;
end process;
        
end rtl;

●コンパイルレポート

下はコンパイルレポートです。



macrocellは128個のうち96個を消費しましたが、率では75%ですからまだ25%残っています。
前回お見せしたCRTIF(80字表示/40字表示切換え)回路では87個を消費していました(68%)から、そこにVGAIF回路を加えてもわずかな増加にとどまっています。
VGAIF回路とCRTIF回路とでカウンタ回路などほとんどの回路を兼用して使っていることが利いています。
macrocellは余裕を残していますが、入出力端子はしっかり使い切ってしまいました。

●Pin Planner

Pin Plannerの画面です。


左下に端子名と端子番号の接続表が表示されています。
使用した端子数が多いので残りが下に隠れていて全部は見えません。

表のサイズを大きくして、さらにスクロールさせて下に隠れていた残りを表示させました。



CPLD入門![第65回]
2019.6.12upload

前へ
次へ
ホームページトップへ戻る