0

我刚刚开始在modelsim中学习VHDL,所以如果我正在做的事情看起来真的很菜,我提前道歉。

基本上我想要创建的是一个可合成的 VHDL 代码,用于一位向上/向下 BCD 计数器。当“启用”为“1”时,计数器将计数,否则保持不变。初始化输入“Init”时,计数器根据“Direction”输入的值设置为 0 或 9。(当“方向”为“1”时,它是一个向上计数器)。

我只是想知道除了连续使用 100 个 if 和 else 之外,是否还有更好的工具可以用于此工作。

这是我的代码,我现在正在为它编写一个测试平台,所以我还不确定这是否会起作用。因此,如果您碰巧也发现了一些错误,请为我指出。

提前非常感谢,这是我的代码

entity BCD_counter is
  port(clk, direction, init, enable: in bit;
    q_out: out integer);
end entity BCD_counter;

architecture behaviour of BCD_counter is
  signal q: integer;
begin
  process(clk)
  begin
    if(Clk'event and Clk = '1') then
      if(direction = '1') then -- counting up
        if(init = '1')then --initialize
          q<=0; -- reset to 0
        else
         if(enable = '1')then -- counting          
            if (q<9) then
              q<=q+1;
            else
              q<=0;
            end if;          
         else
          q<=q;
          end if;
        end if;
      elsif(direction = '0') then --counting down
        if(init = '1') then --initialize
          q<=9; --reset to 9
        else
          if(enable = '1') then --counting        
            if (q>0) then
              q<=q-1;
            else
              q<=9;
            end if;       
          else
            q<=q;
          end if;
        end if;
      end if;
    end if;

  end process;  
      q_out <= q;  
end architecture behaviour;
4

3 回答 3

2

风格略有不同,但我会这样写

architecture behaviour of BCD_counter is
  signal next_q : integer;
  signal q      : integer;
begin

  pReg : process
  begin  -- process pReg
    wait until clk'event and clk = '1';
    if init = '1' then
      q <= 0;
    else
      q <= next_q;
    end if;
  end process pReg;

  pCount : process (direction, enable, q)
  begin  -- process pCount
    next_q <= q;

    if enable = '1' then
      if direction = '1' then
        next_q <= q + 1;

        if q = 9 then
          next_q <= 0;
        end if;

      else
        next_q <= q - 1;

        if q = 0 then
          next_q <= 9;
        end if;

      end if;
    end if;
  end process pCount;

  q_out <= q;
end architecture behaviour;

注意事项:

  • 寄存器行为与逻辑处于不同的过程中。我觉得这种风格很干净。其他人有不同的意见,通常归结为不喜欢有next_blah信号。
  • init是你的复位信号,所以它会覆盖其他一切,我把复位信号放在寄存器过程中。
  • 计数器进程的第一行是我希望默认发生的。在这种情况下,它说让 q 的下一个状态是当前状态。
  • 我有外面if的检查enable。如果我们没有启用,我们什么都不做,那为什么direction要先检查呢?
  • 在方向条件的每一半内,代码结构都是相同的。设置我想要的正常情况,然后检查规则的例外情况。例如:如果我们要上升,我将下一个状态设置为 q+1,但如果 q 为 9,我将其覆盖为 q <= 0。
  • 在任何比较中,我都没有使用>, 。<这些比 贵=,而且=很好。

或者,您可以将启用带入注册过程。它稍微短一些,并且可能更清晰。这也表明您希望使用寄存器的启用引脚来实现此功能。

  pReg : process
  begin  -- process pReg
    wait until clk'event and clk = '1';
    if init = '1' then
      q <= 0;
    else
      if enable = '1' then
        q <= next_q;
      end if;
    end if;
  end process pReg;

  pCount : process (direction, q)
  begin  -- process pCount
    if direction = '1' then
      next_q <= q + 1;

      if q = 9 then
        next_q <= 0;
      end if;
    else
      next_q <= q - 1;

      if q = 0 then
        next_q <= 9;
      end if;
    end if;
  end process pCount;
于 2012-03-27T16:26:03.677 回答
1

我唯一想到的是你可以省略这两个

else
   q<=q;

语句,因为如果没有其他条件检查,这是隐式完成的。

于 2012-03-27T10:49:15.243 回答
0

我做了很多这样的事情——我创建了一个名为的函数modulo_increment,它接受一个输入整数和“模数”整数并返回环绕的值。

所以你可以这样做

q <= modulo_increment(q, 10);
于 2012-03-27T12:42:42.980 回答