NVMain运行机制深入了解之八

地址翻译是每个部件的核心,也是NVMain每个模块的关键部分,这个部分一般情况下是通过ADDCHILD继承得来的,下面我分析一下地址翻译的核心部件。

在nvmain的现有版本中,工厂类按照配置选项,动态从三个可以使用的地址翻译子类中选择,分别是DRCDecoder,Migrator,以及AddressTranslator.


这里从最简单的AddressTranslator.开始,下面贴出它的定义

class AddressTranslator
{
  public:
    AddressTranslator( );
    virtual ~AddressTranslator( );

    virtual void SetConfig( Config * /*config*/, bool /*createChildren*/ = true ) { }

    void SetBusWidth( int );
    void SetBurstLength( int );
    void SetTranslationMethod( TranslationMethod *m );
    TranslationMethod *GetTranslationMethod( );
    
    virtual void Translate( uint64_t address, uint64_t *row, uint64_t *col, uint64_t *bank, 
                            uint64_t *rank, uint64_t *channel, uint64_t *subarray );
    virtual void Translate( NVMainRequest *request, uint64_t *row, uint64_t *col, uint64_t *bank, 
                            uint64_t *rank, uint64_t *channel, uint64_t *subarray );

    virtual uint64_t ReverseTranslate( const uint64_t& row, const uint64_t& col, 
                                       const uint64_t& bank, const uint64_t& rank, 
                                       const uint64_t& channel, const uint64_t& subarray );

    virtual uint64_t Translate( uint64_t address );
    virtual uint64_t Translate( NVMainRequest *request );
    virtual void SetDefaultField( TranslationField f ); 

    void SetStats( Stats *stats );
    Stats *GetStats( );

    void StatName( std::string name );
    std::string StatName( );

    virtual void RegisterStats( ) { } 
    virtual void CalculateStats( ) { }

    virtual void CreateCheckpoint( std::string /*dir*/ ) { }
    virtual void RestoreCheckpoint( std::string /*dir*/ ) { }

  private:
    TranslationMethod *method;
    TranslationField defaultField;
    int busWidth;
    int burstLength;
    int lowColBits;

    Stats *stats;
    std::string statName;

  protected:
    uint64_t Divide( uint64_t partSize, MemoryPartition partition );
    uint64_t Modulo( uint64_t partialAddr, MemoryPartition partition );
    void FindOrder( int order, MemoryPartition *p );
};


其中我们比较关心的就是

void AddressTranslator::Translate( uint64_t address, uint64_t *row, uint64_t *col, uint64_t *bank,
  uint64_t *rank, uint64_t *channel, uint64_t *subarray )

这个函数,它的核心是下面的一个循环

  for( int i = 0; i < 6; i++ )
    {
        FindOrder( i, &part );

        /* 
         *  The new memsize does not include this partition, so dividing by the
         *  new memsize will give us the right channel/rank/bank/whatever.
         */
        *partitions[part] = Modulo( refAddress, part );

        /*
         *  "Mask off" the first partition number we got. For example if memsize = 1000
         *  and the address is 8343, the partition would be 8, and we will look at 343 
         *  to determine the rest of the address now.
         */
        refAddress = Divide( refAddress, part );
    }

我们来分析一次循环调用的具体过程。

首先FindOrder,按照配置文件中地址中各个部件地址的排列顺序【例如:R:RK:BK:CH:C】 【阅读顺序从右至左】

找到第一个出现的是Col, 那么在FindOrder就把part这个枚举变量设置位Col

然后,partitions[part] = Modulo( refAddress, part );

partitions的【part】得到了COL部分的具体数值。

最后,因为COL部分已经被解析出来,调用

refAddress = Divide( refAddress, part );
让地址右移。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值