modulo n generic counter

帅比萌擦擦* 提交于 2019-12-10 17:22:37

问题


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)) to natural(ceil(log2(real(n)))), to address the type mismatches

  • Must change count := 0 to count := (others => '0'), since it is not possible to assign 0 directly to std_logic_vector.

  • May change integer range 1 to integer'right to positive, since use of the standard package type states the intention clearly

  • May change range in variable declaration to data_in'range, since use of the VHDL attribute states the intention clearly

  • May change if(conv_integer(count)=n-1) then to if (count = n-1) then, since the conv_integer is not required when using ieee.std_logic_unsigned.all

  • May change if(...) then to if ... then, since () are not required in if because if is a statement and not a function

  • May change clk'event and clk = '1' to rising_edge(clk), since use of the std_logic_1164 package function states the intention clearly

  • May change the else if to use of elsif 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!