问题描述
我有一个 VHDL BCD 计数器,它的输出是一个整数值(数字)。
但是当我在 Xilinx ISE 中模拟代码时,它以二进制值显示代码的波形。代码有效,但输出应该是整数,但不是。我已经在 Modelsim 中测试了这段代码,输出是正确的,并且是整数值。这个问题也是在代码综合中,值是二进制的。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity bcdcnt is
Port ( clk : in STD_LOGIC;
digit : out INTEGER RANGE 0 TO 9);
end bcdcnt;
architecture Behavioral of bcdcnt is
begin
count: PROCESS(clk)
VARIABLE temp : INTEGER RANGE 0 TO 10;
BEGIN
IF (clk'EVENT AND clk = '1') THEN
temp := temp + 1;
IF (temp = 10) THEN temp := 0;
END IF;
END IF;
digit <= temp;
END PROCESS count;
end Behavioral;
解决方法
这就是合成的作用。
这就是综合必须做的:它将您的高级设计转换为 FPGA 或 ASIC 中的二进制资源。那么,这里有什么问题?
如果您需要模拟合成后的结果,通常的方法是创建一个采用正确端口类型的包装实体,并在这些和合成后网表组件之间进行转换。
然后,模拟应该与原始实体或这个包装实体一起工作,两者都有整数端口。
更好的是,您可以重复使用相同的实体,并将包装器添加为第二个架构,从而保证它使用相同的接口(端口)。
(您甚至可以在测试台的包装器中实例化原始和后合成器,并在其输出上并行使用比较器,以查看它们都做同样的事情。但请注意,两者之间会有门级延迟它们;通常您只在时钟边沿检查输出,因此这些无关紧要。)
另一种方法是将设计顶层的端口类型限制为二进制类型,如 std_logic_vector。这对于设计糟糕的工具来说效果更好,例如 ISE,其中自动生成的测试平台将具有二进制端口类型(我通常将它们编辑回正确的类型;从头开始编写 TB 几乎更容易)。
但它限制您使用晦涩复杂的设计风格,而不是像整数这样的更高级别的抽象。
很糟糕 - 真的很糟糕 - 这种方法被如此广泛地教授和鼓励。但它是,有时你不得不忍受它。 (即使采用这种方法,也没有理由避免 FPGA 内部的体面抽象,只要综合工具理解它们即可)。
第三种方法——粗略地说,“信任,但要验证”——是相信综合工具的编写能力很强——这通常是正确的——而忘记综合后的模拟。
只需在仿真的行为级别彻底验证设计,然后对其进行综合,并在现场 FPGA 中进行测试。
在 99% 的情况下(除非您正在编写 really weird VHDL),合成器和 P&R 做了正确的事情,您看到的任何差异都是由于上述 I/O 时序(I /O 引脚)。然后在测试平台和/或包装器中对这些进行建模,直到您在两者中看到相同的行为(修复任何需要修复的内容,然后重新合成)。
在这种方法中,如果您需要追踪可疑的综合工具错误,您只需要处理(慢得多)后合成和后 PAR 模拟。
这确实发生了:我在四分之一个世纪里见过两次。
大多数时候我只使用第三种方法。