上一篇教程介绍了NEXYS4 开发板中DDR2的使用方式,这一篇介绍不可或缺的网络接口RJ45在FPGA开发板中的使用
NEXYS 4开发板自带一根USB mini-B线,在板子上的接口上写着PROG_UART,就是程序烧写和UART串口通信通用接口复用的。
用来实现串口通信的芯片名称是FTDI(Future Technology Devices International) FT2232HQ,它的文档链接在此:datasheet
NEXYS 4文档中写着,为了实现和FPGA的串口通信,还需要下载一个VCP(Virtual Com Port)驱动。各种不同的平台需要的软件可以从这个网站找到,我下载的是Windows x64:www.ftdichip.com。记得要点击右边的setup executable来下载安装,而不是点击版本号(为什么一定要做这么麻烦):懒人链接
但是我用Putty可以直接收发数据,并没有多大问题,可以跳过VCP驱动这一步直接开始
在开发板中FTDI和FPGA的连接如下:
TXD和RXD分别是串行收发信号,RTS是Require ToSend,CTS是Clear ToSend,作为连接时候的握手信号。从这里发现,这个接口没用提供任何控制配置接口,只有数据接口。它意味着初始配置由其他结构控制,我们只能使用它。因此这次我们不具体研究FTDI芯片的细节。
串口的时序如下
图中用的波特率是9600,但我们用的是115200bps。发送以10位为一个单位,第一位拉低表示开始,接着八位从数据的低位开始直到最高位,最后把电平拉高表示结束。至于CTS和RTS,它们是低电平有效,平时是高电平,在有数据从PC发给FPGA时,就会把RTS拉低,这时需要把CTS拉低做回应。
这篇教程的计划是,看到RTS拉低,就相应的把CTS拉低做回应,然后循环传回提前指定好的数据。
module uart(
input clk,
input rst,
output reg led,
// UART port
input RXD,
output reg TXD,
output reg CTS,
input RTS
);
接口定义,LED接在RTS上,看是否有信号从PC传来
(* dont_touch = "true" *)reg RXD_d;
(* dont_touch = "true" *)reg RTS_d;
reg [15:0] tx_count;
reg [39:0] tx_shift;
always @(posedge clk or posedge rst) begin
if(rst) begin
RXD_d <= 1'b0;
RTS_d <= 1'b0;
end
else begin
RXD_d <= RXD;
RTS_d <= RTS;
end
end
把RXD和RTS接到的数据保存下来,到chipscope中观察
always @(posedge clk or posedge rst) begin
if(rst) begin
TXD <= 1'b1;
tx_shift <= {10'b0011000101, 10'b0101010101, 10'b0110000101, 10'b0110100101};
end
else begin
if(tx_count < 16'd867) begin
tx_count <= tx_count + 16'd1;
end
else begin
tx_count <= 16'd0;
end
if(tx_count == 16'd0) begin
TXD <= tx_shift[39];
tx_shift <= {tx_shift[38:0], tx_shift[39]};
end
end
if(rst) begin
CTS <= 1'b1;
end
else begin
CTS <= 1'b0;
end
end
保持CTS低电位,持续循环输出提前设置好的数据。具体数据内容可以参考UTF-8表格,注意把码反过来。比如说字母F的UTF-8码是0x46=8’b01000110,那么反过来再加上头尾就变成了10’b0011000101
always @(posedge clk or posedge rst) begin
if(rst) begin
led <= 1'b0;
end
else begin
led <= RTS;
end
end
endmodule
Testbench如下:
`timescale 1ns/1ns
module tb_uart;
reg clock;
reg reset;
wire led;
reg RXD;
wire TXD;
wire CTS;
reg RTS;
定义资源
initial begin
clock = 1'b0;
reset = 1'b0;
RXD = 1'b1;
RTS = 1'b1;
// Reset for 1us
#100
reset = 1'b1;
#1000
reset = 1'b0;
#10000
RTS = 1'b0;
repeat(10) begin
#867;
RXD = ~RXD;
end
end
// Generate 100MHz clock signal
always #5 clock <= ~clock;
初始化信号,生成时钟,并且在最开始给予一个字符
uart uart(
.clk (clock),
.rst (reset),
.led (led),
// UART port
.RXD (RXD),
.TXD (TXD),
.CTS (CTS),
.RTS (RTS)
);
endmodule
再写一个仿真脚本sim.do:
vlib work
vlog ../src/uart.v ./tb_uart.v
vsim work.tb_uart -voptargs=+acc +notimingchecks
log -depth 7 /tb_uart/*
#do wave.do
run 1ms
打开ModelSim,将路径切换到仿真文件夹后,调用脚本do sim.do,加入相应信号,结果如下:
可以看出TXD和CTS在输出期望中的信号
新建一个叫uart的project,初始配置可以参考之前的教程。添加代码文件uart.v
下一步加入约束constraint文件uart.xdc,同样这是用标准模板取自己需要部分修改出来的(NEXYS 4 DDR Master XDC):
## This file is a general .xdc for the Nexys4 DDR Rev. C
## To use it in a project:
## - uncomment the lines corresponding to used pins
## - rename the used ports (in each line, after get_ports) according to the top level signal names in the project
## Clock signal
set_property -dict {PACKAGE_PIN E3 IOSTANDARD LVCMOS33} [get_ports clk]
create_clock -period 10.000 -name sys_clk_pin -waveform {0.000 5.000} -add [get_ports clk]
##Switches
set_property -dict {PACKAGE_PIN J15 IOSTANDARD LVCMOS33} [get_ports rst]
## LEDs
set_property -dict {PACKAGE_PIN H17 IOSTANDARD LVCMOS33} [get_ports led]
##USB-RS232 Interface
set_property -dict {PACKAGE_PIN C4 IOSTANDARD LVCMOS33} [get_ports RXD]
set_property -dict {PACKAGE_PIN D4 IOSTANDARD LVCMOS33} [get_ports TXD]
set_property -dict {PACKAGE_PIN D3 IOSTANDARD LVCMOS33} [get_ports CTS]
set_property -dict {PACKAGE_PIN E5 IOSTANDARD LVCMOS33} [get_ports RTS]
到这里可以点击 Run Synthesis做综合,几秒钟完成后用Set Up Debug配置ChipScope:
设置观察长度为8192,因为串口的频率是115200Hz,和时钟频率比起来很低,需要多观察一段时间。下面就可以Run Implementation和Generate Bitstream生成配置文件了。
和前面的教程一样,USB线连接NEXYS4板子,开启Hardware Manager,然后auto连接上板子,Program Device烧写进程序,注意Debug probes file有对应的ltx文件。
现在我们要配置PC端的串口通信软件,就像前面说的,我推荐使用Putty,简单好用,其他很多地方可以用,下载链接就不附了,可以自己找。配置如下:
这里具体用哪个串口COM是可以在设备管理器device manager里看到的,如果找不到,你可以拔一下开发板的USB,看一下哪个消失了,我这里是COM4。
还有一个需要配置的要到左侧Connection -> Serial里,按照图中来配置。到这里就可以开启了。emmmmmmm:
再来配置ChipScope的配置,trigger配置成RTS,这个信号平时是高电平,拉低代表着收到有效信号。开启捕捉后,可以重开一次putty,因为刚刚连接的时候会给一个有效信号,在ChipScope中看到的信号是这样的:
这一篇教程相对短一些,因为串口是作为低速低复杂度的点对点传输,主要存在的意义就是方便传输低速信号,将来做一些需要传回复杂字符数据的时候就可以调用相应代码。
下一篇介绍如何使用开发板上的USB接口,接收键盘和鼠标的信号