在下面的代码中,我提前一个周期输出。我期待为pos_cnt和neg_cnt形成一个寄存器。综合工具提供2个没有寄存器的计数器。为什么呢?
architecture rtl of divide_by_3 is
signal pos_cnt :std_logic_vector (1 downto 0):="00";
signal neg_cnt :std_logic_vector (1 downto 0):="00";
begin
process (clk, reset) begin
if (reset = '1') then
pos_cnt <= (others=>'0');
elsif (rising_edge(clk)) then
if (pos_cnt /= "01") then
pos_cnt <= pos_cnt + 1;
else
pos_cnt <= (others=>'0');
end if;
end if;
end process;
process (clk, reset) begin
if (reset = '1') then
neg_cnt <= (others=>'0');
elsif (falling_edge(clk)) then
if (neg_cnt /="01") then
neg_cnt <= neg_cnt + 1;
else
neg_cnt <= (others=>'0');
end if;
end if;
end process;
cout <= '1' when ((pos_cnt="01") and (neg_cnt ="01")) else
'0';
结束架构;
答案 0 :(得分:0)
区分寄存器和计数器有点误导。生成标准寄存器或触发器的代码和代码之间的唯一区别是计数器的输入来自计数器本身。如果我冒昧地从您的代码中删除特殊的环绕式案例,那么您的一个计数器将成为:
Count1 : process (clk, rst)
begin
if rst = '1' then
pos_cnt <= (others => '0');
elsif rising_edge(clk) then
pos_cnt <= pos_cnt + 1;
end if;
end process Count1;
基本寄存器是:
Reg1 : process (clk, rst)
begin
if rst = '1' then
q <= (others => '0');
elsif rising_edge(clk) then
q <= d;
end if;
end process Reg1;
q
滞后d
一个时钟周期。现在,您可以将Count1
重写为:
signal next_pos_cnt : ...
...
next_pos_cnt <= pos_cnt + 1;
Count2 : process (clk, rst)
begin
if rst = '1' then
pos_cnt <= (others => '0');
elsif rising_edge(clk) then
pos_cnt <= next_pos_cnt;
end if;
end process Count2;
该功能与Count1
相同,您应该认识到时钟进程与Reg1
几乎完全相同。两者都是寄存器。一个只需要一个外部输入,另一个只有反馈。
因此,当你说你希望计数器的行为类似于寄存器时,你可能只是错过了计数器输入只是本身的(组合)函数的事实。计数器的下一个值(在时钟边沿分配)滞后于其输入一个时钟周期,就像寄存器一样。唯一的区别是输入来自哪里。因此,由于它的起始值为0,在复位后的第一个时钟边沿,它变为自身(0)+ 1.有意义吗?额外的时钟周期延迟在哪里?
如果您有任何不明白或无法回答的问题,请告知我们。
编辑:我想提一下,如果需要,可以为计数器添加一个时钟启用,如下所示:
...
elsif rising_edge(clk) then
if clk_en = '1' then
pos_cnt <= pos_cnt + 1;
end if;
end if;
然后,pos_cnt
的值将在您声明clk_en
后改变一个时钟。也许这会更接近你期望的结果。