【问题标题】:Mod-M counter Unsigned values have no signalMod-M 计数器 无符号值没有信号
【发布时间】:2013-01-11 10:21:41
【问题描述】:

我正在为我的 Nexys2 开发板编写 RS232 模块。我目前的波特率控制器有问题,我想将其设置为 19200。

为此,我使用的是 Mod-M 计数器,经过多次 ISim 模拟后,我的代码的问题在于 mod-m 计数器,因为它没有产生任何滴答声。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity baud_rate is
    generic (
    N: integer := 8;
    M: integer :=163);
    Port (clk, reset : in  STD_LOGIC;
           tick : out  STD_LOGIC;
              q : out STD_LOGIC_VECTOR(N-1 downto 0));

end baud_rate;

architecture Behavioral of baud_rate is
signal r_reg :  unsigned(N-1 downto 0);
signal r_next : unsigned(N-1 downto 0);
begin
process(clk,reset)
begin
    if (reset ='1') then
        r_reg <= (others=>'0');
    elsif(clk'event and clk='1') then 
    r_reg <= r_next;
    end if;
end process;

r_next <= (others =>'0') when r_reg=(M-1) else r_reg+1;
tick <='1' when r_reg=(M-1) else '0';
q <= std_logic_vector(r_reg);


end Behavioral;

我已经测试了所有的 clk 输入并且运行良好,问题似乎出在 r_reg 和 r_next 寄存器上。在 ISim 中,当在 q 上输出其中任何一个时,我得到 UUUUUUUU,因此它们似乎没有产生信号。由此我可以推断出两个 r_reg 和 r_next 寄存器没有被创建或存储值,使用 unsigned 时是否有问题?

为了确保三重确保我什至从使用 VHDL 的 FPGA Prototyping 一书中复制了 mod-m 计数器(这是显示的代码)但是这仍然不起作用并且 q 输出是 UUUUUUUU。

如果有任何更好的方法可以从 nexys2 50mz 时钟创建波特率,也将不胜感激!

干杯

【问题讨论】:

  • 由于您没有向我们展示测试平台,我不得不问:您是否应用了复位信号?当你这样做时,r_reg 发生了什么?另外:这是非常糟糕的VHDL(虽然还不错,但它已经坏了);真的是来自乒乓书吗?
  • 我没有应用任何复位信号,是的,它来自书中,因为我想确保它有效!但我确实尝试在 clk 事件之外使用 r_reg
  • 我没有设置测试台,因为它只是传递一个 clk 信号并读出滴答声和 q (如果你能指出一些更好的代码,我将不胜感激,即使一个新手,我发现这很丑!)
  • 嗯,你有你的答案。 r_reg = "UUUU" 的唯一出路是在 Reset 子句中。我将添加一个更整洁但未经测试的 VHDL 的答案。
  • 非常感谢,我只是在 ISim 上强制重置为“1”,当我输出 r_reg 时,我现在得到 XXXXXXXX,所以我认为它现在归结为 r_next 在我执行 r_reg

标签: vhdl fpga hdl


【解决方案1】:

坦率地说,如果人们期望人们从一本提供此类示例的书中学习 VHDL,我会感到震惊。我知道作者有一本关于 Verilog 的类似书:人们最终会认为 VHDL 只是更冗长的 Verilog 吗?

具体批评(其实7,8是更多的观察):

1) 虚假类型转换。 Q 代表一个无符号数。所以让它不签名!

波特率发生器不是 FPGA 中唯一的东西,因此 Q 不太可能是片外端口。制作顶级片外端口 std_logic_vector 有很好的论据,但即使这样也不是强制性的。但是,如果您的客户的规范或编码风格坚持在端口上进行虚假类型转换;跟着它。

2) DRY 原则:

package CPU_types is
    subtype baud_count is unsigned(7 downto 0);
end CPU_types;

发现维护的简化。
如果您在多个地方使用子类型,请将其放在一个包中;通用代码重用工具。

3) 缩进、格式化。 (我认识到这可能已被编辑器设置弄乱了)。它增加了阅读它的大脑负荷。不过,我在这里所做的并不是 The One Way。

4) 逻辑表达式周围的伪括号。无害,但看起来像 C 程序员的拐杖。

5) 古色古香的 clk'event 风格。明年,rising_edge 函数将成熟到可以饮用(在美国。在英国,它已经在每个星期六晚上都贴满了几年了......)

6) 带有 r_reg 和 r_next 的“双进程”样式。他是否也在 next_state 上编写了带有单独组合过程的状态机?鉴于此,我猜是这样。单进程状态机更容易、更小(编写:它们不会生成更小的硬件)且更安全。

7) 我作弊了,我的tick 比原来晚了一个周期。如果这很关键,请恢复外部“tick”分配。我还让它同步,这将有助于提高性能。有些人更喜欢在 else 子句中使用 tick &lt;= '0';但是我使用的默认赋值是安全的,并且可以防止大型设计中出现很多错误(以及不必要的 else 子句)。

8) Q 的赋值也可以带入过程;如果您将 r_reg 设为流程变量,则必须这样做。还有其他变化和偏好的空间。

    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.NUMERIC_STD.ALL;
    use CPU_types.all;

    entity baud_rate is
        generic (
            M: integer := 163);
        Port (
            clk, reset : in  STD_LOGIC;
            tick : out  STD_LOGIC;
            q    : out baud_count);  
    end baud_rate;

    architecture Behavioral of baud_rate is
        signal r_reg : baud_count;
    begin

    process(clk,reset)
    begin
        if reset ='1' then
            r_reg <= (others=>'0');
        elsif rising_edge(clk) then 
            tick  <= 0;
            r_reg <= r_reg+1;
            if r_reg = M then 
                tick  <= '1';
                r_reg <= (others=>'0');
            end if;
        end if;
    end process;

--    tick <='1' when r_reg = M-1 else '0';
--    or simpler, when r_reg = 0
    q <= r_reg;

    end Behavioral;

【讨论】:

  • 为一个很好的答案干杯,非常感谢!
  • Single process state machines are easier, smaller (to write : they don't generate smaller hardware) - 它们也不会生成更大的硬件 :)
  • @BrianDrummond 考虑到原始代码有多丑,我很可能忽略了一些东西,但 if r_reg = M then 行不应该是 if r_reg = M-1 then 吗?我认为您对其进行编码的方式会导致 r_reg 从 0 计数到 M (含),这将导致您的滴答声比原始周期更远。注意r_reg不是变量,所以赋值r_reg &lt;= r_reg+1;不会影响if语句!
  • @Zennehoy:非常正确!现在,如果 R_Reg 是一个变量而不是一个信号,我的代码就会是正确的! (因为它是在增量之后测试的)。当然,我们不知道 M 的魔法值从何而来。通用的应该是波特率,而 M 应该是一个内部常数,由它和时钟周期计算得出......
  • 嗨,我现在正在测试它,抱歉我下午很忙,但会告诉你进展如何!
猜你喜欢
  • 2019-03-22
  • 2012-10-06
  • 2017-04-02
  • 1970-01-01
  • 1970-01-01
  • 2012-04-19
  • 2021-12-16
  • 2023-03-17
  • 1970-01-01
相关资源
最近更新 更多