Сущность возвращает принудительное неизвестное «Х» - PullRequest
0 голосов
/ 25 июня 2019

Моя сущность pixel_controller во время симуляции работает (я думаю) правильно, но выводит неправильно, а точнее выводит std_logic_vector «форсирования неизвестных» вместо правильных битов.

Терминология: Charactor: линия пикселейиз 8 битов символа шрифта.

Я разрабатываю контроллер VGA, который печатает символы на экране.Поэтому после написания (копирования) работающей сущности font_ROM (был создан и протестирован тестовый стенд), я начал работать над логикой, которая будет печатать символы, хранящиеся (пока) в строке;эта логика называется Pixel Controller.
Мой pixel_controller получает сигналы от vga_controller и выводит значения rgb в течение времени screen_enable.
Важно знать, что для ограничения синхронизации контроллер пикселей запрашивает вектор символов, прежде чем они понадобятся, например: когда печатается символ N, контроллер пикселей запрашивает font_ROM для символа N + 1, чтобы на цикле N + 1 этот символ был готов.
Когда векторы символов запрашиваются в тестовом стенде для font_rom, все работает отлично, но когда то же самоесимволы запрашиваются в реализованном font_rom (внутри pixel_controller), заставляя вместо этого генерироваться неизвестные, и только для символов, содержащих хотя бы один 1.

pixel_controller.vhd

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity pixel_controller is
    Generic(
            HORIZONTAL_PIXELS  : INTEGER := 640;
            VERTICAL_PIXELS    : INTEGER := 480;
            ADDR_WIDTH         : INTEGER := 11; -- address width 2^11-1 = addressable memory                  
            DATA_WIDTH         : INTEGER := 8;  -- data width no of pixel reperesenting the character width
            CHAR_WIDTH         : INTEGER := DATA_WIDTH;
            CHAR_HEIGHT        : INTEGER := 16;  
            CHAR_IN_ALPHABET   : INTEGER := 127;
            BITS_ADDRESSING_ALPHABET   : INTEGER := 7; --ln(CHAR_IN_ALPHABET)
            BITS_ADDRESSING_CHAR_HEIGHT: INTEGER := 4; --ln(CHAR_HEIGHT)
    );
    Port ( 
           clk          : in STD_LOGIC;
           resetn       : in STD_LOGIC;
           disp_en      : in STD_LOGIC;
           pixel_col    : in INTEGER;
           pixel_row    : in INTEGER;
           VGA_R        : out STD_LOGIC_VECTOR(3 DOWNTO 0);
           VGA_G        : out STD_LOGIC_VECTOR(3 DOWNTO 0);
           VGA_B        : out STD_LOGIC_VECTOR(3 DOWNTO 0)
     );
end pixel_controller;

architecture Behavioral of pixel_controller is
    type DATA_ARRAY is array (integer range <>) OF INTEGER RANGE 0 TO 127;
    signal stream : DATA_ARRAY (0 to 127):= ( --its the srteam
        0,1,2,3,4,5,6,7,8,9,10,
        11,12,13,14,15,16,17,18,19,20,
        21,22,23,24,25,26,27,28,29,30,
        31,32,33,34,35,36,37,38,39,40,
        41,42,43,44,45,46,47,48,49,50,
        51,52,53,54,55,56,57,58,59,60,
        61,62,63,64,65,66,67,68,69,70,
        71,72,73,74,75,76,77,78,79,80,
        81,82,83,84,85,86,87,88,89,90,
        91,92,93,94,95,96,97,98,99,100,
        101,102,103,104,105,106,107,108,109,110,
        111,112,113,114,115,116,117,118,119,120,
        121,122,123,124,125,126,127
    );
    signal font_address : STD_LOGIC_VECTOR(ADDR_WIDTH-1 DOWNTO 0);
    signal font_out : STD_LOGIC_VECTOR(DATA_WIDTH-1 DOWNTO 0);
    signal char_max_col : INTEGER := HORIZONTAL_PIXELS/data_width; --max number of characters IN A row printable
    signal char_max_row : INTEGER := VERTICAL_PIXELS/data_width; --max number of text rows printable 

    signal char_VGA_col: INTEGER RANGE 0 TO HORIZONTAL_PIXELS/data_width; -- since we think in characters it's usefull to know in witch character column we are
    signal char_VGA_row : INTEGER RANGE 0 TO VERTICAL_PIXELS/data_width; -- since we think in characters it's usefull to know in witch character row we are

begin
    f_rom: entity work.fonts_rom(Behavioral)
    port map(
        clk =>clk,
        addr=>font_address,
        data_out => font_out
    );

    char_VGA_col <= pixel_col/CHAR_WIDTH; --with this we know in witch character colum we are
    char_VGA_row <= pixel_row/CHAR_HEIGHT; --with this we know on which line of text we are                                         
  GET_FUT_PIX_VAL: process (resetn,char_VGA_col) is    -- at clock N get the pixel value for process N+1
                                                    -- the process depends on the char_VGA_Col since 
                                                    -- char_VGA_row cannot change previously to it    
    variable requested_character : INTEGER := 0; -- character obtained by stream 
    variable charactor_line : INTEGER:= 0; -- which line of pixels of a specific character is requested
    begin
        if resetn = '0' then   -- async reset
            font_address <= (others => '0'); 
            font_out <= (others =>'0');
            requested_character := 0;
            charactor_line := 0;
         elsif char_VGA_col /= char_VGA_col'LAST_VALUE then -- if actual value is different then the previous one
                                                           -- process starts every CHAR_WIDTH pixel printed
           if(char_VGA_col + char_max_col*char_VGA_row < 126) -- my string contains 127 chars

            requested_character := stream(char_max_col*char_VGA_row + char_VGA_col + 1); -- note the + 1: the requested value is for the future pixel_col
                                                                                         -- the value will be accessible at a clk delay (not VGA_CLK)
            charactor_line := pixel_row MOD CHAR_HEIGHT; -- which charactor line of the character we are printing

            font_address <=  std_logic_vector(to_unsigned(requested_character,BITS_ADDRESSING_ALPHABET))
                            & std_logic_vector(to_unsigned(charactor_line,BITS_ADDRESSING_CHAR_HEIGHT));                          

           end if;     -- NB values will be requested even during the back porch pulse and front porch of v_sync
        end if;
    end process;
   PRINT_PIXEL: process (pixel_col) is -- pixel_col is effectively the same as CLK TODO:see if the latency is problematic
   begin
        if (font_out( (pixel_col)  MOD CHAR_WIDTH ) = '0' AND disp_en = '1') then -- HERE COULD BE PRINTED ALL IN REVERS ORDER LOOK AT HOW FONT_OUT IS DEFINED
            VGA_R <= (others => '1'); -- inverse coloring: white on black
            VGA_G <= (others => '1');
            VGA_B <= (others => '1');
        else 
            VGA_R <= (others => '0');
            VGA_G <= (others => '0');
            VGA_B <= (others => '0');
        end if;
   end process;

testbench_pixel_controller.vhd

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
use work.commonPak.ALL;

entity pixel_controller_testbench is
--  Port ( );
end pixel_controller_testbench;

architecture Behavioral of pixel_controller_testbench is
    component clk_wiz_0 is --takes 100MHZ and returns 25MHz 
    port(
        clk_in1 : in STD_LOGIC;
        resetn  : in STD_LOGIC;
        CLK_VGA : out STD_LOGIC
    );
    end component;
    component pixel_controller is
    Generic(
            HORIZONTAL_PIXELS  : INTEGER := 640;
            VERTICAL_PIXELS    : INTEGER := 480;
            ADDR_WIDTH         : INTEGER := 11;     
            DATA_WIDTH         : INTEGER := 8;
            CHAR_WIDTH         : INTEGER := DATA_WIDTH;
            CHAR_HEIGHT        : INTEGER := 16;  
            CHAR_IN_ALPHABET   : INTEGER := 127;
            BITS_ADDRESSING_ALPHABET   : INTEGER := 7; --ln(CHAR_IN_ALPHABET)
            BITS_ADDRESSING_CHAR_HEIGHT: INTEGER := 4; --ln(CHAR_HEIGHT)
    ); 
    port(
        clk         : in STD_LOGIC;
        resetn      : in STD_LOGIC;
        disp_en     : in STD_LOGIC;
        pixel_col   : in INTEGER;
        pixel_row   : in INTEGER;
        VGA_R       : out STD_LOGIC_VECTOR(3 DOWNTO 0);
        VGA_G       : out STD_LOGIC_VECTOR(3 DOWNTO 0);
        VGA_B       : out STD_LOGIC_VECTOR(3 DOWNTO 0)
    );
    end component;
    component vga_controller is 
    generic(
        h_pulse         : INTEGER   :=96;       
        h_bkprch        : INTEGER   :=48;       
        h_pixels        : INTEGER   :=640;      
        h_frprch        : INTEGER   :=16;       
        h_pol           : STD_LOGIC :='0';      

        v_pulse         : INTEGER   :=2;        
        v_bkprch        : INTEGER   :=33;       
        v_pixels        : INTEGER   :=480;      
        v_frprch        : INTEGER   :=10;       
        v_pol           : STD_LOGIC :='1'       
        );
    port(
        pixel_clk   : in STD_LOGIC;
        res         : in STD_LOGIC;
        h_sync      : out STD_LOGIC;
        v_sync      : out STD_LOGIC;
        disp_en     : out STD_LOGIC;
        column      : out INTEGER;
        row         : out INTEGER
    );
    end component;
    signal CLK100HZ,CPU_RESETN,VGA_HS,VGA_VS,CLK_25,disp_en : STD_LOGIC;
    signal column,row : INTEGER;
    signal VGA_R,VGA_G,VGA_B : STD_LOGIC_VECTOR (3 DOWNTO 0);
begin
    clk_wiz: clk_wiz_0 port map(
        clk_in1 => CLK100HZ,
        resetn  => CPU_RESETN,
        CLK_VGA =>CLK_25
    );
    vga_c: vga_controller port map(
        pixel_clk   => CLK_25,
        res         => CPU_RESETN,
        h_sync      => VGA_HS,
        v_sync      => VGA_VS,
        disp_en     => disp_en,
        column      => column,
        row         => row
    );
    px_ctrl: pixel_controller port map(
        clk         => CLK100HZ,
        resetn      => CPU_RESETN,
        disp_en     => disp_en,
        pixel_col   => column,
        pixel_row   => row,
        VGA_R       => VGA_R,
        VGA_G       => VGA_G,
        VGA_B       => VGA_B
    );


    CLK:process begin
        CLK100HZ <= '0';
        wait for 5ns;
        CLK100HZ <= '1';
        wait for 5ns;
    end process;

    process begin
        CPU_RESETN <= '0';
        wait for 15ns;
        CPU_RESETN <= '1';
        wait;
    end process;
end Behavioral;

VGA_controller.vhd и font_ROM.vhd (ASCII) - это файлы, которые "всегда" везде одинаковы.

На пикселе 56 первой строки должно отображаться значение 07 характера и запрашиваться значение 08 характера.Запрос выполняется, и после clk значение должно быть «11111111», иначе xff, вместо этого я получаю кучу «X».

Здесь визуализация последовательности
- clk100 - это система clk, с которой выполняются запросы шрифтов
- clk25 - это VGA clk, с помощью которого рисуются пиксели.testbench timeline

...