0

このVHDLを使って画面上にグリッドを作ろうとしています。今は2本の線が書けるのですが、画面を更新すると線が動いてしまいます。エラーがどこにあるのかわかりません。誰かが助けたり、ポインタを提供したりできますか?

library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.std_logic_unsigned.all;
--use IEEE.std_logic_arith.all; --VVVVVVV
use IEEE.NUMERIC_STD.all;       --^^^^^^^ 

entity SCRN is
port(
    clk     : in STD_LOGIC;
    vga     : OUT STD_LOGIC_VECTOR (7 downto 0);
    Hsync : OUT STD_LOGIC;
    Vsync : OUT STD_LOGIC
    );
end SCRN;

architecture Behavioral of SCRN is

type PLC_HOLD is array (1 to 800, 1 to 525) of STD_LOGIC_VECTOR(7 downto 0);
signal scrn : PLC_HOLD;

signal s_clk    : std_logic_vector (1 downto 0) := (others => '0');
signal xx_vga   : std_logic_vector (7 downto 0);

signal xx_h : std_logic;
signal xx_v : std_logic;

signal X : std_logic_vector (9 downto 0) := (others => '1');
signal Y : std_logic_vector (9 downto 0) := (others => '1');

-- signal test : ieee.numeric_std.unsigned 
-- test now works with mod
begin

NW_CLK: process (clk) is
    begin
    if rising_edge (clk) then 
        s_clk <= (s_clk + "01");
    end if;
end process NW_CLK;
--###############################--
scrn_loc : 
process (s_clk(1)) is

begin
    if RISING_EDGE (s_clk(1)) then
    X <= X + "0000000001";
        if (X = "1100100000") then --if x = 800
            X <= "0000000001"; 
            Y <= (Y + "0000000001");
        elsif (Y = 525) then -- if y = 525
            X <= "0000000001"; 
            Y <= "0000000001";
        end if;
    end if;
end process;

--###############################--
draw : 
process (X,Y) is 

    -- h and v sync process
    begin
    if (X > 640) then -- and (X <= 752) then -- low for sync pulse at 656 to 752 -- 96 pixel
        xx_h <= '0';
    else 
        xx_h <= '1';
    end if;

    if (Y> 490) and (Y <= 492) then -- low for sync puls at 490 to 492
        xx_v <= '0';
    else
        xx_v <= '1';
    end if;
--  (CONV_INTEGER((X)) mod 10)
-- CONV_INTEGER(Y) mod 10
--  if  X = 1 then
--      xx_vga <= "00111000";
----    elsif Y = 1 or Y = 480 then
----        xx_vga <= "11101011";
--  else 
--      xx_vga <= "11100000";
--  end if;

end process;
--###############################--


scrn(CONV_INTEGER(X),CONV_INTEGER(Y)) <=    "00111000" when X = 1 else
                                                "11100101" when Y = 2 else
                                                "00000111" when X = 640 else
                                                "11001101";

Hsync <= xx_h;
Vsync <= xx_v;

vga <= scrn(CONV_INTEGER(X),CONV_INTEGER(Y));

end Behavioral;
4

3 に答える 3

1

うーん...割り当て先の行をプロセス内のどこかに移動するとどうなりますscrn(CONV_INTEGER(X),CONV_INTEGER(Y)) <= "00111000" when X = 1 else ...か?

また、コードでバイナリ リテラルを使用する必要もありません (例: if (X = "1100100000"))。整数リテラルまたは 10 進ビット文字列リテラルを使用してください。さらに良いことに、すべての数値を整数または自然数として定義します。おまけとして、これらすべての変換関数が不要になるため、コードがよりクリーンになります。

于 2013-11-14T18:52:16.077 に答える
0

時計から時計を作成していますが、これは悪い考えです。あなたは4で割ろうとしているようですか?代わりに、イネーブル パルスを作成します。

NW_CLK: process (clk) is
  variable divider : integer range 0 to 3;
    begin
    if rising_edge (clk) then 
        if divider = 3 then
           divider := 0;
           screen_process_enable <= '1';
        else
           divider := divider + 1;
           screen_process_enable <= '0';
        end if
    end if;
end process NW_CLK;

次に、画面プロセスで:

scrn_loc : process (clk) is

begin
    if RISING_EDGE (clk) and screen_process_enable = '1' then
       etc...

あなたの質問とは関係ありませんが、とにかくここでコメントします。画面全体をメモリに保持しようとしているようです-これは、実際のチップで要求している非常に多くのストレージです(シミュレーション)。

グリッドを作成するには、x カウンターと y カウンターの値に応じて VGA 出力に割り当てることで、オンザフライで行うことができます。scrnプロセスへの割り当てとプロセス外の割り当ての両方があるためvga、シンセサイザーはおそらく、要求したメモリ ストレージをまったく使用せず、最適化してしまったことを理解するのに十分賢いでしょう。将来scrn、真のフレームバッファとして使用するようになった場合、デバイスによっては、パフォーマンスまたはリソースの制限に直面する可能性があります。

于 2013-11-15T10:45:53.810 に答える
0

「Circuit Design and Simulation with VHDL」の第 15 章 (VHDL Design of VGA Video Interfaces) を確認してください。詳細な VGA 理論と、VHDL および VGA モニターを使用した多数の実験が示されています。

于 2013-11-18T13:28:29.810 に答える