问题
I am required to design a modulo "n" counter with generic parameters. I am having trouble fixing the length of the std_logic_vector which will hold the output. Firstly, I get errors regarding the use of airthmetic operators on numeric types. And secondly, I am not allowed to use a dynamic expression in the range specification of the vector. Here is my code so far:
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;
回答1:
Some suggestions:
Must change
ceil(log2(1.0*n))
tonatural(ceil(log2(real(n))))
, to address the type mismatchesMust change
count := 0
tocount := (others => '0')
, since it is not possible to assign0
directly tostd_logic_vector
.May change
integer range 1 to integer'right
topositive
, since use of thestandard
package type states the intention clearlyMay change range in variable declaration to
data_in'range
, since use of the VHDL attribute states the intention clearlyMay change
if(conv_integer(count)=n-1) then
toif (count = n-1) then
, since theconv_integer
is not required when usingieee.std_logic_unsigned.all
May change
if(...) then
toif ... then
, since()
are not required inif
becauseif
is a statement and not a functionMay change
clk'event and clk = '1'
torising_edge(clk)
, since use of thestd_logic_1164
package function states the intention clearlyMay change the
else if
to use ofelsif
for a clearer and less verbose style
The code can then be updated to:
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;
Consider changing ieee.std_logic_unsigned
to ieee.numeric_std.all
, since
the ieee.std_logic_unsigned
is not a standard package, so the place in the
ieee
library is misleading. It requires change in inner if
to:
if to_integer(unsigned(count)) = n-1 then
count := (others => '0');
else
count := std_logic_vector(unsigned(count)+1);
end if;
来源:https://stackoverflow.com/questions/23882781/modulo-n-generic-counter