about read32 operation

Questions and discussions about the Xillybus IP core and drivers

about read32 operation

Postby phdwong » Mon Nov 18, 2019 2:36 am

Hi
I have some question about DMA ,read32 operation




Code: Select all
module frame_wifi_itfc(
                  bus_clk             ,
                  quiesce             ,
                 
                  user_r_read_32_rden ,
                  user_r_read_32_empty,
                  user_r_read_32_data ,
                  user_r_read_32_eof  ,
                  user_r_read_32_open ,

                  clk25               ,
                  rst                 ,
                  line_start          ,
                  scanlinenum         ,
                  coef_en,
                  line_comb_addr      ,
                                   
                  frame_freq          ,
                  frame_cnt           ,
                  package_num         ,
                                     
                  dot                 ,
                  dot_en              ,
                  store_enable        ,
                                   
                  image_din         
              );
//------------------------------------------------------------------------------
//DMA port
//------------------------------------------------------------------------------
input         bus_clk             ;
input         quiesce             ;
input         user_r_read_32_rden ;
output        user_r_read_32_empty;
output [31:0] user_r_read_32_data ;
output        user_r_read_32_eof  ;
input         user_r_read_32_open ;
// User Logic
input         clk25         ;
input         rst           ;
input         line_start    ;
input         coef_en       ;
input [7:0]   scanlinenum   ;
input [7:0]   line_comb_addr;

input         frame_freq    ;
input [15:0]  frame_cnt     ;
input [5:0]   package_num   ;

input [8:0]   dot           ;
input         dot_en        ;
input         store_enable  ;

input [15:0]  image_din     ;

 
reg [10:0] frame_wr_addr;initial frame_wr_addr='d0;
reg [15:0] frame_wr_data;initial frame_wr_data='d0;
always @(posedge clk25)
begin
  if(store_enable & dot_en)
  begin
    if(dot == 9'd0)
      frame_wr_data <= frame_cnt          ;  //dot=0, frame number
    else if(dot == 9'd1)
      frame_wr_data <= {8'd0,line_comb_addr};//scanlinenum} ;  //dot=1, scan_number
    else if(dot == 9'd2)
      frame_wr_data <= {10'd0,package_num} ;  //dot=2, pakage_num
    else
      frame_wr_data <=image_din;// frame_num + scan_number + dot ;
  end
  else
    frame_wr_data <= 16'd0 ;
end
reg [1:0]    line_comb_addr_tmp;
always @(posedge clk25)
begin
   if(rst)
      line_comb_addr_tmp <= 2'd0;
   else
      line_comb_addr_tmp <=line_comb_addr[1:0];
end

always @(posedge clk25)
begin
  //if(store_enable & dot_en)
    frame_wr_addr <= {line_comb_addr_tmp[1:0],dot[8:0]};
  //else ;
end

(*mark_debug = "true"*)reg        wren_a       ;
(*mark_debug = "true"*)reg        wren_b       ;
(*mark_debug = "true"*)reg        ping_pong_flg;
always @(posedge clk25)
if(rst)
begin
   wren_a        <= 1'b0;
   wren_a        <= 1'b0;
   ping_pong_flg <= 1'b0;
end
else
begin
  ping_pong_flg <= package_num[0] ;
  //if ping_pong_flg == 1'b1 write A package, read B package
  //if ping_pong_flg == 1'b0 write B package, read A package
  wren_a <= ping_pong_flg ? 1'b1 &coef_en &store_enable &dot_en : 1'b0;
  wren_b <= ping_pong_flg ? 1'b0 : 1'b1 & coef_en &store_enable &dot_en;     
end


// Clock crossing logic: fpga_clk -> bus_clk
(*mark_debug = "true"*)reg [2:0] wren_a_cross;
(*mark_debug = "true"*)reg [2:0] wren_b_cross;
(*mark_debug = "true"*)reg       rden_a;
(*mark_debug = "true"*)reg       rden_b;
always @(posedge bus_clk)
begin
  wren_a_cross <= {wren_a_cross[1:0],ping_pong_flg};//wren_a & ping_pong_flg};
  wren_b_cross <= {wren_b_cross[1:0],~ping_pong_flg};//wren_b & (~ping_pong_flg)};
  rden_a       <= ~wren_a_cross[2]          ;
  rden_b       <= ~wren_b_cross[2]          ;
end

(*mark_debug = "true"*)reg [2:0] ping_pong_flg_cross;
(*mark_debug = "true"*)reg       clear_empty        ;
always @(posedge bus_clk)
begin
  ping_pong_flg_cross <= {ping_pong_flg_cross[1:0],ping_pong_flg};
  clear_empty         <= (ping_pong_flg_cross[2] & ~(ping_pong_flg_cross[1])) | (ping_pong_flg_cross[1] & ~(ping_pong_flg_cross[2]));
end
     
//////////////////////////////////////////////////
(*mark_debug = "true"*)reg  [9:0]  pkg_rd_addr ;
(*mark_debug = "true"*)wire [31:0] pkg_rd_douta;
(*mark_debug = "true"*)wire [31:0] pkg_rd_doutb;
pkg_frame_buffer ua_pkg_frame_buffer (
                                      .clka  (clk25         ),    // input wire clka
                                      .ena   (wren_a        ),    // input wire ena
                                      .wea   (wren_a        ),    // input wire [0 : 0] wea
                                      .addra (frame_wr_addr ),    // input wire [10 : 0] addra
                                      .dina  (frame_wr_data ),    // input wire [15 : 0] dina
                                      .douta (              ),    // output wire [15 : 0] douta
                                     
                                      .clkb  (bus_clk       ),    // input wire clkb
                                      .enb   (rden_a        ),    // input wire enb
                                      .web   (1'b0          ),    // input wire [0 : 0] web
                                      .addrb (pkg_rd_addr   ),    // input wire [9 : 0] addrb
                                      .dinb  (32'd0         ),    // input wire [31 : 0] dinb
                                      .doutb (pkg_rd_douta  )     // output wire [31 : 0] doutb
                                      );
 
pkg_frame_buffer ub_pkg_frame_buffer (
                                      .clka  (clk25         ),    // input wire clka
                                      .ena   (wren_b        ),    // input wire ena
                                      .wea   (wren_b        ),    // input wire [0 : 0] wea
                                      .addra (frame_wr_addr ),    // input wire [10 : 0] addra
                                      .dina  (frame_wr_data ),    // input wire [15 : 0] dina
                                      .douta (              ),    // output wire [15 : 0] douta
                                     
                                      .clkb  (bus_clk       ),    // input wire clkb
                                      .enb   (rden_b        ),    // input wire enb
                                      .web   (1'b0          ),    // input wire [0 : 0] web
                                      .addrb (pkg_rd_addr   ),    // input wire [9 : 0] addrb
                                      .dinb  (32'd0         ),    // input wire [31 : 0] dinb
                                      .doutb (pkg_rd_doutb  )     // output wire [31 : 0] doutb
                                      );

always @(posedge bus_clk)
begin
  if(~user_r_read_32_open || clear_empty) //| ~user_r_read_32_empty)
    pkg_rd_addr <= 10'd0;
  else if(user_r_read_32_rden)
  begin
    if(pkg_rd_addr == 10'd1023)
      pkg_rd_addr <= pkg_rd_addr;
    else
      pkg_rd_addr <= pkg_rd_addr + 1'b1;
  end
//  else
//    pkg_rd_addr <= 10'd0;
end
 
(*mark_debug = "true"*)reg user_r_read_32_empty;
always @(posedge bus_clk)
begin
  if(clear_empty)
    user_r_read_32_empty <= 1'b0;
  else if(pkg_rd_addr == 10'd1023)
    user_r_read_32_empty <= 1'b1;
  else ;
end

assign user_r_read_32_eof = 1'b0;

(*mark_debug = "true"*)assign user_r_read_32_data = rden_a ? pkg_rd_douta : pkg_rd_doutb;
endmodule
phdwong
 
Posts: 2
Joined: Mon Nov 12, 2018 2:48 am

Re: about read32 operation

Postby support » Mon Nov 18, 2019 8:09 am

Hello,

It's not clear what the question is, but reading the code you submitted, it's apparent that you've implemented your own mechanism for crossing clock domains, by virtue of a dual buffer. This technique is quite common, however it's unnecessarily complicated when Xillybus IP core already has taken care of the data flow complexity.

I suggest following the suggested guideline: Interfacing with Xillybus' IP core through FIFOs. For crossing the clock domain, use dual-clock FIFOs.

Regards,
Eli
support
 
Posts: 733
Joined: Tue Apr 24, 2012 3:46 pm


Return to Xillybus

cron