Mod-M计数器无符号值没有信号

时间:2013-01-11 10:21:41

标签: vhdl fpga hdl

我正在为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中输出这些中的任何一个时,我得到了UUUUUUUU,所以它们似乎没有产生信号。从这里我可以推断出两个r_reg和r_next寄存器没有被创建或存储值,使用unsigned时是否存在问题?

为了确保三重,我甚至从VHDL的FPGA原型开发中复制了mod-m计数器(这是显示的代码)但仍然不起作用,q输出是UUUUUUUU。

如果有更好的方法可以从nexys2 50mz时钟创建波特率,那也是值得赞赏的!

干杯

1 个答案:

答案 0 :(得分:3)

坦率地说,如果人们期望从一本书中学习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)我作弊,我的嘀嗒比原来要晚一个周期。如果这很重要,请恢复外部“勾号”分配。我也使它同步vhich将有助于性能。有些人宁愿在else子句中使用tick <= '0';但是我使用的默认赋值是安全的,可以防止大型设计中出现很多错误(以及不必要的其他条款)。

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;