在市面上能见到的zynq教程中,看的到的uart实验,都是使用的MIO,这是最简单的,但是有一个问题,那就是MIO是只连接到PS的,对PL端口是透明的,这就产生了一个问题:当我想使用任意分配在引脚的UART时该怎么办?换句话说,我有一个需求,要把串口的tx和rx分配在指定的EMIO上。
1. 其实是很简单的,首先双击ZYNQ配置芯片。这是使用MIO的配置,我们点击UART的IO口,选择EMIO,注意UART1下的Modem signals一般不需勾选。
然后我们可以看到UART1被自动引了出来,如下图。
2. 然后Generate Output Products -> Create HDL Wrapper,看到的底层模块是这样的
`timescale 1 ps / 1 ps
module design_1_wrapper
(DDR_addr,
DDR_ba,
DDR_cas_n,
DDR_ck_n,
DDR_ck_p,
DDR_cke,
DDR_cs_n,
DDR_dm,
DDR_dq,
DDR_dqs_n,
DDR_dqs_p,
DDR_odt,
DDR_ras_n,
DDR_reset_n,
DDR_we_n,
FIXED_IO_ddr_vrn,
FIXED_IO_ddr_vrp,
FIXED_IO_mio,
FIXED_IO_ps_clk,
FIXED_IO_ps_porb,
FIXED_IO_ps_srstb,
UART_1_rxd,
UART_1_txd);
inout [14:0]DDR_addr;
inout [2:0]DDR_ba;
inout DDR_cas_n;
inout DDR_ck_n;
inout DDR_ck_p;
inout DDR_cke;
inout DDR_cs_n;
inout [3:0]DDR_dm;
inout [31:0]DDR_dq;
inout [3:0]DDR_dqs_n;
inout [3:0]DDR_dqs_p;
inout DDR_odt;
inout DDR_ras_n;
inout DDR_reset_n;
inout DDR_we_n;
inout FIXED_IO_ddr_vrn;
inout FIXED_IO_ddr_vrp;
inout [53:0]FIXED_IO_mio;
inout FIXED_IO_ps_clk;
inout FIXED_IO_ps_porb;
inout FIXED_IO_ps_srstb;
input UART_1_rxd;
output UART_1_txd;
wire [14:0]DDR_addr;
wire [2:0]DDR_ba;
wire DDR_cas_n;
wire DDR_ck_n;
wire DDR_ck_p;
wire DDR_cke;
wire DDR_cs_n;
wire [3:0]DDR_dm;
wire [31:0]DDR_dq;
wire [3:0]DDR_dqs_n;
wire [3:0]DDR_dqs_p;
wire DDR_odt;
wire DDR_ras_n;
wire DDR_reset_n;
wire DDR_we_n;
wire FIXED_IO_ddr_vrn;
wire FIXED_IO_ddr_vrp;
wire [53:0]FIXED_IO_mio;
wire FIXED_IO_ps_clk;
wire FIXED_IO_ps_porb;
wire FIXED_IO_ps_srstb;
wire UART_1_rxd;
wire UART_1_txd;
design_1 design_1_i
(.DDR_addr(DDR_addr),
.DDR_ba(DDR_ba),
.DDR_cas_n(DDR_cas_n),
.DDR_ck_n(DDR_ck_n),
.DDR_ck_p(DDR_ck_p),
.DDR_cke(DDR_cke),
.DDR_cs_n(DDR_cs_n),
.DDR_dm(DDR_dm),
.DDR_dq(DDR_dq),
.DDR_dqs_n(DDR_dqs_n),
.DDR_dqs_p(DDR_dqs_p),
.DDR_odt(DDR_odt),
.DDR_ras_n(DDR_ras_n),
.DDR_reset_n(DDR_reset_n),
.DDR_we_n(DDR_we_n),
.FIXED_IO_ddr_vrn(FIXED_IO_ddr_vrn),
.FIXED_IO_ddr_vrp(FIXED_IO_ddr_vrp),
.FIXED_IO_mio(FIXED_IO_mio),
.FIXED_IO_ps_clk(FIXED_IO_ps_clk),
.FIXED_IO_ps_porb(FIXED_IO_ps_porb),
.FIXED_IO_ps_srstb(FIXED_IO_ps_srstb),
.UART_1_rxd(UART_1_rxd),
.UART_1_txd(UART_1_txd));
endmodule
在verilog代码中,UART_1_rxd和UART_1_tx也已经能够看到且引在了顶层模块的端口,剩下的就是为其分配引脚。
2. 然后添加约束文件,这里我命名为pins.xdc
set_property SEVERITY {Warning} [get_drc_checks NSTD-1]
set_property SEVERITY {Warning} [get_drc_checks RTSTAT-1]
set_property SEVERITY {Warning} [get_drc_checks UCIO-1]
set_property IOSTANDARD LVCMOS33 [get_ports UART_1_tx]
set_property IOSTANDARD LVCMOS25 [get_ports UART_1_rxd]
set_property PACKAGE_PIN P22 [get_ports UART_1_tx]
set_property PACKAGE_PIN M22 [get_ports UART_1_rxd]
其中T22和F22是底板上两个EMIO引脚。
3. 编译,生成bit文件,把P22和M22这两个引脚接线到你的CH340或者CP2012这种串口头上去,sdk中使用hello_world例程即可跑通。