实体返回强迫未知的“ X”

时间:2019-06-25 01:46:35

标签: vhdl fpga vga

我的pixel_controller实体在仿真过程中会正确运行(我认为),但输出错误,更具体地说,它将输出“强制未知”的std_logic_vector而不是正确的位。

术语: 字符:字符字体的8位像素行。

我正在开发一个VGA控制器,可以在屏幕上打印文字。 因此,在编写(复制)了一个有效的font_ROM实体(已建立并测试了一个测试台)之后,我开始研究将打印(暂时)存储在字符串中的字符的逻辑。这种逻辑称为像素控制器。
我的pixel_controller从vga_controller获取信号,并在screen_enable时间内输出rgb值。
重要的是要知道,对于时序约束,像素控制器在需要字符向量之前会先询问它们,例如:打印字符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

0 个答案:

没有答案