方向不匹配且在 Vivado 中没有驱动程序警告

Direction mismatch and does not have driver warning in Vivado

您好,我收到了这些警告,由于这些警告,我的代码无法按预期工作。具体来说,下面是完整的警告。顺便说一句,由于这两个警告彼此密切相关,所以我问这个问题包括这两个警告,而不是问两个单独的问题。

[Synth 8-547] port direction mismatch for port 'douta' 
[Synth 8-3848] Net data_out_ram in module/entity top_mod does not have 
driver.

但是,不需要这些警告。据我所知,驱动程序意味着连接,下面的这个信号有连接。我的意思是我不明白这些警告背后的原因。

signal data_out_ram : std_logic_vector(11 downto 0); --declared in top_module

U4: Block_Ram port map(addra => address_ram,
                       clka => clk,
                       dina => data_in_ram,
                       douta => data_out_ram, -- here
                       wea => write_enable);

U5: Brightness_Contrast port map(clk_in => clk,
                                 operation => operation,
                                 pos_x => pos_x,
                                 pos_y => pos_y,
                                 data_in => data_out_ram, --here
                                 cursor_pos_x => cursor_pos_x,
                                 cursor_pos_y => cursor_pos_y,
                                 length => length,
                                 output_of_operation => output_of_operation,
                                 mode => mode);

U6: Display port map(clk_in => clk,
                     rst => rst,
                     visible => visible,
                     data_r => data_r,
                     data_g => data_g,
                     data_b => data_b,
                     pos_x => pos_x,
                     pos_y => pos_y,
                     data_out_ram => data_out_ram, --here
                     length => length,
                     cursor_pos_x => cursor_pos_x,
                     cursor_pos_y => cursor_pos_y);

component Display
port(clk_in : in  std_logic ;
rst     : in  std_logic;
visible: in std_logic;
data_r  : out std_logic_vector(COLOR_BIT-1 downto 0);
data_g  : out std_logic_vector(COLOR_BIT-1 downto 0);
data_b  : out std_logic_vector(COLOR_BIT-1 downto 0);
pos_x  : in integer range 0 to 2047;
pos_y  : in integer range 0 to 2047;
display_data: in std_logic_vector(11 downto 0);
length: in integer range 0 to PICTURE_WIDTH_HEIGHT;
cursor_pos_x: in integer range 0 to PICTURE_WIDTH_HEIGHT;
cursor_pos_y: in integer range 0 to PICTURE_WIDTH_HEIGHT
);
end component;

component Block_Ram
port(addra :in std_logic_vector(15 downto 0);
 clka : in std_logic;
 dina : in std_logic_vector(11 downto 0);
 douta: in std_logic_vector(11 downto 0);
 wea: in std_logic);
 end component;

component Brightness_Contrast
port (
clk_in : in  std_logic;
operation : in std_logic_vector(1 downto 0);
pos_x: in integer range 0 to 2047 ;  
pos_y: in integer range 0 to 2047 ; 
data_in: in std_logic_vector(11 downto 0);
cursor_pos_x: in integer range 0 to PICTURE_WIDTH_HEIGHT;
cursor_pos_y: in integer range 0 to PICTURE_WIDTH_HEIGHT;
length: in integer range 0 to PICTURE_WIDTH_HEIGHT;
output_of_operation: out std_logic_vector(11 downto 0);
mode: in std_logic
);

Ram是用块内存生成器构建的

我真的需要这方面的帮助。我该如何解决这里的问题??

好的。

除了 douta: in std_logic_vector(11 downto 0); 上明显不正确的端口模式之外,这里还有一个教训要吸取。

VHDL 是在一个截然不同的时代设计的,当时计算机的功能要弱得多,编译是一项相当缓慢且昂贵的操作;因此它允许单独编译和检查模块,而无需读取和编译大量其他模块。

Component 语句是该机制的一部分:它告诉编译器您的设计意图是将此模块连接到具有一堆输入端口但没有输出的 component Block_Ram,即Write Only Memory.

它忠实地遵循了这个设计意图,提醒你沿途的任何问题;例如这些错误消息:没有驱动程序的信号。您可以通过任何方式解决该错误,也许可以通过添加驱动程序 data_out_ram <= something_else; 消除该错误。

稍后,设计将是"elaborated",将一堆成功编译的模块连接在一起,在适当的库中搜索与组件声明匹配的只写内存。但是在这个阶段,您可以在不编写任何这些模块的情况下进行编译。

如果它找到一个,那么一切都很好,您的设计将进行综合,成功地实现您所陈述的设计意图。

然而,更有可能的是,阐述会失败,因为你的库中最接近的匹配是

entity Block_Ram
port(addra :in std_logic_vector(15 downto 0);
 clka : in std_logic;
 dina : in std_logic_vector(11 downto 0);
 douta: out std_logic_vector(11 downto 0);
 wea: in std_logic);
end entity;

一个完全正常的 RAM,在 in 端口应该是 douta 的地方有一个 out 端口。显然你的编译器在编译时执行检查而不是详细说明,给你 "port direction mismatch" 错误。那么为何不?编译速度比 1980 年代快了几个数量级。


真正可悲的是,VHDL 仍然被教导,好像它应该用于在 1980 年代机器上编译的 1980 年代设计。

那种程度的单独编译现在完全没有必要了。

所以删除所有组件声明,改用直接实体实例化。即:

U4: entity Work.Block_Ram port map(addra => address_ram,
                       clka => clk,
                       dina => data_in_ram,
                       douta => data_out_ram, 
                       wea => write_enable);

它会直接实例化你已经编译到库Work中的任何BlockRam。 (当然,这确实要求所有这些实体都已经被写入,并且它将编译它们以交叉检查端口接口)。如果 BlockRam 在其他库中,只需更改实例化中的库名称即可。

如果您真的想要一个带有实际输出端口的 RAM,这将顺利通过,因为没有 Component 声明来犯一个愚蠢的错误。

这是 VHDL 教学落后于良好 VHDL 实践数十年的几个领域之一,鼓励大型和容易出错的设计,其中更小、更简单的形式会减少错误。