我正在为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时钟创建波特率,那也是值得赞赏的!
干杯
答案 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;