我正在创建一个变频脉冲序列来控制电机,并使用以下代码使用计数器生成脉冲,该计数器按某个输入增量值进行计数inc_i
。然后,我将计数器输出的 MSBdout_o[N-1]
传输到 FPGA 上的输出引脚。这应该给我一个所需频率的 50% 占空比方波,但我只是看到一个信号开始变低,变高,然后再也不会关闭。我的代码有明显问题吗?
--****************************************************************************
-- Load required libraries
--****************************************************************************
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
--****************************************************************************
-- Define the inputs, outputs, and parameters
--****************************************************************************
entity var_count is
generic(N: integer :=32); -- for generic counter size
port(
inc_i : in std_logic_vector(N-1 downto 0);
load_i : in std_logic;
clk_i : in std_logic;
clear_i : in std_logic;
clk_en_i : in std_logic;
count_en_i : in std_logic;
msb_o : out std_logic
);
end var_count;
--****************************************************************************
-- Define the behavior of the counter
--****************************************************************************
architecture behavior of var_count is
-- Define our count variable. No need to initialize in VHDL.
signal count : unsigned(N-1 downto 0) := to_unsigned(0, N);
signal incr : unsigned(N-1 downto 0) := to_unsigned(0, N);
begin
-- Define our clock process
clk_proc : process(clk_i, clear_i, load_i)
begin
-- Asynchronous clear
if clear_i = '1' then
count <= to_unsigned(0, N);
end if;
-- Asynchronous load
if load_i = '1' then
incr <= unsigned(inc_i);
end if;
-- Define processes synch'd with clock.
if rising_edge(clk_i) and clk_en_i = '1' then
if count_en_i = '1' then -- increment the counter
count <= count + incr;
end if;
end if;
end process clk_proc;
-- Output the MSB for the sake of generating a nice easy square wave.
msb_o <= count(count'left);
end behavior;
方波频率应由pulse_freq = clock_freq * inc_i / 2^N
N 位计数器的公式给出。
我还试图通过将我的计数器输出 ( msb_o(k)
) 的 MSB 传递给一位 DQ 触发器来获取msb_o(k-1)
然后执行:
pulse = ~msb_o(k) * msb_o(k-1)
where~
代表逻辑NOT
,并且*
代表逻辑AND
。这应该只在计数器翻转时给我一个时钟周期脉冲。当我使用示波器读取输出引脚时,这和 MSB 本身(50% 占空比方波)都没有显示。如果您在我的代码中发现任何错误,请告诉我。
谢谢您的帮助!
编辑1:我已经用用户提出的建议更新了问题中的代码。现在,当我输出计数器的 MSB 时,它会变高并且永远不会再次关闭。我需要在溢出时重置计数器(我在上面尝试过这样做)。关于如何做到这一点的任何建议?
编辑 2:我意识到,由于我的增量值inc_i
不一定是 1,因此我可能没有达到2**N - 1
用于翻转计算的值。因此,我将翻转条件更改为:
if count > (2**N - unsigned(inc_i) - 1) then
count <= to_unsigned(0, N);
我现在似乎得到了脉冲,但它们并不完全是 50% 的占空比(我认为这是有道理的),当我改变我的增量值时,它们似乎没有像预期的那样改变inc_i
。知道为什么利率没有变化吗?
编辑 3:我意识到我对我的应用程序所关心的只是计数器的 MSB,因为我将使用它来生成 50% 占空比的方波,或者当它翻转时产生一个脉冲。鉴于此,我dout_o
在实体声明中替换为:
`msb_o : out std_logic`
我将最后的并发赋值语句替换为:
msb_o <= '1' when count > (2**(N-1) - 1) else '0';
我仍然收到非常奇怪的脉冲,它们根本不是 50% 的占空比或不一定是正确的频率。任何进一步的建议将不胜感激。
编辑 4:通过进一步的更改更新了我的代码。还将这本免费书添加到参考列表中。
编辑 5:将我的代码更新为(最终)工作版本。