本帖最后由 kangqiao004 于 2020-7-20 17:42 编辑
68013 在传输过程中偶尔会出现不确定bit位数据错误,出错几率比较大,10次会有3/4次出错。
例如:发送1b1a787878780078, FPGA的ila抓到1b1a587978780078
如下代码,fpga_gclk来自68013的IFCLK。代码中“ if(i==3) begin”红色高亮的地方,如果i=1,就不会出错。
如果i=3,就会大概率出错。 i=1 改到i=3,仅仅是为了连续从68013多读取两个16bit数据。
这份代码是参考开发板改的。
还请大神帮忙分析!或者有遇到过类似问题的赐教,感谢!!
//////////////////////////////////////////////////////////////////////////////////
// Module Name: usb_test
// Description: If the FIFO of EP2 is not empty and
// the EP6 is not full, Read the 16bit data from EP2 FIFO
// and send to EP6 FIFO.
//////////////////////////////////////////////////////////////////////////////////
module usb_test(
input fpga_gclk, // FPGA Clock Input 48Mhz
input reset_n, // FPGA Reset input
output reg [1:0] usb_fifoaddr, // CY68013 FIFO Address
(*mark_debug = "true"*) output reg usb_slcs, // CY68013 Chipset select
(*mark_debug = "true"*) output reg usb_sloe, // CY68013 Data output enable
(*mark_debug = "true"*) output reg usb_slrd, // CY68013 READ indication
(*mark_debug = "true"*) output reg usb_slwr, // CY68013 Write indication
(*mark_debug = "true"*) output wire usb_pktend, // package end
inout [15:0] usb_fd, // CY68013 Data
(*mark_debug = "true"*) input usb_flaga, // CY68013 EP2 FIFO empty indication; 1:not empty; 0: empty
(*mark_debug = "true"*) input usb_flagb, // CY68013 EP4 FIFO empty indication; 1:not empty; 0: empty
input usb_flagc, // CY68013 EP6 FIFO full indication; 1:not full; 0: full
(*mark_debug = "true"*) output reg [63:0] user_data,
(*mark_debug = "true"*) output reg user_data_valid,
input data_to_usb_valid,// INA226 read done
input [15:0] data_to_usb, // INA226 data
input pkt_end_flag // pkt_end_flag
);
reg bus_busy; //usb busy
reg rd_ep2_req; //read EP2 request
reg wr_ep6_req; //write EP6 request
reg usb_fd_en; //usb data bus direction control
(*mark_debug = "true"*) reg [4:0] usb_state; //usb FSM state
(*mark_debug = "true"*) reg [4:0] i;
wire [15:0] fifo_dout; //fifo data out
wire full; //fifo full
wire empty; //fifo empty
reg [63:0] fifo_din; //fifo data in
(*mark_debug = "true"*)wire [15:0] i_usb_fd;
(*mark_debug = "true"*)wire [15:0] o_usb_fd;
wire [12:0] rd_data_count; //fifo rd_data_count
wire [63:0] data2fifo2; //data to fifo, buffer for data2fifo1
reg fifo_wr_en; //fifo write enable
//*** modified by KQ ************************
reg k_data_to_usb_valid;
reg k_data_to_usb_valid_r;
reg k_usb_pktend;
wire usb_pktend_r;
//**************wire for audio***************
wire [63:0] data2fifo1;
wire o_ak_bick;
wire transmit_stop;
wire wr_fifo_en;
//*****************************************
parameter IDLE = 5'd0;
parameter EP2_RD_CMD = 5'd1;
parameter EP2_RD_DATA = 5'd2;
parameter EP2_RD_OVER = 5'd3;
parameter EP6_WR_CMD = 5'd4;
parameter EP6_WR_OVER = 5'd5;
assign usb_pktend_r = k_usb_pktend ;
assign usb_pktend = usb_pktend_r;
assign data2fifo2 = {data2fifo1[47:40],data2fifo1[39:32],data2fifo1[63:56],data2fifo1[55:48],data2fifo1[15:8],data2fifo1[7:0],data2fifo1[31:24],data2fifo1[23:16]};
/* Generate USB read/write access request*/
//*** modified by KQ ************************
// use k_data_to_usb_valid posedge to generate wr_ep6_req ,for triggering usb writing state
always @(posedge fpga_gclk)
begin
if(~reset_n)
k_data_to_usb_valid <= 1'b0;
else
k_data_to_usb_valid <= data_to_usb_valid;
end
always @(posedge fpga_gclk)
begin
if(~reset_n)
k_data_to_usb_valid_r <= 1'b0;
else
k_data_to_usb_valid_r <= k_data_to_usb_valid;
end
//*****************************************
//***sync ak5397(ADC) data and fifo_wr_en to o_ak_bick*********
always @(posedge o_ak_bick or negedge reset_n)
begin
if(~reset_n)
begin
fifo_din <= 0;
fifo_wr_en <= 0;
end
else
begin
fifo_din <= data2fifo2;
fifo_wr_en <= ((wr_fifo_en)&&(!full));
end
end
//***collect data from usb_fd for user_data *********
//command from PC
always@(posedge fpga_gclk or negedge reset_n)
begin
if (~reset_n )
begin
user_data <= 64'd0;
end
else
if(usb_slrd==1'b0)
begin
user_data <= {user_data[47:0],i_usb_fd};
end
else
begin
user_data <= user_data;
end
end
//***generate read EP2 request*******************
always @(negedge fpga_gclk or negedge reset_n)
begin
if (~reset_n ) begin
rd_ep2_req <= 1'b0;
end
else begin
if (usb_flaga & (bus_busy==1'b0)) //EP2 is not empty ,and usb state is not busy
rd_ep2_req <= 1'b1; //generate read EP2 request
else
rd_ep2_req <= 1'b0;
end
end
//***generate write EP6 request*******************
always @(negedge fpga_gclk or negedge reset_n)
begin
if (~reset_n ) begin
wr_ep6_req <= 1'b0;
end
else begin
if (usb_flagb & (!empty) & (bus_busy==1'b0) || (k_data_to_usb_valid && (~k_data_to_usb_valid_r))) //EP6 is not full, fifo is not empty and usb state is not busy or other data-to-usb request
wr_ep6_req <= 1'b1; //generate write EP6 request
else
wr_ep6_req <= 1'b0;
end
end
//***usb FSM****************************************
always @(posedge fpga_gclk or negedge reset_n)
begin
if (~reset_n)
begin
usb_fifoaddr <= 2'b00;
usb_slcs <= 1'b0;
usb_sloe <= 1'b1;
usb_slrd <= 1'b1;
usb_slwr <= 1'b1;
usb_fd_en <= 1'b0;
usb_state <= IDLE;
k_usb_pktend <= 1;
end
else begin
case(usb_state)
IDLE:
begin //Idle
k_usb_pktend <= 1;
i<=0;
usb_fd_en <= 1'b0;
if (rd_ep2_req==1'b1) begin
usb_state <= EP2_RD_CMD; //jump to EP2_RD_CMD
bus_busy <= 1'b1; //set bus_busy
usb_fifoaddr <= 2'b00; //select EP2 address
user_data_valid <= 1'b0;
end
else if ((wr_ep6_req==1'b1)) begin
usb_state <= EP6_WR_CMD; //jump to EP6_WR_CMD
bus_busy <= 1'b1; //set bus_busy
usb_fifoaddr <= 2'b10; //select EP6 address
end
else begin
bus_busy <= 1'b0;
usb_state <= IDLE;
usb_fifoaddr <= usb_fifoaddr;//select EP2 address
user_data_valid <= 1'b0;
end
end
EP2_RD_CMD:
begin //EP2 FIFO Read Command
k_usb_pktend <= 1;
if(i==2) begin
usb_slrd <= 1'b1;
usb_sloe <= 1'b0; //set sloe to low
i <= i+1'b1;
end
else if(i==8) begin
usb_slrd <= 1'b0; //set slrd to low
usb_sloe <= 1'b0;
i<=0;
usb_state <= EP2_RD_DATA;
end
else begin
i <= i+1'b1;
end
end
EP2_RD_DATA:
begin //EP2 FIFO Read Data
k_usb_pktend <= 1;
if(i==3) begin
usb_slrd <= 1'b1; //
usb_sloe <= 1'b0;
i <= 0;
usb_state <= EP2_RD_OVER;
end
else begin
usb_slrd <= 1'b0;
usb_sloe <= 1'b0;
i <= i + 1'b1;
end
end
EP2_RD_OVER:
begin //read over
k_usb_pktend <= 1;
if(i==4) begin
usb_slrd <= 1'b1;
usb_sloe <= 1'b1;
i <= 0;
usb_fifoaddr <= 2'b00; //EP6 address
usb_state <= IDLE;
user_data_valid <= 1'b1;
bus_busy <= 1'b0;
end
else begin
usb_slrd <= 1'b1;
usb_sloe <= 1'b0;
i <= i + 1'b1;
end
end
EP6_WR_CMD:
begin //write EP6 FIFO
k_usb_pktend <= 1;
if(i==1) begin
usb_slwr <= 1'b1; //
i <= 0;
usb_state <= EP6_WR_OVER;
end
else begin
usb_slwr <= 1'b0; //slwr = 0 >50ns
usb_fd_en <= 1'b1; //
i <= i + 1'b1;
end
end
EP6_WR_OVER:
begin //EP6 write over
if(i==4)
begin
k_usb_pktend <= 0;
if(empty|(!usb_flagb))
begin
usb_fd_en <= 1'b0;
bus_busy <= 1'b0;
i <= 0;
usb_state <= IDLE;
end
else
begin
usb_fd_en <= 1'b1;
bus_busy <= 1'b1;
i <= 0;
usb_state <= EP6_WR_CMD;
end
end
else
begin
i <= i + 1'b1;
end
end
default: usb_state <= IDLE;
endcase
end
end
//assign o_usb_fd = (pkt_end_flag || user_data[63:48] == 16'haaaa) ? data_to_usb : fifo_dout ; //switch data source
assign o_usb_fd = data_to_usb ;
genvar j;
generate
for(j=0;j<16;j=j+1)
begin :UINT
IOBUF #(
.DRIVE(12), // Specify the output drive strength
.IBUF_LOW_PWR("TRUE"), // Low Power - "TRUE", High Performance = "FALSE"
.IOSTANDARD("DEFAULT"), // Specify the I/O standard
.SLEW("SLOW") // Specify the output slew rate
) IOBUF_inst (
.O(i_usb_fd[j]), // Buffer output
.IO(usb_fd[j]), // Buffer inout port (connect directly to top-level port)
.I(o_usb_fd[j]), // Buffer input
.T(~usb_fd_en) // 3-state enable input, high=input, low=output
);
end
endgenerate
fifo_generator_0 uut (
.wr_clk(~o_ak_bick), // input wire wr_clk
.rd_clk(fpga_gclk), // input wire rd_clk
.din(fifo_din), // input wire [31 : 0] din
.wr_en(fifo_wr_en), // input wire wr_en
.rd_en(~usb_slwr), // input wire rd_en
.dout(fifo_dout), // output wire [15 : 0] dout
.full(full), // output wire full
.empty(empty), // output wire empty
.rd_data_count(rd_data_count) // output wire [9 : 0] rd_data_count
//.rst(rst) // input wire rst
);
endmodule
|
|