雕虫小技

可预置计数器/分频器

这个电路比较简单,就是一个加法计数器,在计数到最大值时候,同步载入预置值,实现可预置的计数/分频。不过还是值得我学习,代码如下:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity counter is
port(clk : in std_logic;
q   : out std_logic;
set_q :in std_logic_vector(7 downto 0));
end counter;
architecture behav of counter is
signal reg : std_logic_vector(7 downto 0);
begin
process
begin
reg<=set_q;
wait until falling_edge(clk);
end process;
process
variable num : integer range 255 downto 0;
begin
if num=255 then
num:=conv_integer(reg);
q<=’1′;
else
num:=num+1;
q<=’0′;
end if;
wait until rising_edge(clk);
end process;
end behav;
综合后的RTL电路如下:

counter_rtl

仿真波形:

counter_wave
不过这个电路有两个明显的缺点,第一是分频数是计数最大值和输入预置数的差值,而不是直接等于预置值,第二是输出脉冲太窄,用它来驱动后续的低速电路的话是不合适的。
下面的电路进行了一些改进,可以克服这两个缺点,
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity counter is
port(clk :in std_logic;
q   :out std_logic;
set_q :in std_logic_vector(7 downto 0));
end counter;
architecture behav of counter is
signal reg, num : std_logic_vector(7 downto 0);
begin
process
begin
reg<=set_q;
wait until falling_edge(clk);
end process;
process
begin
if num=”00000000″ then
num<=reg;
else
num<=num-1;
end if;
wait until rising_edge(clk);
end process;
process
begin
if conv_integer(num)<=conv_integer(reg)/2 then
q<=’0′;
else
q<=’1′;
end if;
wait until rising_edge(clk);
end process;
end behav;RTL电路如下,
counter_rtl_a

仿真波形如下,
counter_wave_a

Leave a Reply

Your email address will not be published. Required fields are marked *