起因:
使用之前测试没问题的xpm_fifo_async时出了问题。用xpm_fifo_async取代fifo ip,做并转串功能,输入8bit,输出1bit。
输出的bit不对。不知道原因。
发展:
上网搜索,得一篇文章:
关于FIFO Generator IP和XPM_FIFO在涉及位宽转换上的区别
根据上文,xpm_fifo_async输出的数据是小端的。但是我平时在fpga里处理数据都是按照大端模式处理。
我测试了写位宽8,读位宽1。xpm_fifo_async输出顺序为bit0,bit1,…,bit7。这相当于把一个字节的高低位翻过来了。想看文档里对此是否有说明,遂使用DocNav搜索UG953,发现无法打开xilinx的网页,折腾许久。重新安装DocNav,终于看到了UG953。但是没有找到相关说明。
结局:
我在8位数据进入xpm_fifo_async之前,先把bit0到bit7的数据对调(SW_ENDIAN模块),输出来的数据就变成大端了。
`timescale 1ns / 1ps
/*
switch big endian to little endian;
switch little endian to big endian;
*/
module SW_ENDIAN#(
parameter WIDTH = 8)(
input CLK,
input ND,
input [WIDTH-1:0] DIN,
output DV,
output [WIDTH-1:0] DOUT
);
//
localparam width_split = (WIDTH<=8)?1:8;
reg [WIDTH-1:0]do_temp = 0;
genvar i;
generate
for(i=0;i<WIDTH;i=i+1) begin: SW
always @(posedge CLK)
do_temp[i +: width_split] <= DIN[(WIDTH-1-i) -: width_split];
end
endgenerate
reg dv = 0;
always @(posedge CLK) begin
dv <= ND;
end
assign DV = dv;
assign DOUT = do_temp;
endmodule
其他
使用xpm_fifo_async和xpm_fifo_sync还得注意:
- rst是写时钟域的,“Must be synchronous to wr_clk”.
- 复位后,rd_rst_busy和wr_rst_busy会拉高,他们拉高时,不能读写。
- Write and read width aspect ratio must be 1:1,1:2, 1:4, 1:8, 8:1, 4:1 and 2:1 . For example, if WRITE_DATA_WIDTH is 32, then the READ_DATA_WIDTH must be 32, 64,128,256, 16, 8, 4.
- WRITE_DATA_WIDTH should be equal to READ_DATA_WIDTH if FIFO_MEMORY_TYPE is set to “auto”. Violating this may result incorrect behavior.
- The maximum FIFO size (width x depth) is limited to 150-Megabits.
- 根据上文结论,当数据位宽超过一个字节时,例如写位宽16位,读位宽8位,会先输出低字节,再输出高字节。字节中的bit位置不会变。
- 参考《UG953 (v2022.2) 7 Series FPGA and Zynq-7000 SoC Libraries Guide》