2010年6月24日 星期四

AHB Slave emulator @ SystemC

continuous with AHB Master emulator @ SystemC

#include <systemc.h>
#include <iostream>

using namespace std;

#define WP_BUS_BUFF_DEP 32
#define WP_BUS_MEM_DEP  1024

enum AHB_BUS_SLAVE_TYPE {
 AHB_BUS_SLAVE_IDLE =0,
 AHB_BUS_SLAVE_NON =1,
 AHB_BUS_SLAVE_RD =2,
 AHB_BUS_SLAVE_WT =3,  
};

SC_MODULE(AHB_BUS_SLAVE) {
 sc_in<bool>  HSELx;
 sc_in<sc_uint<32> > HADDR;
 sc_in<bool>  HWRITE;
 sc_in<sc_uint<3> > HTRANS;
 sc_in<sc_uint<3> > HSIZE;
 sc_in<sc_uint<5> > HBURST;

 sc_in<sc_uint<32> > HWDATA;
 sc_in<bool>  HRESETn;
 sc_in<bool>  HCLK;
 sc_in<sc_uint<4> > HMASTER;
 sc_in<bool>  HMASTLOCK;

 sc_out<bool>  HREADY;
 sc_out<sc_uint<2> > HRESP;

 sc_out<sc_uint<32> > HRDATA;
 sc_out<sc_uint<16> > HSPLITx;   

        sc_signal<bool>  WP_BUS_MASTER_BUSY;
 sc_signal<bool>  WP_BUS_HREADY;
 sc_signal<sc_uint<32> > WP_BUS_HREADY_COT;
 sc_signal<sc_uint<2> > WP_BUS_HRESP;
 sc_signal<sc_uint<2> > WP_BUS_HRESP_COT;
 
 sc_signal<sc_uint<3> > WP_BUS_CUR_ST;
 sc_signal<sc_uint<3> > WP_BUS_NXT_ST;

 sc_signal<sc_uint<32> > WP_BUS_WT_HADDR_BUFF[WP_BUS_BUFF_DEP];
 sc_signal<sc_uint<32> > WP_BUS_WT_HDATA_BUFF[WP_BUS_BUFF_DEP];
 sc_signal<sc_uint<32> > WP_BUS_WT_HADDR_INX;
 sc_signal<sc_uint<32> > WP_BUS_WT_HDATA_INX;

 sc_signal<sc_uint<32> > WP_BUS_RD_HADDR_BUFF[WP_BUS_BUFF_DEP];
 sc_signal<sc_uint<32> > WP_BUS_RD_HDATA_BUFF[WP_BUS_BUFF_DEP];
 sc_signal<sc_uint<32> > WP_BUS_RD_HADDR_INX;
 sc_signal<sc_uint<32> > WP_BUS_RD_HDATA_INX;


 sc_signal<sc_uint<32> > WP_BUS_INT_MEM[WP_BUS_MEM_DEP];
 

 SC_CTOR(AHB_BUS_SLAVE){
 SC_METHOD(PRO_WP_BUS_ST);
 dont_initialize();
 sensitive << HRESETn;
 sensitive << HCLK.pos();

 SC_METHOD(PRO_WP_BUS_ST_DO);
 dont_initialize();
 sensitive << WP_BUS_CUR_ST;
 sensitive << HSELx;
 sensitive << HTRANS;
 sensitive << HWRITE;
 sensitive << WP_BUS_HRESP;
 sensitive << WP_BUS_RD_HDATA_INX;
 sensitive << WP_BUS_WT_HDATA_INX;
 sensitive << HBURST;

        SC_METHOD(PRO_WP_BUS_RSP);
 dont_initialize();
 sensitive << HCLK.pos();

        SC_METHOD(PRO_WP_BUS_WT);
 dont_initialize();
 sensitive << HCLK.pos();

        SC_METHOD(PRO_WP_BUS_RD);
 dont_initialize();
 sensitive << HCLK.pos();

 SC_METHOD(PRO_WP_BUS_MASTER_BUSY);
 dont_initialize();
 sensitive << HTRANS;

 SC_METHOD(PRO_WP_BUS_INT_MEM);
 dont_initialize();
 sensitive << WP_BUS_CUR_ST;

 AHB_BUS_SLAVE_VCD_DUMP();

 };

 void PRO_WP_BUS_ST();
 void PRO_WP_BUS_ST_DO();
 void   PRO_WP_BUS_RSP();


 void   PRO_WP_BUS_RD();
 void PRO_WP_BUS_WT();
 void   PRO_WP_BUS_MASTER_BUSY();
 void   PRO_WP_BUS_INT_MEM();
 void AHB_BUS_SLAVE_VCD_DUMP();
};


#include "AHB_BUS_SLAVE.h"
#include "AHB.h"

void AHB_BUS_SLAVE::PRO_WP_BUS_ST(){

 sc_uint<3> TMP_NXT_ST = ( HRESETn.read() == false ) ? AHB_BUS_SLAVE_IDLE : WP_BUS_NXT_ST.read();
 WP_BUS_CUR_ST.write(TMP_NXT_ST);
  
}


void AHB_BUS_SLAVE::PRO_WP_BUS_ST_DO(){

 sc_uint<3> TMP_CUR_ST = WP_BUS_CUR_ST.read();
 sc_uint<3> TMP_NXT_ST = WP_BUS_NXT_ST.read();

 switch(TMP_CUR_ST){
 case  AHB_BUS_SLAVE_IDLE : TMP_NXT_ST =   AHB_BUS_SLAVE_NON; break;
        case  AHB_BUS_SLAVE_NON  : TMP_NXT_ST = ( HSELx.read() == true && HTRANS.read()== AMBA_NONSEQ && HWRITE.read()== true )? AHB_BUS_SLAVE_WT : 
                                                ( HSELx.read() == true && HTRANS.read()== AMBA_NONSEQ && HWRITE.read()== false)? AHB_BUS_SLAVE_RD : AHB_BUS_SLAVE_NON;  break;
 case  AHB_BUS_SLAVE_RD   : TMP_NXT_ST = ( HSELx.read() == true && HWRITE.read()== false && WP_BUS_HRESP.read()  == AMBA_RETY )? AHB_BUS_SLAVE_NON :
                                                ( HSELx.read() == true && HWRITE.read()== false && WP_BUS_HRESP.read()  == AMBA_SPLIT)? AHB_BUS_SLAVE_NON :
                                                ( HSELx.read() == true && HWRITE.read()== false && WP_BUS_HRESP.read()  == AMBA_ERROR)? AHB_BUS_SLAVE_RD   :
                                                ( HSELx.read() == true && HWRITE.read()== false && 
                                                  WP_BUS_RD_HDATA_INX.read() == HBURST.read() )?      AHB_BUS_SLAVE_IDLE   :  AHB_BUS_SLAVE_RD; break; 
 case  AHB_BUS_SLAVE_WT   : TMP_NXT_ST = ( HSELx.read() == true && HWRITE.read()== true  && WP_BUS_HRESP.read()  == AMBA_RETY )? AHB_BUS_SLAVE_NON :
                                                ( HSELx.read() == true && HWRITE.read()== true  && WP_BUS_HRESP.read()  == AMBA_SPLIT)? AHB_BUS_SLAVE_NON :
                                                ( HSELx.read() == true && HWRITE.read()== true  && WP_BUS_HRESP.read()  == AMBA_ERROR)? AHB_BUS_SLAVE_WT   :
                                                ( HSELx.read() == true && HWRITE.read()== true  && 
                                                  WP_BUS_WT_HDATA_INX.read() == HBURST.read() )?      AHB_BUS_SLAVE_IDLE   :  AHB_BUS_SLAVE_WT; break; 
 }
 WP_BUS_NXT_ST.write(TMP_NXT_ST);
}

void AHB_BUS_SLAVE::PRO_WP_BUS_RSP(){
     sc_uint<32> TMP_HREADY_COT    = WP_BUS_HREADY_COT.read();
     sc_uint<32> TMP_HRESP_COT     = WP_BUS_HRESP_COT.read();
     sc_uint<32> TMP_CUR_ST        = WP_BUS_CUR_ST.read();
 
     ( (50  >= TMP_HREADY_COT && TMP_HREADY_COT >= 10 ) ||
       (100 >= TMP_HREADY_COT && TMP_HREADY_COT >= 60 ) ) ? WP_BUS_HREADY.write(true)   : WP_BUS_HREADY.write(false);

     ( (50  >= TMP_HREADY_COT && TMP_HREADY_COT >= 10 ) ||
       (100 >= TMP_HREADY_COT && TMP_HREADY_COT >= 60 ) ) ? HREADY.write(true)   : HREADY.write(false);
    
     if( (50  >= TMP_HREADY_COT && TMP_HREADY_COT >= 10 ) ||
         (100 >= TMP_HREADY_COT && TMP_HREADY_COT >= 60 ) ) { WP_BUS_HRESP.write(AMBA_OKAY);HRESP.write(AMBA_OKAY);  }
     else {
         ( TMP_HRESP_COT  == 0)? WP_BUS_HRESP.write(AMBA_RETY)  :
         ( TMP_HRESP_COT  == 1)? WP_BUS_HRESP.write(AMBA_SPLIT) :
         ( TMP_HRESP_COT  == 2)? WP_BUS_HRESP.write(AMBA_ERROR) : WP_BUS_HRESP.write(AMBA_ERROR);
   
         ( TMP_HRESP_COT  == 0)? HRESP.write(AMBA_RETY)  :
         ( TMP_HRESP_COT  == 1)? HRESP.write(AMBA_SPLIT) :
         ( TMP_HRESP_COT  == 2)? HRESP.write(AMBA_ERROR) : HRESP.write(AMBA_ERROR);
 
     }

     TMP_HRESP_COT  = ( TMP_CUR_ST == AHB_BUS_SLAVE_IDLE || TMP_HRESP_COT  == 2 )? 0 :
                      ( TMP_HREADY_COT ==100                                    )? TMP_HRESP_COT+1: TMP_HRESP_COT+0;
                                         
     TMP_HREADY_COT = ( TMP_CUR_ST == AHB_BUS_SLAVE_IDLE || TMP_HREADY_COT == 100 )? 0 : TMP_HREADY_COT +1; 

    WP_BUS_HREADY_COT.write(TMP_HREADY_COT); 
    WP_BUS_HRESP_COT.write(TMP_HRESP_COT);
}


void AHB_BUS_SLAVE::PRO_WP_BUS_MASTER_BUSY(){

      sc_uint<3> TMP_HTRANS = HTRANS.read();
        
       (TMP_HTRANS == AMBA_BUSY )? WP_BUS_MASTER_BUSY.write(true) : WP_BUS_MASTER_BUSY.write(false);
}


void AHB_BUS_SLAVE::PRO_WP_BUS_INT_MEM(){
     sc_uint<32> TMP_CUR_ST      = WP_BUS_CUR_ST.read();
    
   if(TMP_CUR_ST == AHB_BUS_SLAVE_IDLE){
       for(unsigned int i=0; i< WP_BUS_BUFF_DEP; i++ ){
          sc_uint<32> TMP_HADDR  = WP_BUS_WT_HADDR_BUFF[i].read();
          sc_uint<32> TMP_HDATA  = WP_BUS_WT_HDATA_BUFF[i].read();

   WP_BUS_INT_MEM[TMP_HADDR].write(TMP_HDATA);
      }
   } 

}


void AHB_BUS_SLAVE::PRO_WP_BUS_WT(){
     sc_uint<32> TMP_CUR_ST      = WP_BUS_CUR_ST.read();
     sc_uint<2>  TMP_HRESP       = WP_BUS_HRESP.read();      
     sc_uint<3>  TMP_HTRANS      = HTRANS.read();
     sc_uint<32> TMP_HADDR       = HADDR.read();
     sc_uint<32> TMP_HWDATA      = HWDATA.read();
     sc_uint<32> TMP_WT_HADDR_INX= WP_BUS_WT_HADDR_INX.read();
     sc_uint<32> TMP_WT_HDATA_INX= WP_BUS_WT_HDATA_INX.read();

     bool        TMP_HREADY      = WP_BUS_HREADY.read();
     bool        TMP_MASTER_BUSY = WP_BUS_MASTER_BUSY.read();
     bool        TMP_HWRITE      = HWRITE.read();
 
    TMP_WT_HADDR_INX =  (TMP_CUR_ST == AHB_BUS_SLAVE_IDLE || TMP_CUR_ST == AHB_BUS_SLAVE_NON ) ? 0 : TMP_WT_HADDR_INX+0;
    TMP_WT_HDATA_INX =  (TMP_CUR_ST == AHB_BUS_SLAVE_IDLE || TMP_CUR_ST == AHB_BUS_SLAVE_NON ) ? 0 : TMP_WT_HDATA_INX+0;
  
   if( (TMP_HTRANS == AMBA_NONSEQ || TMP_HTRANS == AMBA_SEQ ) && TMP_HREADY == true && TMP_HRESP == AMBA_OKAY && TMP_MASTER_BUSY==false && TMP_HWRITE ==true){
        TMP_HADDR = TMP_HADDR - WP_BUS_SLAVE_0; 
        WP_BUS_WT_HADDR_BUFF[TMP_WT_HADDR_INX++].write(TMP_HADDR);
    }
 
    if( TMP_HTRANS == AMBA_SEQ && TMP_HREADY == true && TMP_HRESP == AMBA_OKAY && TMP_MASTER_BUSY==false && TMP_HWRITE == true){
       WP_BUS_WT_HDATA_BUFF[TMP_WT_HDATA_INX++].write(TMP_HWDATA);
    }

  WP_BUS_WT_HADDR_INX.write(TMP_WT_HADDR_INX);
  WP_BUS_WT_HDATA_INX.write(TMP_WT_HDATA_INX);

}

void AHB_BUS_SLAVE::PRO_WP_BUS_RD(){
     sc_uint<32> TMP_CUR_ST      = WP_BUS_CUR_ST.read();
     sc_uint<2>  TMP_HRESP       = WP_BUS_HRESP.read();      
     sc_uint<3>  TMP_HTRANS      = HTRANS.read();
     sc_uint<32> TMP_HADDR       = HADDR.read();
     sc_uint<32> TMP_RD_HADDR_INX= WP_BUS_RD_HADDR_INX.read();
     sc_uint<32> TMP_RD_HDATA_INX= WP_BUS_RD_HDATA_INX.read();

     bool        TMP_HREADY      = WP_BUS_HREADY.read();
     bool        TMP_MASTER_BUSY = WP_BUS_MASTER_BUSY.read();
     bool        TMP_HWRITE      = HWRITE.read(); 
 
    TMP_RD_HADDR_INX =  (TMP_CUR_ST == AHB_BUS_SLAVE_IDLE || TMP_CUR_ST == AHB_BUS_SLAVE_NON ) ? 0 : TMP_RD_HADDR_INX+0;
    TMP_RD_HDATA_INX =  (TMP_CUR_ST == AHB_BUS_SLAVE_IDLE || TMP_CUR_ST == AHB_BUS_SLAVE_NON ) ? 0 : TMP_RD_HDATA_INX+0;
  
   if( (TMP_HTRANS == AMBA_NONSEQ || TMP_HTRANS == AMBA_SEQ ) && TMP_HREADY == true && TMP_HRESP == AMBA_OKAY && TMP_MASTER_BUSY==false && TMP_HWRITE==false){
        TMP_HADDR = TMP_HADDR - WP_BUS_SLAVE_0;
        WP_BUS_RD_HADDR_BUFF[TMP_RD_HADDR_INX++].write(TMP_HADDR); 
      }
 
    if( TMP_HTRANS == AMBA_SEQ && TMP_HREADY == true && TMP_HRESP == AMBA_OKAY && TMP_MASTER_BUSY==false && TMP_HWRITE==false){
        TMP_HADDR = WP_BUS_RD_HADDR_BUFF[TMP_RD_HDATA_INX++].read();
        sc_uint<32> TMP_HRDATA = WP_BUS_INT_MEM[TMP_HADDR].read();
       
        HRDATA.write(TMP_HRDATA);

    }

  WP_BUS_RD_HADDR_INX.write(TMP_RD_HADDR_INX);
  WP_BUS_RD_HDATA_INX.write(TMP_RD_HDATA_INX);

}


void AHB_BUS_SLAVE::AHB_BUS_SLAVE_VCD_DUMP(){
sc_trace_file *fp = sc_create_vcd_trace_file("AHB_BUS_SLAVE");
((vcd_trace_file*)fp)->sc_set_vcd_time_unit(-9);


sc_trace(fp, HSELx,"HSELx");
sc_trace(fp, HADDR,"HADDR");
sc_trace(fp, HWRITE,"HWRITE");
sc_trace(fp, HTRANS,"HTRANS");
sc_trace(fp, HSIZE,"HSIZE");
sc_trace(fp, HBURST,"HBURST");

sc_trace(fp, HWDATA,"HWDATA");
sc_trace(fp, HRESETn,"HRESETn");
sc_trace(fp, HCLK,"HCLK");
sc_trace(fp, HMASTER,"HMASTER");
sc_trace(fp, HMASTLOCK,"HMASTLOCK");

sc_trace(fp, HREADY,"HREADY");
sc_trace(fp, HRESP,"HRESP");

sc_trace(fp, HRDATA,"HRDATA");
sc_trace(fp, HSPLITx,"HSPLITx");   

sc_trace(fp, WP_BUS_HREADY,"WP_BUS_HREADY");
sc_trace(fp, WP_BUS_HREADY_COT,"WP_BUS_HREADY_COT");
sc_trace(fp, WP_BUS_HRESP,"WP_BUS_HRESP");
sc_trace(fp, WP_BUS_HRESP_COT,"WP_BUS_HRESP_COT");

sc_trace(fp, WP_BUS_CUR_ST,"WP_BUS_CUR_ST");
sc_trace(fp, WP_BUS_NXT_ST,"WP_BUS_NXT_ST");

sc_trace(fp, WP_BUS_WT_HADDR_BUFF[0],"WP_BUS_WT_HADDR_BUFF_0");
sc_trace(fp, WP_BUS_WT_HADDR_BUFF[1],"WP_BUS_WT_HADDR_BUFF_1");
sc_trace(fp, WP_BUS_WT_HADDR_BUFF[2],"WP_BUS_WT_HADDR_BUFF_2");

sc_trace(fp, WP_BUS_WT_HDATA_BUFF[0],"WP_BUS_WT_HDATA_BUFF_0");
sc_trace(fp, WP_BUS_WT_HDATA_BUFF[1],"WP_BUS_WT_HDATA_BUFF_1");
sc_trace(fp, WP_BUS_WT_HDATA_BUFF[2],"WP_BUS_WT_HDATA_BUFF_2");

sc_trace(fp, WP_BUS_WT_HADDR_INX,"WP_BUS_WT_HADDR_INX");
sc_trace(fp, WP_BUS_WT_HDATA_INX,"WP_BUS_WT_HDATA_INX");

sc_trace(fp, WP_BUS_RD_HADDR_BUFF[0],"WP_BUS_RD_HADDR_BUFF_0");
sc_trace(fp, WP_BUS_RD_HADDR_BUFF[1],"WP_BUS_RD_HADDR_BUFF_1");
sc_trace(fp, WP_BUS_RD_HADDR_BUFF[2],"WP_BUS_RD_HADDR_BUFF_2");

sc_trace(fp, WP_BUS_RD_HDATA_BUFF[0],"WP_BUS_RD_HDATA_BUFF_0");
sc_trace(fp, WP_BUS_RD_HDATA_BUFF[1],"WP_BUS_RD_HDATA_BUFF_1");
sc_trace(fp, WP_BUS_RD_HDATA_BUFF[2],"WP_BUS_RD_HDATA_BUFF_2");

sc_trace(fp, WP_BUS_RD_HADDR_INX,"WP_BUS_RD_HADDR_INX");
sc_trace(fp, WP_BUS_RD_HDATA_INX,"WP_BUS_RD_HDATA_INX");


}

沒有留言:

張貼留言