如何在VHDL中将Nexys3的100MHz时钟分频为0.01Hz并解决整数溢出报错
VHDL 100MHz转0.01Hz时钟分频报错解决方案
错误原因
VHDL 标准中默认integer类型为32位有符号整数,最大值仅为2147483647。你需要的分频系数为100MHz / 0.01Hz = 10000000000,远大于整数上限,因此传递generic参数时直接写入该字面量会触发越界报错。
另外你现有逻辑还存在一处隐含问题:判断temp >= 1010中1010是十进制值,而你定义的temp仅为4位向量,最大值为15,永远无法触发复位条件,需要改为二进制字面量"1010"或者十进制值10。
修复方案
方案1:修改分频器参数与计数器位宽
调整你的frekdiv分频器实体,明确generic参数的取值范围,同时匹配足够位宽的计数器:
-- 修改后的分频器实体 entity frekdiv is generic ( -- 指定参数范围,告知综合器分配足够存储位宽 DIV_COUNT : integer range 0 to 10000000000 := 10000000000 ); port ( clk_in : in std_logic; clk_out : out std_logic ); end frekdiv; architecture Behavioral of frekdiv is -- 10000000000小于2^34,使用34位无符号计数器 signal cnt : unsigned(33 downto 0) := (others => '0'); signal clk_reg : std_logic := '0'; begin process(clk_in) begin if rising_edge(clk_in) then if cnt = DIV_COUNT - 1 then cnt <= (others => '0'); clk_reg <= not clk_reg; else cnt <= cnt + 1; end if; end if; end process; clk_out <= clk_reg; end Behavioral;
修改后你原来的例化代码无需调整即可正常使用。
方案2:拆分两级分频规避大数问题
如果你不想修改原有分频器的integer类型generic,可将10000000000拆分为100000000 * 100两次分频,两个系数均在整数上限范围内:
architecture Behavioral of stotinkasekunde is signal clk_1hz : std_logic; signal clk_001hz : std_logic; signal temp: std_logic_vector(3 downto 0) := "0000"; begin -- 第一级:100MHz转1Hz,分频系数1e8 s1: entity work.frekdiv generic map(100000000) port map(clk, clk_1hz); -- 第二级:1Hz转0.01Hz,分频系数100 s2: entity work.frekdiv generic map(100) port map(clk_1hz, clk_001hz); process (clk_001hz) begin if rising_edge(clk_001hz) then if ss='1' then temp <= temp + 1; -- 修正判断条件 if temp >= "1010" then temp <= "0000"; end if; end if; end if; end process; -- 补全剩余输出逻辑即可 end Behavioral;
内容的提问来源于stack exchange,提问作者Niko_Niko
相关产品推荐
相关产品推荐

