본문 바로가기

Logic Design

AXI4 Bus Interface

bus_slv.v  // shift + scroll

 

module bus_slv (

   input wire              clk_axi_slv             ,
   input wire              rstb_slv                ,

   input wire  [   1:0]    i_axi4_slv_awid___      ,
   input wire  [  31:0]    i_axi4_slv_awaddr_      ,
   input wire  [   7:0]    i_axi4_slv_awlen__      ,
   input wire  [   2:0]    i_axi4_slv_awsize_      ,
   input wire              i_axi4_slv_awvalid      ,
   output reg              o_axi4_slv_awready      ,

   input wire  [   1:0]    i_axi4_slv_wid____      ,
   input wire  [  31:0]    i_axi4_slv_wdata__      ,
   input wire              i_axi4_slv_wlast__      ,
   input wire              i_axi4_slv_wvalid_      ,
   output reg              o_axi4_slv_wready_      ,

   output reg  [   1:0]    o_axi4_slv_bid____      ,
   output reg  [   1:0]    o_axi4_slv_bresp__      ,
   output reg              o_axi4_slv_bvalid_      ,
   input wire              i_axi4_slv_bready_      ,

   input wire  [   1:0]    i_axi4_slv_arid___      ,
   input wire  [  31:0]    i_axi4_slv_araddr_      ,
   input wire  [   7:0]    i_axi4_slv_arlen__      ,
   input wire  [   2:0]    i_axi4_slv_arsize_      ,
   input wire              i_axi4_slv_arvalid      ,
   output reg              o_axi4_slv_arready      ,

   output reg  [   1:0]    o_axi4_slv_rid____      ,
   output reg  [  31:0]    o_axi4_slv_rdata__      ,
   output reg  [   1:0]    o_axi4_slv_rresp__      ,
   output reg              o_axi4_slv_rlast__      ,
   output reg              o_axi4_slv_rvalid_      ,
   input wire              i_axi4_slv_rready_      );

`include "./bus_slv_para.sv"

///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Address Decode
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
wire  w_axi4_wr__mem_slv   =  (i_axi4_slv_awvalid && (i_axi4_slv_awaddr_[31:24] == AXI4_SLV____SRAM) && (i_axi4_slv_awaddr_[23:0]<=24'h1FF));
wire  w_axi4_rd__mem_slv   =  (i_axi4_slv_arvalid && (i_axi4_slv_araddr_[31:24] == AXI4_SLV____SRAM) && (i_axi4_slv_araddr_[23:0]<=24'h1FF));
wire  w_axi4_wr__reg_slv   =  (i_axi4_slv_awvalid && (i_axi4_slv_awaddr_[31:24] == AXI4_SLV_____REG) && (i_axi4_slv_awaddr_[23:0]<=24'h3FF));
wire  w_axi4_rd__reg_slv   =  (i_axi4_slv_arvalid && (i_axi4_slv_araddr_[31:24] == AXI4_SLV_____REG) && (i_axi4_slv_araddr_[23:0]<=24'h3FF));
wire  w_axi4_wr__rsv_slv   =  (i_axi4_slv_awvalid && (~w_axi4_wr__mem_slv && ~w_axi4_wr__reg_slv));
wire  w_axi4_rd__rsv_slv   =  (i_axi4_slv_arvalid && (~w_axi4_rd__mem_slv && ~w_axi4_rd__reg_slv));

wire  w_axi4_wr__bus_slv   =  (w_axi4_wr__mem_slv || w_axi4_wr__reg_slv);
wire  w_axi4_rd__bus_slv   =  (w_axi4_rd__mem_slv || w_axi4_rd__reg_slv);

///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// module internal register
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
reg   [   7:0]    register[0:1023];
reg   [   7:0]    sram_wr_buff[0:7];
reg   [   7:0]    sram_rd_buff[0:7];
reg               r_slv_sel;

reg   [  23:0]    r_axi4_slv_awaddr_ ;
reg   [   1:0]    r_axi4_slv_awid___ ;
reg   [   7:0]    r_axi4_slv_awlen__ ;
reg   [   2:0]    r_axi4_slv_awsize_ ;
reg   [  23:0]    r_axi4_slv_araddr_ ;
reg   [   1:0]    r_axi4_slv_arid___ ;
reg   [   7:0]    r_axi4_slv_arlen__ ;
reg   [   2:0]    r_axi4_slv_arsize_ ;

reg   [   2:0]    r_wr_fsm;
reg   [   2:0]    w_wr_nxt;
reg   [   2:0]    r_rd_fsm;
reg   [   2:0]    w_rd_nxt;

reg   [   9:0]    r_wr_adr_cnt;
reg               r_wr_adr_end;
reg   [   8:0]    r_wr_len_cnt;
reg   [  10:0]    r_rd_adr_cnt;
reg   [   8:0]    r_rd_len_cnt;  

reg   [   3:0]    r_wr_lp, r_rd_lp;
reg   [   2:0]    r_wr_wp, r_rd_wp;
reg   [   2:0]    r_wr_rp, r_rd_rp;

reg   [   1:0]    r_wr_buf_cnt;


///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// module internal wire
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
wire  [   7:0]    w_wdata0 = i_axi4_slv_wdata__[ 7: 0];
wire  [   7:0]    w_wdata1 = i_axi4_slv_wdata__[15: 8];
wire  [   7:0]    w_wdata2 = i_axi4_slv_wdata__[23:16];
wire  [   7:0]    w_wdata3 = i_axi4_slv_wdata__[31:24];

wire  [   9:0]    w_waddr0 = r_wr_adr_cnt;
wire  [   9:0]    w_waddr1 = r_wr_adr_cnt + 1;
wire  [   9:0]    w_waddr2 = r_wr_adr_cnt + 2;
wire  [   9:0]    w_waddr3 = r_wr_adr_cnt + 3;  

wire  [   2:0]    w_wr_wp0 = r_wr_wp;
wire  [   2:0]    w_wr_wp1 = r_wr_wp + 1;
wire  [   2:0]    w_wr_wp2 = r_wr_wp + 2;
wire  [   2:0]    w_wr_wp3 = r_wr_wp + 3;

wire              w_wr_len_cnt = (r_wr_len_cnt<=r_axi4_slv_awlen__) ;
wire              w_wr_len_don = (r_wr_len_cnt>=r_axi4_slv_awlen__) ;

wire              w_wr_adr_end = ( r_slv_sel    ) ? ((r_axi4_slv_awsize_ == AXI4_SIZE__1BYTE) ? (r_wr_adr_cnt  >=1024) ? 1'b1 : 1'b0 :
                                                     (r_axi4_slv_awsize_ == AXI4_SIZE__2BYTE) ? (r_wr_adr_cnt  >=1023) ? 1'b1 : 1'b0 :
                                                     (r_axi4_slv_awsize_ == AXI4_SIZE__4BYTE) ? (r_wr_adr_cnt  >=1021) ? 1'b1 : 1'b0 : 1'b0):
                                                    ((r_axi4_slv_awsize_ == AXI4_SIZE__1BYTE) ? (r_wr_adr_cnt+1>= 512) ? 1'b1 : 1'b0 : // wr_lp 1,0 
                                                                                                (r_wr_adr_cnt+7>= 512) ? 1'b1 : 1'b0); // wr_lp 7,6,5,4,3,2,1,0
                                                                                                
wire              w_wr_dat_end = ( r_slv_sel    ) ? ( w_wr_len_don ) ? 1'b1 : 1'b0 : 
                                                    ( w_wr_adr_end ) ? (~|r_wr_lp) ? ( w_wr_len_don ) ? 1'b1 : 1'b0 : 1'b0 :
                                                                       (~|r_wr_lp) ? (~w_wr_len_cnt ) ? 1'b1 : 1'b0 : 1'b0 ;                                                                                                              
                                                                            
wire              w_wready_ena = ( w_wr_adr_end ) ? ( w_wr_len_cnt ) ? 1'b1 : 1'b0 :
                                                    ( w_wr_len_cnt ) ? (r_axi4_slv_awsize_ == AXI4_SIZE__1BYTE) ? (r_wr_lp<=7) ? 1'b1 : 1'b0 :
                                                                       (r_axi4_slv_awsize_ == AXI4_SIZE__2BYTE) ? (r_wr_lp<=6) ? 1'b1 : 1'b0 :
                                                                       (r_axi4_slv_awsize_ == AXI4_SIZE__4BYTE) ? (r_wr_lp<=4) ? 1'b1 : 1'b0 : 1'b0 : 1'b0 ;

wire              w_rvalid_ena;
wire              w_rd_lst_dat;
wire              w_rd_dat_end;                
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// compiled SRAM instantiation
///////////////////////////////////////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// slave select
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
always@(posedge clk_axi_slv or negedge rstb_slv)
   if(!rstb_slv)
      r_slv_sel <= 1'b0;
   else if(w_axi4_wr__reg_slv || w_axi4_rd__reg_slv || w_axi4_wr__rsv_slv || w_axi4_rd__rsv_slv)
      r_slv_sel <= 1'b1;
   else if(w_axi4_wr__mem_slv || w_axi4_rd__mem_slv)
      r_slv_sel <= 1'b0;
      
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Initial latch signal
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
always @(posedge clk_axi_slv)
   if(w_wr_nxt == AXI4_SLV_WR_ADDR || w_wr_nxt == AXI4_SLV_WR_RSVD) begin
      r_axi4_slv_awid___ <= i_axi4_slv_awid___;
      r_axi4_slv_awaddr_ <= i_axi4_slv_awaddr_;
      r_axi4_slv_awlen__ <= i_axi4_slv_awlen__;
      r_axi4_slv_awsize_ <= i_axi4_slv_awsize_;
   end

always @(posedge clk_axi_slv)
   if(w_wr_nxt == AXI4_SLV_RD_ADDR || w_wr_nxt == AXI4_SLV_RD_RSVD) begin
      r_axi4_slv_arid___ <= i_axi4_slv_arid___;
      r_axi4_slv_araddr_ <= i_axi4_slv_araddr_;
      r_axi4_slv_arlen__ <= i_axi4_slv_arlen__;
      r_axi4_slv_arsize_ <= i_axi4_slv_arsize_;
   end

///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// write FSM
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
always@(posedge clk_axi_slv or negedge rstb_slv)
   if(!rstb_slv)
      r_wr_fsm <= AXI4_SLV_WR_IDLE;
   else
      r_wr_fsm <= w_wr_nxt;

always@*
   case(r_wr_fsm)
      AXI4_SLV_WR_IDLE : w_wr_nxt = ( w_axi4_wr__bus_slv ) ? AXI4_SLV_WR_ADDR : 
                                    ( w_axi4_wr__rsv_slv ) ? AXI4_SLV_WR_RSVD : AXI4_SLV_WR_IDLE ;
      AXI4_SLV_WR_ADDR : w_wr_nxt = ( i_axi4_slv_awvalid ) ? AXI4_SLV_WR_DATA : AXI4_SLV_WR_ADDR ;
      AXI4_SLV_WR_DATA : w_wr_nxt = ( w_wr_dat_end       ) ? AXI4_SLV_WR_BRSP : AXI4_SLV_WR_DATA ;
      AXI4_SLV_WR_RSVD : w_wr_nxt = ( i_axi4_slv_awvalid ) ? AXI4_SLV_WR_RSDT : AXI4_SLV_WR_RSVD ;
      AXI4_SLV_WR_RSDT : w_wr_nxt = ( w_wr_dat_end       ) ? AXI4_SLV_WR_BRSP : AXI4_SLV_WR_RSDT ;
      AXI4_SLV_WR_BRSP : w_wr_nxt = AXI4_SLV_WR_IDLE ;
      default          : w_wr_nxt = AXI4_SLV_WR_IDLE ;
   endcase
   
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// write output signal
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
always@(posedge clk_axi_slv or negedge rstb_slv)
   if(!rstb_slv)
      o_axi4_slv_awready <= 1'b0;
   else if(w_wr_nxt == AXI4_SLV_WR_ADDR || w_wr_nxt == AXI4_SLV_WR_RSVD)
      o_axi4_slv_awready <= 1'b1;
   else 
      o_axi4_slv_awready <= 1'b0;

always@*
   if(r_wr_fsm == AXI4_SLV_WR_RSDT)
      o_axi4_slv_wready_ = 1'b1;
   else if(r_wr_fsm == AXI4_SLV_WR_DATA)
      o_axi4_slv_wready_ = (r_slv_sel) ? 1'b1 : w_wready_ena;
   else
      o_axi4_slv_wready_ = 1'b0;
      
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// wp, lp, rp
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
always@(posedge clk_axi_slv)
   if(r_wr_fsm == AXI4_SLV_WR_ADDR)
      r_wr_wp <= 3'd0;
   else if(~r_slv_sel && i_axi4_slv_wvalid_ &&  w_wready_ena && (r_wr_fsm == AXI4_SLV_WR_DATA))
      case(r_axi4_slv_awsize_)
         AXI4_SIZE__1BYTE : r_wr_wp <= r_wr_wp + 1;
         AXI4_SIZE__2BYTE : r_wr_wp <= r_wr_wp + 2;
         AXI4_SIZE__4BYTE : r_wr_wp <= r_wr_wp + 4;
      endcase

always@(posedge clk_axi_slv)
   if(r_wr_fsm == AXI4_SLV_WR_ADDR)
      r_wr_lp <= 4'd0;
   else if(~r_slv_sel && i_axi4_slv_wvalid_ && ~w_wr_adr_end && (r_wr_fsm == AXI4_SLV_WR_DATA))
      case(r_axi4_slv_awsize_)
         AXI4_SIZE__1BYTE : r_wr_lp <= (w_wready_ena) ? (|r_wr_lp) ? r_wr_lp     : r_wr_lp + 1 :
                                                        (|r_wr_lp) ? r_wr_lp - 1 : r_wr_lp ;
         AXI4_SIZE__2BYTE : r_wr_lp <= (w_wready_ena) ? (|r_wr_lp) ? r_wr_lp + 1 : r_wr_lp + 2 :                                               
                                                        (|r_wr_lp) ? r_wr_lp - 1 : r_wr_lp ;
         AXI4_SIZE__4BYTE : r_wr_lp <= (w_wready_ena) ? (|r_wr_lp) ? r_wr_lp + 3 : r_wr_lp + 4 :                                       
                                                        (|r_wr_lp) ? r_wr_lp - 1 : r_wr_lp ;
      endcase
   else if(~r_slv_sel && i_axi4_slv_wvalid_ &&  w_wr_adr_end && (r_wr_fsm == AXI4_SLV_WR_DATA))
      r_wr_lp <= (~|r_wr_lp) ? r_wr_lp : r_wr_lp - 1;
      

always@(posedge clk_axi_slv)
   if(r_wr_fsm == AXI4_SLV_WR_ADDR)
      r_wr_rp <= 3'd0;
   else if(~r_slv_sel && (|r_wr_lp))
      r_wr_rp <= r_wr_rp + 1;
                                                                                                                          
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// address count, length count, sram buff address count
///////////////////////////////////////////////////////////////////////////////////////////////////////////////                      
always@(posedge clk_axi_slv)
   if(r_wr_fsm == AXI4_SLV_WR_ADDR)
      case(r_axi4_slv_awsize_)
         AXI4_SIZE__1BYTE : r_wr_adr_cnt <=  i_axi4_slv_awaddr_[9:0]         ;
         AXI4_SIZE__2BYTE : r_wr_adr_cnt <= {i_axi4_slv_awaddr_[9:1], 1'b0 } ;
         AXI4_SIZE__4BYTE : r_wr_adr_cnt <= {i_axi4_slv_awaddr_[9:2], 2'b00} ;
      endcase
   else if( r_slv_sel && (r_wr_fsm == AXI4_SLV_WR_DATA) && i_axi4_slv_wvalid_ )
      case(r_axi4_slv_awsize_)
         AXI4_SIZE__1BYTE : r_wr_adr_cnt <= (r_wr_adr_cnt>=1023) ? r_wr_adr_cnt : r_wr_adr_cnt + 1 ;
         AXI4_SIZE__2BYTE : r_wr_adr_cnt <= (r_wr_adr_cnt>=1022) ? r_wr_adr_cnt : r_wr_adr_cnt + 2 ;
         AXI4_SIZE__4BYTE : r_wr_adr_cnt <= (r_wr_adr_cnt>=1020) ? r_wr_adr_cnt : r_wr_adr_cnt + 4 ;
      endcase
   else if(~r_slv_sel && (r_wr_fsm == AXI4_SLV_WR_DATA) && |r_wr_lp )
      r_wr_adr_cnt <= (r_wr_adr_cnt>=511) ? r_wr_adr_cnt : r_wr_adr_cnt + 1 ;
      
always@(posedge clk_axi_slv)
   if((r_wr_fsm == AXI4_SLV_WR_ADDR) || (r_wr_fsm == AXI4_SLV_WR_RSVD))
      r_wr_len_cnt <= 8'd0;
   else if( r_slv_sel && (r_wr_fsm == AXI4_SLV_WR_DATA || r_wr_fsm == AXI4_SLV_WR_RSDT) && i_axi4_slv_wvalid_ )
      r_wr_len_cnt <= r_wr_len_cnt + 1;
   else if(~r_slv_sel && (r_wr_fsm == AXI4_SLV_WR_DATA) && i_axi4_slv_wvalid_ && w_wready_ena )
      r_wr_len_cnt <= r_wr_len_cnt + 1;
      
always@(posedge clk_axi_slv)
   if(r_wr_fsm == AXI4_SLV_WR_ADDR)
      case(r_axi4_slv_awsize_)
         AXI4_SIZE__1BYTE : r_wr_buf_cnt <=  i_axi4_slv_awaddr_[1:0]         ;
         AXI4_SIZE__2BYTE : r_wr_buf_cnt <= {i_axi4_slv_awaddr_[1  ], 1'b0 } ;
         AXI4_SIZE__4BYTE : r_wr_buf_cnt <=                           2'b00  ;
      endcase
   else if(~r_slv_sel && (r_wr_fsm == AXI4_SLV_WR_DATA) && i_axi4_slv_wvalid_ )
      case(r_axi4_slv_awsize_)
         AXI4_SIZE__1BYTE : r_wr_buf_cnt <= r_wr_buf_cnt + 1 ;
         AXI4_SIZE__2BYTE : r_wr_buf_cnt <= r_wr_buf_cnt + 2 ;
         AXI4_SIZE__4BYTE : r_wr_buf_cnt <= r_wr_buf_cnt + 4 ;
      endcase
      
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// register write 
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
                      
always@(posedge clk_axi_slv)
   if( r_slv_sel && i_axi4_slv_wvalid_ && (r_wr_fsm == AXI4_SLV_WR_DATA) && ~w_wr_adr_end )
      case(r_axi4_slv_awsize_)
         AXI4_SIZE__1BYTE : register[w_waddr0] <= (r_wr_adr_cnt[1:0] == 2'b00) ? w_wdata0 :
                                                  (r_wr_adr_cnt[1:0] == 2'b01) ? w_wdata1 :
                                                  (r_wr_adr_cnt[1:0] == 2'b10) ? w_wdata2 : w_wdata3 ;
         AXI4_SIZE__2BYTE : begin
                            register[w_waddr0] <= (r_wr_adr_cnt[1]   == 1'b0 ) ? w_wdata0 : w_wdata2 ;
                            register[w_waddr1] <= (r_wr_adr_cnt[1]   == 1'b0 ) ? w_wdata1 : w_wdata3 ;
                            end
         AXI4_SIZE__4BYTE : begin
                            register[w_waddr0] <= w_wdata0 ;
                            register[w_waddr1] <= w_wdata1 ;
                            register[w_waddr2] <= w_wdata2 ;
                            register[w_waddr3] <= w_wdata3 ;
                            end
      endcase
   else if(~r_slv_sel && i_axi4_slv_wvalid_ && (r_wr_fsm == AXI4_SLV_WR_DATA) && ~w_wr_adr_end && w_wready_ena ) 
      case(r_axi4_slv_awsize_)
         AXI4_SIZE__1BYTE : sram_wr_buff[w_wr_wp0] <= (r_wr_buf_cnt[1:0] == 2'b00) ? w_wdata0 :
                                                      (r_wr_buf_cnt[1:0] == 2'b01) ? w_wdata1 :
                                                      (r_wr_buf_cnt[1:0] == 2'b10) ? w_wdata2 : w_wdata3 ;
         AXI4_SIZE__2BYTE : begin
                            sram_wr_buff[w_wr_wp0] <= (r_wr_buf_cnt[1]   == 1'b0 ) ? w_wdata0 : w_wdata2 ;
                            sram_wr_buff[w_wr_wp1] <= (r_wr_buf_cnt[1]   == 1'b0 ) ? w_wdata1 : w_wdata3 ;
                            end
         AXI4_SIZE__4BYTE : begin
                            sram_wr_buff[w_wr_wp0] <= w_wdata0 ;
                            sram_wr_buff[w_wr_wp1] <= w_wdata1 ;
                            sram_wr_buff[w_wr_wp2] <= w_wdata2 ;
                            sram_wr_buff[w_wr_wp3] <= w_wdata3 ;
                            end
      endcase

///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// read FSM
///////////////////////////////////////////////////////////////////////////////////////////////////////////////      
always@(posedge clk_axi_slv or negedge rstb_slv)
   if(!rstb_slv)
      r_rd_fsm <= AXI4_SLV_RD_IDLE ;
   else 
      r_rd_fsm <= w_rd_nxt ;

wire  w_axi4_slv_rd_data = (i_axi4_slv_arvalid &&  |r_axi4_slv_arlen__);
wire  w_axi4_slv_rd_last = (i_axi4_slv_arvalid && ~|r_axi4_slv_arlen__);   
   
always@*
   case(r_rd_fsm)
      AXI4_SLV_RD_IDLE : w_rd_nxt = ( w_axi4_rd__bus_slv ) ? AXI4_SLV_RD_ADDR : 
                                    ( w_axi4_rd__rsv_slv ) ? AXI4_SLV_RD_RSVD : AXI4_SLV_RD_IDLE ;
      AXI4_SLV_RD_ADDR : w_rd_nxt = ( w_axi4_slv_rd_data ) ? AXI4_SLV_RD_DATA : 
                                    ( w_axi4_slv_rd_last ) ? AXI4_SLV_RD_LAST : AXI4_SLV_RD_ADDR ;
      AXI4_SLV_RD_DATA : w_rd_nxt = ( i_axi4_slv_awvalid ) ? AXI4_SLV_RD_HOLD : 
                                    ( w_rd_lst_dat       ) ? AXI4_SLV_RD_LAST : AXI4_SLV_RD_DATA ;
      AXI4_SLV_RD_HOLD : w_rd_nxt = ( w_wr_dat_end       ) ? AXI4_SLV_RD_DATA : AXI4_SLV_RD_HOLD ;
      AXI4_SLV_RD_RSVD : w_rd_nxt = ( w_axi4_slv_rd_data ) ? AXI4_SLV_RD_RSDT : 
                                    ( w_axi4_slv_rd_last ) ? AXI4_SLV_RD_LAST : AXI4_SLV_RD_RSVD ;
      AXI4_SLV_RD_RSDT : w_rd_nxt = ( i_axi4_slv_awvalid ) ? AXI4_SLV_RD_HOLD : 
                                    ( w_rd_lst_dat       ) ? AXI4_SLV_RD_LAST : AXI4_SLV_RD_RSDT ;
      AXI4_SLV_RD_LAST : w_rd_nxt = ( w_rd_dat_end       ) ? AXI4_SLV_RD_IDLE : AXI4_SLV_RD_LAST ;
      default          : w_rd_nxt = AXI4_SLV_RD_IDLE ;
   endcase

///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// read output signals
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
always@(posedge clk_axi_slv or rstb_slv)
   if(!rstb_slv)
      o_axi4_slv_arready <= 1'b0;
   else if(w_rd_nxt == AXI4_SLV_RD_ADDR || w_rd_nxt == AXI4_SLV_RD_RSVD)
      o_axi4_slv_arready <= 1'b1;
   else
      o_axi4_slv_arready <= 1'b0;

always@*
   if(r_rd_fsm == AXI4_SLV_RD_RSDT) 
      o_axi4_slv_rvalid_ = 1'b1;
   else if(r_rd_fsm == AXI4_SLV_RD_DATA)
      o_axi4_slv_rvalid_ = (r_slv_sel) ? 1'b1 : w_rvalid_ena;
   else  
      o_axi4_slv_rvalid_ = 1'b0;

///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// read address count 
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
always@(posedge clk_axi_slv)
   if(r_rd_fsm == AXI4_SLV_RD_ADDR)
      case(r_axi4_slv_arsize_)
         AXI4_SIZE__1BYTE : r_rd_adr_cnt <=  i_axi4_slv_araddr_[9:0]         ;
         AXI4_SIZE__2BYTE : r_rd_adr_cnt <= {i_axi4_slv_araddr_[9:1], 1'b0 } ;
         AXI4_SIZE__4BYTE : r_rd_adr_cnt <= {i_axi4_slv_araddr_[9:2], 2'b00} ;
      endcase
   else if( r_slv_sel && (r_rd_fsm == AXI4_SLV_RD_DATA || r_rd_fsm == AXI4_SLV_RD_LAST) && i_axi4_slv_rready_ )
      case(r_axi4_slv_arsize_)
         AXI4_SIZE__1BYTE : r_rd_adr_cnt <= (r_rd_adr_cnt>=1023) ? r_rd_adr_cnt : r_rd_adr_cnt + 1 ;
         AXI4_SIZE__2BYTE : r_rd_adr_cnt <= (r_rd_adr_cnt>=1022) ? r_rd_adr_cnt : r_rd_adr_cnt + 2 ;
         AXI4_SIZE__4BYTE : r_rd_adr_cnt <= (r_rd_adr_cnt>=1020) ? r_rd_adr_cnt : r_rd_adr_cnt + 4 ;
      endcase

///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// wp, lp, rp
///////////////////////////////////////////////////////////////////////////////////////////////////////////////

   

endmodule

 

 

bus_slv_para.sv

 

localparam  AXI4_SLV____SRAM  =  8'h00; // mem identifier
localparam  AXI4_SLV_____REG  =  8'h01; // buf identifier

localparam  AXI4_SIZE__1BYTE  =  3'b000;
localparam  AXI4_SIZE__2BYTE  =  3'b001;
localparam  AXI4_SIZE__4BYTE  =  3'b010;

localparam  AXI4_RESP___OKAY  =  2'b00;
localparam  AXI4_RESP_EXOKAY  =  2'b01;
localparam  AXI4_RESP_SLVERR  =  2'b10;
localparam  AXI4_RESP_DECERR  =  2'b11;

localparam  AXI4_SLV_WR_IDLE  =  3'd0;
localparam  AXI4_SLV_WR_ADDR  =  3'd1;
localparam  AXI4_SLV_WR_DATA  =  3'd2;
localparam  AXI4_SLV_WR_BRSP  =  3'd3;
localparam  AXI4_SLV_WR_RSVD  =  3'd4;
localparam  AXI4_SLV_WR_RSDT  =  3'd5;

localparam  AXI4_SLV_RD_IDLE  =  3'd0;
localparam  AXI4_SLV_RD_ADDR  =  3'd1;
localparam  AXI4_SLV_RD_DATA  =  3'd2;
localparam  AXI4_SLV_RD_HOLD  =  3'd3;
localparam  AXI4_SLV_RD_RSVD  =  3'd4;
localparam  AXI4_SLV_RD_RSDT  =  3'd5;

 

 

tb_bus_slv.v

 

`timescale 1ns/1ns

//`define BUS_SIZE2_MEM
//`define BUS_SIZE1_MEM
//`define BUS_SIZE0_MEM
`define BUS_SIZE2_REG
//`define BUS_SIZE1_REG
//`define BUS_SIZE0_REG

module tb_bus_slv ();

   reg            clk_axi_slv             ;
   reg            rstb_slv                ;
   // write address channel
   reg   [ 1:0]   i_axi4_slv_awid___      ;
   reg   [31:0]   i_axi4_slv_awaddr_      ;
   reg   [ 7:0]   i_axi4_slv_awlen__      ;
   reg   [ 2:0]   i_axi4_slv_awsize_      ;
   reg            i_axi4_slv_awvalid      ;
   wire           o_axi4_slv_awready      ;
   // write data channel
   reg   [ 1:0]   i_axi4_slv_wid____      ;
   reg   [31:0]   i_axi4_slv_wdata__      ;
   reg            i_axi4_slv_wlast__      ;
   reg            i_axi4_slv_wvalid_      ;
   wire           o_axi4_slv_wready_      ;
   // write response channel
   wire  [ 1:0]   o_axi4_slv_bid____      ;
   wire  [ 1:0]   o_axi4_slv_bresp__      ;
   wire           o_axi4_slv_bvalid_      ;
   reg            i_axi4_slv_bready_      ;
   // read address channel
   reg   [ 1:0]   i_axi4_slv_arid___      ;
   reg   [31:0]   i_axi4_slv_araddr_      ;
   reg   [ 7:0]   i_axi4_slv_arlen__      ;
   reg   [ 2:0]   i_axi4_slv_arsize_      ;
   reg            i_axi4_slv_arvalid      ;
   wire           o_axi4_slv_arready      ;
   // read data channel
   wire  [ 1:0]   o_axi4_slv_rid____      ;
   wire  [31:0]   o_axi4_slv_rdata__      ;
   wire  [ 1:0]   o_axi4_slv_rresp__      ;
   wire           o_axi4_slv_rlast__      ;
   wire           o_axi4_slv_rvalid_      ;
   reg            i_axi4_slv_rready_      ;

   bus_slv u_bus_slv (
      .clk_axi_slv         (clk_axi_slv         ),    
      .rstb_slv            (rstb_slv            ),    
      .i_axi4_slv_awid___  (i_axi4_slv_awid___  ), 
      .i_axi4_slv_awaddr_  (i_axi4_slv_awaddr_  ), 
      .i_axi4_slv_awlen__  (i_axi4_slv_awlen__  ), 
      .i_axi4_slv_awsize_  (i_axi4_slv_awsize_  ), 
      .i_axi4_slv_awvalid  (i_axi4_slv_awvalid  ), 
      .o_axi4_slv_awready  (o_axi4_slv_awready  ), 
      .i_axi4_slv_wid____  (i_axi4_slv_wid____  ), 
      .i_axi4_slv_wdata__  (i_axi4_slv_wdata__  ), 
      .i_axi4_slv_wlast__  (i_axi4_slv_wlast__  ), 
      .i_axi4_slv_wvalid_  (i_axi4_slv_wvalid_  ), 
      .o_axi4_slv_wready_  (o_axi4_slv_wready_  ), 
      .o_axi4_slv_bid____  (o_axi4_slv_bid____  ), 
      .o_axi4_slv_bresp__  (o_axi4_slv_bresp__  ), 
      .o_axi4_slv_bvalid_  (o_axi4_slv_bvalid_  ), 
      .i_axi4_slv_bready_  (i_axi4_slv_bready_  ), 
      .i_axi4_slv_arid___  (i_axi4_slv_arid___  ), 
      .i_axi4_slv_araddr_  (i_axi4_slv_araddr_  ), 
      .i_axi4_slv_arlen__  (i_axi4_slv_arlen__  ), 
      .i_axi4_slv_arsize_  (i_axi4_slv_arsize_  ), 
      .i_axi4_slv_arvalid  (i_axi4_slv_arvalid  ), 
      .o_axi4_slv_arready  (o_axi4_slv_arready  ), 
      .o_axi4_slv_rid____  (o_axi4_slv_rid____  ), 
      .o_axi4_slv_rdata__  (o_axi4_slv_rdata__  ), 
      .o_axi4_slv_rresp__  (o_axi4_slv_rresp__  ), 
      .o_axi4_slv_rlast__  (o_axi4_slv_rlast__  ), 
      .o_axi4_slv_rvalid_  (o_axi4_slv_rvalid_  ), 
      .i_axi4_slv_rready_  (i_axi4_slv_rready_  )
   );

`include "bus_slv_para.sv"

integer i,j;

always@*
   if(u_bus_slv.r_wr_fsm == AXI4_SLV_WR_ADDR)
      for(i=0;i<=1023;i=i+1)
         u_bus_slv.register[i] = 8'hxx;

always@*
   if(u_bus_slv.r_wr_fsm == AXI4_SLV_WR_ADDR)   
      for(j=0;j<=7;j=j+1)
         u_bus_slv.sram_wr_buff[j] = 8'hxx;
         
`ifdef BUS_SIZE2_REG
      
initial begin
   // write initial value
   i_axi4_slv_awvalid = 1'b0;
   i_axi4_slv_awaddr_ = 32'h3046_d70c;
   i_axi4_slv_awid___ = 2'd0;
   i_axi4_slv_awlen__ = 8'd0;
   i_axi4_slv_awsize_ = 3'd0;    
   // read initial value
   i_axi4_slv_arvalid = 1'b0;
   i_axi4_slv_araddr_ = 32'h3046_d70c;
   i_axi4_slv_arid___ = 2'd0;
   i_axi4_slv_arlen__ = 8'd0;
   i_axi4_slv_arsize_ = 3'd0;    
   repeat(100) @(posedge clk_axi_slv);
   // write transaction : addr, id, len, size
   wr_trans(32'h0100_0000, 2'd1, 8'd255, 3'd2);
   repeat(300) @(posedge clk_axi_slv);
   wr_trans(32'h0100_0001, 2'd1, 8'd255, 3'd2);
   repeat(300) @(posedge clk_axi_slv);
   wr_trans(32'h0100_0002, 2'd1, 8'd255, 3'd2);
   repeat(300) @(posedge clk_axi_slv);
   wr_trans(32'h0100_0003, 2'd1, 8'd255, 3'd2);
   repeat(300) @(posedge clk_axi_slv);
   wr_trans(32'h0100_0004, 2'd1, 8'd255, 3'd2);
   repeat(300) @(posedge clk_axi_slv);
   
   wr_trans(32'h0100_0000, 2'd1, 8'd255, 3'd2);
   repeat(300) @(posedge clk_axi_slv);
   wr_trans(32'h0100_0100, 2'd1, 8'd255, 3'd2);
   repeat(300) @(posedge clk_axi_slv);
   wr_trans(32'h0100_0200, 2'd1, 8'd255, 3'd2);
   repeat(300) @(posedge clk_axi_slv);
   wr_trans(32'h0100_0300, 2'd1, 8'd255, 3'd2);
   repeat(300) @(posedge clk_axi_slv);
   
   wr_trans(32'h0100_0000, 2'd1, 8'd255, 3'd2);
   repeat(300) @(posedge clk_axi_slv);
   wr_trans(32'h0100_0000, 2'd1, 8'd1  , 3'd2);
   repeat(300) @(posedge clk_axi_slv);
   wr_trans(32'h0100_0000, 2'd1, 8'd0  , 3'd2);
   repeat(300) @(posedge clk_axi_slv); 
   
   rd_trans(32'h0100_0000, 2'd1, 8'd255, 3'd2);
   repeat(300) @(posedge clk_axi_slv);    
end

`elsif BUS_SIZE1_REG

initial begin
   // write initial value
   i_axi4_slv_awvalid = 1'b0;
   i_axi4_slv_awaddr_ = 32'h3046_d70c;
   i_axi4_slv_awid___ = 2'd0;
   i_axi4_slv_awlen__ = 8'd0;
   i_axi4_slv_awsize_ = 3'd0;    
   // read initial value
   i_axi4_slv_arvalid = 1'b0;
   i_axi4_slv_araddr_ = 32'h3046_d70c;
   i_axi4_slv_arid___ = 2'd0;
   i_axi4_slv_arlen__ = 8'd0;
   i_axi4_slv_arsize_ = 3'd0;    
   repeat(100) @(posedge clk_axi_slv);
   // write transaction : addr, id, len, size
   wr_trans(32'h0100_0000, 2'd1, 8'd255, 3'd1);
   repeat(300) @(posedge clk_axi_slv);
   wr_trans(32'h0100_0001, 2'd1, 8'd255, 3'd1);
   repeat(300) @(posedge clk_axi_slv);
   wr_trans(32'h0100_0002, 2'd1, 8'd255, 3'd1);
   repeat(300) @(posedge clk_axi_slv);
   wr_trans(32'h0100_0003, 2'd1, 8'd255, 3'd1);
   repeat(300) @(posedge clk_axi_slv);
   wr_trans(32'h0100_0004, 2'd1, 8'd255, 3'd1);
   repeat(300) @(posedge clk_axi_slv);
   
   wr_trans(32'h0100_0000, 2'd1, 8'd255, 3'd1);
   repeat(300) @(posedge clk_axi_slv);
   wr_trans(32'h0100_0100, 2'd1, 8'd255, 3'd1);
   repeat(300) @(posedge clk_axi_slv);
   wr_trans(32'h0100_0200, 2'd1, 8'd255, 3'd1);
   repeat(300) @(posedge clk_axi_slv);
   wr_trans(32'h0100_0300, 2'd1, 8'd255, 3'd1);
   repeat(300) @(posedge clk_axi_slv);
   
   wr_trans(32'h0100_0000, 2'd1, 8'd255, 3'd1);
   repeat(300) @(posedge clk_axi_slv);
   wr_trans(32'h0100_0000, 2'd1, 8'd1  , 3'd1);
   repeat(300) @(posedge clk_axi_slv);
   wr_trans(32'h0100_0000, 2'd1, 8'd0  , 3'd1);
   repeat(300) @(posedge clk_axi_slv); 
end

`elsif BUS_SIZE0_REG

initial begin
   // write initial value
   i_axi4_slv_awvalid = 1'b0;
   i_axi4_slv_awaddr_ = 32'h3046_d70c;
   i_axi4_slv_awid___ = 2'd0;
   i_axi4_slv_awlen__ = 8'd0;
   i_axi4_slv_awsize_ = 3'd0;    
   // read initial value
   i_axi4_slv_arvalid = 1'b0;
   i_axi4_slv_araddr_ = 32'h3046_d70c;
   i_axi4_slv_arid___ = 2'd0;
   i_axi4_slv_arlen__ = 8'd0;
   i_axi4_slv_arsize_ = 3'd0;    
   repeat(100) @(posedge clk_axi_slv);
   // write transaction : addr, id, len, size
   wr_trans(32'h0100_0000, 2'd1, 8'd255, 3'd0);
   repeat(300) @(posedge clk_axi_slv);
   wr_trans(32'h0100_0001, 2'd1, 8'd255, 3'd0);
   repeat(300) @(posedge clk_axi_slv);
   wr_trans(32'h0100_0002, 2'd1, 8'd255, 3'd0);
   repeat(300) @(posedge clk_axi_slv);
   wr_trans(32'h0100_0003, 2'd1, 8'd255, 3'd0);
   repeat(300) @(posedge clk_axi_slv);
   wr_trans(32'h0100_0004, 2'd1, 8'd255, 3'd0);
   repeat(300) @(posedge clk_axi_slv);
   
   wr_trans(32'h0100_0000, 2'd1, 8'd255, 3'd0);
   repeat(300) @(posedge clk_axi_slv);
   wr_trans(32'h0100_0100, 2'd1, 8'd255, 3'd0);
   repeat(300) @(posedge clk_axi_slv);
   wr_trans(32'h0100_0200, 2'd1, 8'd255, 3'd0);
   repeat(300) @(posedge clk_axi_slv);
   wr_trans(32'h0100_0300, 2'd1, 8'd255, 3'd0);
   repeat(300) @(posedge clk_axi_slv);
   
   wr_trans(32'h0100_0000, 2'd1, 8'd255, 3'd0);
   repeat(300) @(posedge clk_axi_slv);
   wr_trans(32'h0100_0000, 2'd1, 8'd1  , 3'd0);
   repeat(300) @(posedge clk_axi_slv);
   wr_trans(32'h0100_0000, 2'd1, 8'd0  , 3'd0);
   repeat(300) @(posedge clk_axi_slv);
end
   
`elsif BUS_SIZE2_MEM

initial begin
   // write initial value
   i_axi4_slv_awvalid = 1'b0;
   i_axi4_slv_awaddr_ = 32'h3046_d70c;
   i_axi4_slv_awid___ = 2'd0;
   i_axi4_slv_awlen__ = 8'd0;
   i_axi4_slv_awsize_ = 3'd0;    
   // read initial value
   i_axi4_slv_arvalid = 1'b0;
   i_axi4_slv_araddr_ = 32'h3046_d70c;
   i_axi4_slv_arid___ = 2'd0;
   i_axi4_slv_arlen__ = 8'd0;
   i_axi4_slv_arsize_ = 3'd0;    
   repeat(100) @(posedge clk_axi_slv);
   // write transaction : addr, id, len, size
   wr_trans(32'h0000_0000, 2'd1, 8'd255, 3'd2);
   repeat(1000) @(posedge clk_axi_slv);
   wr_trans(32'h0000_0000, 2'd1, 8'd127, 3'd2);
   repeat(1000) @(posedge clk_axi_slv);
   wr_trans(32'h0000_0000, 2'd1, 8'd63 , 3'd2);
   repeat(1000) @(posedge clk_axi_slv);
   wr_trans(32'h0000_0000, 2'd1, 8'd1  , 3'd2);
   repeat(1000) @(posedge clk_axi_slv);
   wr_trans(32'h0000_0000, 2'd1, 8'd0  , 3'd2);
   repeat(1000) @(posedge clk_axi_slv);
   
   wr_trans(32'h0000_0100, 2'd1, 8'd255, 3'd2);
   repeat(1000) @(posedge clk_axi_slv);
   wr_trans(32'h0000_0200, 2'd1, 8'd255, 3'd2);
   repeat(1000) @(posedge clk_axi_slv);
   wr_trans(32'h0000_0300, 2'd1, 8'd255, 3'd2);
   repeat(1000) @(posedge clk_axi_slv);
   
   wr_trans(32'h0000_0001, 2'd1, 8'd255, 3'd2);
   repeat(1000) @(posedge clk_axi_slv);
   wr_trans(32'h0000_0003, 2'd1, 8'd255, 3'd2);
   repeat(1000) @(posedge clk_axi_slv);
   wr_trans(32'h0000_0005, 2'd1, 8'd255, 3'd2);
   repeat(1000) @(posedge clk_axi_slv);
end

`elsif BUS_SIZE1_MEM

initial begin
   // write initial value
   i_axi4_slv_awvalid = 1'b0;
   i_axi4_slv_awaddr_ = 32'h3046_d70c;
   i_axi4_slv_awid___ = 2'd0;
   i_axi4_slv_awlen__ = 8'd0;
   i_axi4_slv_awsize_ = 3'd0;    
   // read initial value
   i_axi4_slv_arvalid = 1'b0;
   i_axi4_slv_araddr_ = 32'h3046_d70c;
   i_axi4_slv_arid___ = 2'd0;
   i_axi4_slv_arlen__ = 8'd0;
   i_axi4_slv_arsize_ = 3'd0;    
   repeat(100) @(posedge clk_axi_slv);
   // write transaction : addr, id, len, size
   wr_trans(32'h0000_0000, 2'd1, 8'd255, 3'd1);
   repeat(1000) @(posedge clk_axi_slv);
   wr_trans(32'h0000_0000, 2'd1, 8'd127, 3'd1);
   repeat(1000) @(posedge clk_axi_slv);
   wr_trans(32'h0000_0000, 2'd1, 8'd63 , 3'd1);
   repeat(1000) @(posedge clk_axi_slv);
   wr_trans(32'h0000_0000, 2'd1, 8'd1  , 3'd1);
   repeat(1000) @(posedge clk_axi_slv);
   wr_trans(32'h0000_0000, 2'd1, 8'd0  , 3'd1);
   repeat(1000) @(posedge clk_axi_slv);

   wr_trans(32'h0000_0100, 2'd1, 8'd255, 3'd1);
   repeat(1000) @(posedge clk_axi_slv);
   wr_trans(32'h0000_0200, 2'd1, 8'd255, 3'd1);
   repeat(1000) @(posedge clk_axi_slv);
   wr_trans(32'h0000_0300, 2'd1, 8'd255, 3'd1);
   repeat(1000) @(posedge clk_axi_slv);

   wr_trans(32'h0000_0001, 2'd1, 8'd255, 3'd1);
   repeat(1000) @(posedge clk_axi_slv);
   wr_trans(32'h0000_0003, 2'd1, 8'd255, 3'd1);
   repeat(1000) @(posedge clk_axi_slv);
   wr_trans(32'h0000_0005, 2'd1, 8'd255, 3'd1);
   repeat(1000) @(posedge clk_axi_slv);
end
`endif
   
always@*
   if(u_bus_slv.r_wr_fsm == AXI4_SLV_WR_DATA || u_bus_slv.r_wr_fsm == AXI4_SLV_WR_RSDT)
      i_axi4_slv_wvalid_ = 1'b1;

always@(posedge clk_axi_slv)
   if(u_bus_slv.r_wr_fsm == AXI4_SLV_WR_ADDR || u_bus_slv.r_wr_fsm == AXI4_SLV_WR_RSVD)
      i_axi4_slv_wdata__ <= 32'h0302_0100;
   else if(i_axi4_slv_wvalid_ && o_axi4_slv_wready_ && (u_bus_slv.r_wr_fsm == AXI4_SLV_WR_DATA || u_bus_slv.r_wr_fsm == AXI4_SLV_WR_RSDT))
      i_axi4_slv_wdata__ <= i_axi4_slv_wdata__ + 32'h0404_0404;

always@*
   if((u_bus_slv.r_wr_fsm == AXI4_SLV_WR_DATA || u_bus_slv.r_wr_fsm == AXI4_SLV_WR_RSDT) && u_bus_slv.r_wr_len_cnt==u_bus_slv.r_axi4_slv_awlen__)
      i_axi4_slv_wlast__ <= 1'b1;
   else
      i_axi4_slv_wlast__ <= 1'b0;
      
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// transaction address task
///////////////////////////////////////////////////////////////////////////////////////////////////////////////   
task wr_trans ;
input [31:0]   t_addr;
input [ 1:0]   t_id;
input [ 7:0]   t_len;
input [ 2:0]   t_siz;
begin
   i_axi4_slv_awvalid = 1'b0;
   i_axi4_slv_awaddr_ = 32'h3046_d70c;
   i_axi4_slv_awid___ = 2'd0;
   i_axi4_slv_awlen__ = 8'd0;
   i_axi4_slv_awsize_ = 3'd0; 
   @(posedge clk_axi_slv);
   i_axi4_slv_awvalid = 1'b1;
   i_axi4_slv_awaddr_ = t_addr;
   i_axi4_slv_awid___ = t_id;
   i_axi4_slv_awlen__ = t_len;
   i_axi4_slv_awsize_ = t_siz;
   repeat(2) @(posedge clk_axi_slv);
   i_axi4_slv_awvalid = 1'b0;
   i_axi4_slv_awaddr_ = 32'h3046_d70c;
   i_axi4_slv_awid___ = 2'd0;
   i_axi4_slv_awlen__ = 8'd0;
   i_axi4_slv_awsize_ = 3'd0; 
end
endtask

task rd_trans ;
input [31:0]   t_addr;
input [ 1:0]   t_id;
input [ 7:0]   t_len;
input [ 2:0]   t_siz;
begin
   i_axi4_slv_arvalid = 1'b0;
   i_axi4_slv_araddr_ = 32'h3046_d70c;
   i_axi4_slv_arid___ = 2'd0;
   i_axi4_slv_arlen__ = 8'd0;
   i_axi4_slv_arsize_ = 3'd0; 
   @(posedge clk_axi_slv);
   i_axi4_slv_arvalid = 1'b1;
   i_axi4_slv_araddr_ = t_addr;
   i_axi4_slv_arid___ = t_id;
   i_axi4_slv_arlen__ = t_len;
   i_axi4_slv_arsize_ = t_siz;
   repeat(2) @(posedge clk_axi_slv);
   i_axi4_slv_arvalid = 1'b0;
   i_axi4_slv_araddr_ = 32'h3046_d70c;
   i_axi4_slv_arid___ = 2'd0;
   i_axi4_slv_arlen__ = 8'd0;
   i_axi4_slv_arsize_ = 3'd0; 
end
endtask

///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// clk & reset
///////////////////////////////////////////////////////////////////////////////////////////////////////////////   
initial begin
   clk_axi_slv = 1'b1;
   forever #5 clk_axi_slv = ~clk_axi_slv;
end

initial begin
   rstb_slv = 1'b1;
   @(negedge clk_axi_slv);
   rstb_slv = 1'b0;
   repeat(2) @(negedge clk_axi_slv);
   rstb_slv = 1'b1;
end

reg   [8*16-1:0] wr_fsm_txt;
always@(u_bus_slv.r_wr_fsm)begin
   case(u_bus_slv.r_wr_fsm)
      AXI4_SLV_WR_IDLE : wr_fsm_txt = "AXI4_SLV_WR_IDLE";
      AXI4_SLV_WR_ADDR : wr_fsm_txt = "AXI4_SLV_WR_ADDR";
      AXI4_SLV_WR_DATA : wr_fsm_txt = "AXI4_SLV_WR_DATA";
      AXI4_SLV_WR_BRSP : wr_fsm_txt = "AXI4_SLV_WR_BRSP";
      AXI4_SLV_WR_RSVD : wr_fsm_txt = "AXI4_SLV_WR_RSVD";
      AXI4_SLV_WR_RSDT : wr_fsm_txt = "AXI4_SLV_WR_RSDT";
      default          : wr_fsm_txt = "default";
   endcase
end

reg   [8*16-1:0] wr_nxt_txt;
always@(u_bus_slv.w_wr_nxt)begin
   case(u_bus_slv.w_wr_nxt)
      AXI4_SLV_WR_IDLE : wr_nxt_txt = "AXI4_SLV_WR_IDLE";
      AXI4_SLV_WR_ADDR : wr_nxt_txt = "AXI4_SLV_WR_ADDR";
      AXI4_SLV_WR_DATA : wr_nxt_txt = "AXI4_SLV_WR_DATA";
      AXI4_SLV_WR_BRSP : wr_nxt_txt = "AXI4_SLV_WR_BRSP";
      AXI4_SLV_WR_RSVD : wr_nxt_txt = "AXI4_SLV_WR_RSVD";
      AXI4_SLV_WR_RSDT : wr_nxt_txt = "AXI4_SLV_WR_RSDT";
      default          : wr_nxt_txt = "default";
   endcase
end

reg   [8*16-1:0] rd_fsm_txt;
always@(u_bus_slv.r_rd_fsm)begin
   case(u_bus_slv.r_rd_fsm)
      AXI4_SLV_RD_IDLE : rd_fsm_txt = "AXI4_SLV_RD_IDLE";
      AXI4_SLV_RD_ADDR : rd_fsm_txt = "AXI4_SLV_RD_ADDR";
      AXI4_SLV_RD_DATA : rd_fsm_txt = "AXI4_SLV_RD_DATA";
      AXI4_SLV_RD_LAST : rd_fsm_txt = "AXI4_SLV_RD_LAST";
      AXI4_SLV_RD_HOLD : rd_fsm_txt = "AXI4_SLV_RD_HOLD";
      AXI4_SLV_RD_RSVD : rd_fsm_txt = "AXI4_SLV_RD_RSVD";
      AXI4_SLV_RD_RSDT : rd_fsm_txt = "AXI4_SLV_RD_RSDT";
      default          : rd_fsm_txt = "default";
   endcase
end

reg   [8*16-1:0] rd_nxt_txt;
always@(u_bus_slv.w_rd_nxt)begin
   case(u_bus_slv.w_rd_nxt)
      AXI4_SLV_RD_IDLE : rd_nxt_txt = "AXI4_SLV_RD_IDLE";
      AXI4_SLV_RD_ADDR : rd_nxt_txt = "AXI4_SLV_RD_ADDR";
      AXI4_SLV_RD_DATA : rd_nxt_txt = "AXI4_SLV_RD_DATA";
      AXI4_SLV_RD_LAST : rd_nxt_txt = "AXI4_SLV_RD_LAST";
      AXI4_SLV_RD_HOLD : rd_nxt_txt = "AXI4_SLV_RD_HOLD";
      AXI4_SLV_RD_RSVD : rd_nxt_txt = "AXI4_SLV_RD_RSVD";
      AXI4_SLV_RD_RSDT : rd_nxt_txt = "AXI4_SLV_RD_RSDT";
      default          : rd_nxt_txt = "default";
   endcase
end

endmodule

 

 

tb_bus_slv.tcl

 

vlib work
vlog bus_slv.v tb_bus_slv.v bus_slv_para.sv
vsim work.tb_bus_slv
view wave

add wave -divider write

add wave -radix uns                 /clk_axi_slv
add wave -radix uns                 /rstb_slv            
add wave -radix hex                 /i_axi4_slv_awaddr_
add wave -radix uns                 /i_axi4_slv_awvalid
add wave -radix uns                 /u_bus_slv/w_axi4_wr__mem_slv
add wave -radix uns                 /u_bus_slv/w_axi4_wr__reg_slv
add wave -radix uns                 /u_bus_slv/w_axi4_wr__bus_slv
add wave -radix uns                 /u_bus_slv/w_axi4_wr__rsv_slv
add wave -radix uns                 /i_axi4_slv_awid___
add wave -radix uns                 /i_axi4_slv_awlen__
add wave -radix uns                 /i_axi4_slv_awsize_
add wave -radix ASCII -color gold   /wr_nxt_txt
add wave -radix ASCII -color gold   /wr_fsm_txt
add wave -radix uns                 /o_axi4_slv_awready
add wave -radix uns -color gray60   /u_bus_slv/r_axi4_slv_awaddr_
add wave -radix uns -color gray60   /u_bus_slv/r_axi4_slv_awid___
add wave -radix uns -color gray60   /u_bus_slv/r_axi4_slv_awlen__
add wave -radix uns -color gray60   /u_bus_slv/r_axi4_slv_awsize_          
add wave -radix uns                 /i_axi4_slv_wvalid_
add wave -radix hex                 /i_axi4_slv_wdata__
add wave -radix hex                 /i_axi4_slv_wlast__
add wave -radix uns -color gray80   /u_bus_slv/w_wdata0
add wave -radix uns -color gray80   /u_bus_slv/w_wdata1
add wave -radix uns -color gray80   /u_bus_slv/w_wdata2
add wave -radix uns -color gray80   /u_bus_slv/w_wdata3
add wave -radix uns                 /u_bus_slv/r_wr_buf_cnt          
add wave -radix uns                 /u_bus_slv/r_wr_wp
add wave -radix uns                 /u_bus_slv/r_wr_lp
add wave -radix uns                 /o_axi4_slv_wready_           
add wave -radix uns                 /u_bus_slv/r_wr_len_cnt
add wave -radix uns                 /u_bus_slv/w_wr_len_cnt
add wave -radix uns                 /u_bus_slv/w_wr_len_don
add wave -radix uns                 /u_bus_slv/sram_wr_buff
add wave -radix uns                 /u_bus_slv/r_wr_rp            
add wave -radix uns                 /u_bus_slv/r_wr_adr_cnt
add wave -radix uns                 /u_bus_slv/w_wr_adr_end
add wave -radix uns                 /u_bus_slv/w_wr_dat_end          
add wave -radix uns                 /u_bus_slv/register

add wave -divider read

add wave -radix uns                 /clk_axi_slv
add wave -radix uns                 /rstb_slv               
add wave -radix hex                 /i_axi4_slv_araddr_
add wave -radix uns                 /i_axi4_slv_arvalid
add wave -radix uns                 /u_bus_slv/w_axi4_rd__mem_slv
add wave -radix uns                 /u_bus_slv/w_axi4_rd__reg_slv
add wave -radix uns                 /u_bus_slv/w_axi4_rd__bus_slv
add wave -radix uns                 /u_bus_slv/w_axi4_rd__rsv_slv
add wave -radix uns                 /i_axi4_slv_arid___
add wave -radix uns                 /i_axi4_slv_arlen__
add wave -radix uns                 /i_axi4_slv_arsize_
add wave -radix ASCII -color gold   /rd_nxt_txt
add wave -radix ASCII -color gold   /rd_fsm_txt
add wave -radix uns                 /o_axi4_slv_arready


run 120000ns

 

 

 

AXI4 BUS SLV .xlsx
0.04MB

 

'Logic Design' 카테고리의 다른 글

Pulse Generator.  (0) 2024.03.24
SPI Interface.  (0) 2024.03.10
sys_sync_gen  (0) 2024.03.01
Image processing filter design.  (0) 2024.02.09
MIPI specification.  (0) 2024.02.01