use*_*971 4 generics counter vhdl modulo
我需要设计一个带有通用参数的模"n"计数器.我无法修复将保存输出的std_logic_vector的长度.首先,我在数字类型上使用airthmetic运算符时遇到错误.其次,我不允许在向量的范围规范中使用动态表达式.到目前为止,这是我的代码:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.math_real.all;
entity counter_mod is
generic(n: integer range 1 to integer'right);
port(clk,reset,load:in std_logic;
data_in:in std_logic_vector(ceil(log2(1.0*n))-1 downto 0);
q:out std_logic_vector(ceil(log2(1.0*n))-1 downto 0));
end counter_mod;
architecture behavioral of counter_mod is
begin
process(clk,reset,load)
variable count:std_logic_vector(ceil(log2(1.0*n))-1 downto 0):=(others=>'0');
begin
if(reset='1') then
count:=(others=>'0');
else if(load='1') then
count:=data_in;
else if(clk'event and clk='1') then
if(conv_integer(count)=n-1) then
count:=0;
else
count:=count+1;
end if;
end if;
end if;
end if;
q<=count;
end process;
end architecture;
Run Code Online (Sandbox Code Playgroud)
一些建议:
必须ceil(log2(1.0*n))改为natural(ceil(log2(real(n)))),以解决类型不匹配问题
必须更改count := 0为count := (others => '0'),因为无法0直接分配给std_logic_vector.
可以integer range 1 to integer'right改为positive,因为使用
standard包类型清楚地表明了意图
可以将变量声明中的范围更改为data_in'range,因为使用VHDL属性清楚地表明了意图
可以更改if(conv_integer(count)=n-1) then为if (count = n-1) then,因为conv_integer使用时不需要
ieee.std_logic_unsigned.all
可以if(...) then改为if ... then,因为()不是必需的
if因为if是一个声明而不是一个函数
可以clk'event and clk = '1'改为rising_edge(clk),因为使用
std_logic_1164包函数清楚地表明了意图
可以改变else if使用elsif更清晰,更简洁的风格
然后可以将代码更新为:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.math_real.all;
entity counter_mod is
generic(n : positive);
port(clk, reset, load : in std_logic;
data_in : in std_logic_vector(natural(ceil(log2(real(n))))-1 downto 0);
q : out std_logic_vector(natural(ceil(log2(real(n))))-1 downto 0));
end counter_mod;
architecture behavioral of counter_mod is
begin
process(clk, reset, load)
variable count : std_logic_vector(data_in'range) := (others => '0');
begin
if reset = '1' then
count := (others => '0');
elsif load = '1' then
count := data_in;
elsif rising_edge(clk) then
if count = n-1 then
count := (others => '0');
else
count := count+1;
end if;
end if;
q <= count;
end process;
end architecture;
Run Code Online (Sandbox Code Playgroud)
考虑更改ieee.std_logic_unsigned为ieee.numeric_std.all,因为ieee.std_logic_unsigned它不是标准包,因此
ieee库中的位置具有误导性.它需要改变内在if:
if to_integer(unsigned(count)) = n-1 then
count := (others => '0');
else
count := std_logic_vector(unsigned(count)+1);
end if;
Run Code Online (Sandbox Code Playgroud)