UART模块和运算
Posted
技术标签:
【中文标题】UART模块和运算【英文标题】:Uart Module and op 【发布时间】:2018-05-02 19:31:28 【问题描述】:我想使用 Verilog 在 fpga (Nexys 2) 中分别点亮 LED,但我没有在蓝牙 (hc-06) 和 fpga 之间同步。例如:我从手机发送 255 (1111 1111) 并点亮 LED 4。它应该点亮了所有 8 个 LED。
我怀疑问题是我没有正确设置波特率(蓝牙波特率默认为 9600)。
我的 Verilog 代码贴在下面。
波特率部分:
module baud_rate_gen(input wire clk_50m,
output wire rxclk_en,
output wire txclk_en);
parameter RX_ACC_MAX = 50000000 / (9600 * 10);
parameter TX_ACC_MAX = 50000000 / 9600;
parameter RX_ACC_WIDTH = 9;//$clog2(RX_ACC_MAX);
parameter TX_ACC_WIDTH = 8;//$clog2(TX_ACC_MAX);
reg [RX_ACC_WIDTH - 1:0] rx_acc = 0;
reg [TX_ACC_WIDTH - 1:0] tx_acc = 0;
assign rxclk_en = (rx_acc == 5'd0);
assign txclk_en = (tx_acc == 9'd0);
always @(posedge clk_50m) begin
if (rx_acc == RX_ACC_MAX[RX_ACC_WIDTH - 1:0])
rx_acc <= 0;
else
rx_acc <= rx_acc + 5'b1;
end
always @(posedge clk_50m) begin
if (tx_acc == TX_ACC_MAX[TX_ACC_WIDTH - 1:0])
tx_acc <= 0;
else
tx_acc <= tx_acc + 9'b1;
end
endmodule
发射器和接收器部分复制自
https://github.com/jamieiles/uart/blob/master/receiver.v https://github.com/jamieiles/uart/blob/master/transmitter.v
部分ucf文件:
NET "dout<0>" LOC = "J14"; # Bank = 1, Pin name = IO_L14N_1/A3/RHCLK7, Type = RHCLK/DUAL, Sch name = JD10/LD0
NET "dout<1>" LOC = "J15"; # Bank = 1, Pin name = IO_L14P_1/A4/RHCLK6, Type = RHCLK/DUAL, Sch name = JD9/LD1
NET "dout<2>" LOC = "K15"; # Bank = 1, Pin name = IO_L12P_1/A8/RHCLK2, Type = RHCLK/DUAL, Sch name = JD8/LD2
NET "dout<3>" LOC = "K14"; # Bank = 1, Pin name = IO_L12N_1/A7/RHCLK3/TRDY1, Type = RHCLK/DUAL, Sch name = JD7/LD3
NET "dout<4>" LOC = "E17"; # Bank = 1, Pin name = IO, Type = I/O, Sch name = LD4? s3e500 only
NET "dout<5>" LOC = "P15"; # Bank = 1, Pin name = IO, Type = I/O, Sch name = LD5? s3e500 only
NET "dout<6>" LOC = "F4"; # Bank = 3, Pin name = IO, Type = I/O, Sch name = LD6? s3e500 only
NET "dout<7>" LOC = "R4"; # Bank = 3, Pin name = IO/VREF_3, Type = VREF, Sch name = LD7? s3e500 only
引脚连接器部分:
NET "tX" LOC = "L17"; # Bank = 1, Pin name = IO_L10N_1/VREF_1, Type = VREF, Sch name = JA3
NET "rx" LOC = "M15"; # Bank = 1, Pin name = IO_L07P_1, Type = I/O, Sch name = JA4
uart_top 模块:
module uart(input wire [7:0] din,
input wire wr_en,
input wire clk_50m,
output wire tx,
output wire tx_busy,
input wire rx,
output wire rdy,
input wire rdy_clr,
output wire [7:0] dout,
output tX,
input reset);
wire rxclk_en, txclk_en;
baud_rate_gen uart_baud(.clk_50m(clk_50m),
.rxclk_en(rxclk_en),
.txclk_en(txclk_en));
transmitter uart_tx(.din(din),
.wr_en(wr_en),
.clk_50m(clk_50m),
.clken(txclk_en),
.tx(tx),
.tx_busy(tx_busy));
receiver uart_rx(.rx(rx),
.rdy(rdy),
.rdy_clr(rdy_clr),
.clk_50m(clk_50m),
.clken(rxclk_en),
.data(dout));
assign tX = 1;
endmodule
【问题讨论】:
【参考方案1】:首先想到我注意到的是接收器有==15
,这意味着一个16x 过采样时钟。查看 github 评论部分证实了这一点。
您的波特率代码使用50000000 / (9600 * 10);
,这是一个 10 倍波特率时钟,而不是 16。
在您的波特率代码和 git hub UART 代码中,大量使用了初始化变量。在很多情况下这不起作用。正确的方法是使用复位。
我只看了github接收器的代码,但是非常非常草率:
文件顶部没有标题来解释它是什么或做什么。 没有重置 没有同步器。 UART 数据与时钟异步到达,需要同步! rdy 写在两个地方。这里表示一个 rdy_clr 与数据字节同时到达 data 丢失数据字节。 没有溢出检测。 停止状态不检查位高。这使得未连接的线(始终为低)被视为全零的比特流。次要点:组装接收字节是用解复用器完成的。 scratch[bitpos[2:0]]
使用移位寄存器可以做什么的很多慢逻辑。
【讨论】:
以上是关于UART模块和运算的主要内容,如果未能解决你的问题,请参考以下文章