AXI_DATAMOVER的控制接口



`timescale 1ns/1ns




module test_dm ;

reg  clk=0,rst =0,bus_wr=0 ;
reg [1:0] bus_addr =0;
reg [31:0]  bus_din=0;
 
wire [31:0] bus_dout ;

wire [71:0] m_cmd;
wire m_valid;
reg m_ready=0 ;

reg [7:0]s_sts ;
reg s_valid=0;
wire  s_ready;
reg error=0;
wire rstn ;
 
 
task wr_reg ;
input [1:0]addr;
input [31:0] value;
begin
bus_din = value ;
bus_addr = addr ;
@(posedge clk);bus_wr = 0;
@(posedge clk);bus_wr = 1;
@(posedge clk);bus_wr = 0;
end
endtask


always #5 clk = ~clk ;

initial begin

rst =1;

#20 ; rst =0;

#20;

wr_reg( 0 ,0  );
wr_reg (1, 250);
wr_reg (2, 7);

end


dm_ctlr #(16) DM_CNTLR(

  .clk( clk ),
  .rst( rst ),
  .bus_wr( bus_wr ),
  .bus_addr(bus_addr  ),
  .bus_din(bus_din  ),
  .bus_dout(bus_dout  ) ,

   .m_cmd( m_cmd ),
   .m_valid(m_valid  ) ,
      .m_ready(1 ) ,

       //  .m_ready( m_ready ) ,

   .s_sts( s_sts ),
   .s_valid( s_valid ),
   .s_ready(s_ready  ),

   .error(error  ) ,
   .rstn(rstn  )

);
 
 endmodule
 
 
 /*
 
 
 datamover_ctlr #(16) DM_CNTLR(
   .clk( clk ),
   .rst( rst ),
   .bus_wr( bus_wr ),
   .bus_addr(bus_addr  ),
   .bus_din(bus_din  ),
   .bus_dout(bus_dout  ) ,
 
    .m_cmd( m_cmd ),
    .m_valid(m_valid  ) ,
    .m_ready( m_ready ) ,
 
    .s_sts( s_sts ),
    .s_valid( s_valid ),
    .s_ready(s_ready  ),
 
    .error(error  ) ,
    .rstn(rstn  )
 
 );
 
 */

module  dm_ctlr #(
parameter MAX_BYTES_IN_CMD = 4096
)(

input clk,
input rst,
input bus_wr,
input [1:0] bus_addr,
input [31:0] bus_din,
output reg [31:0]bus_dout ,

output reg [71:0] m_cmd=0 ,
output reg m_valid ,
input m_ready ,

input [7:0]s_sts,
input s_valid,
output reg  s_ready,

input error ,
output reg  rstn

);

reg local_rst ;
always @ (posedge clk)
local_rst <= ( rst == 1) ||(rstn == 0 );


reg [31:0] addr ,len ;
reg need_eof,incr,en ;
reg  [7:0] st ;

reg [31:0] cur_addr , remain_len ;

always@(posedge clk)
if (bus_wr)
case (bus_addr)
0: addr <= bus_din ;
1: len <= bus_din ;
2: begin  en <= bus_din[0]; incr<=bus_din[1]; need_eof<=bus_din[2];  end
endcase

always@(posedge clk)
rstn <= ~( (bus_wr==1 ) && (bus_addr[1:0]==3) && (bus_din[0]==1)) ;

always@(posedge clk ) s_ready<= 1;//s_valid ;

reg [8:0 ] last_sts ;
always@(posedge clk )
if (s_ready&s_valid)
last_sts <= {error,s_sts[7:0]} ;

reg [31:0]  cntr ;

always@*
case (bus_addr)
0 : bus_dout <= last_sts ;
1 : bus_dout <= cntr ;
default  bus_dout<='hx ;
endcase

always @ (posedge clk )
if ((en==0)||(local_rst==1)) cntr <=0;else
if (st==11) cntr<=1+cntr ;



always @ (posedge clk) m_cmd[23]<= incr;
always @ (posedge clk)
case (st)
10,11 :m_cmd[31]<=(1==need_eof) ;
 default m_cmd[31]<=0;  
endcase

always @* m_cmd[71:64] <=0 ;
always @* m_cmd[31:24] <=0 ;

always @ (posedge clk)
case (st)
3,10: m_cmd[63:32] = cur_addr ;
endcase

always @ (posedge clk)
case (st)
3:m_cmd[22:0] = MAX_BYTES_IN_CMD ;
10:m_cmd[22:0] = remain_len ;
endcase

always @ (posedge clk)
case (st)
3,10 : m_valid<=1;
4,11 : if (m_ready) m_valid <=0;
default m_valid<=0;
endcase

always @ (posedge clk)
case (st)
3:begin cur_addr<=cur_addr+MAX_BYTES_IN_CMD; remain_len<=remain_len-MAX_BYTES_IN_CMD;end  
1:begin cur_addr <= addr; remain_len<=len ;end
endcase
 
always  @ (posedge clk)
if (local_rst) st<=0;else
case ( st )
0 : if ( en ) st<=1;
1 :  st<=2; //保存寄存器
2 : if (remain_len > MAX_BYTES_IN_CMD )  st<=3 ;	else st<=10;// 分支检测是否是最后一个命令
3 :  st<=4; // 设置valid  // 更新计数器
4 : if (m_ready) st<=2; // 检查ready
//处理最后一个命令
10: st<=11;//设置valid
11:  st<=11; //if (m_ready) st<=0; //检查ready
default st<=0;
endcase

endmodule









你可能感兴趣的:(ZYNQ7,OV7670,FPGA,VERILOG)