OpenCores
URL https://opencores.org/ocsvn/hssdrc/hssdrc/trunk

Subversion Repositories hssdrc

[/] [hssdrc/] [trunk/] [testbench/] [hssdrc_driver_class.sv] - Rev 3

Compare with Previous | Blame | View Log

//
// Project      : High-Speed SDRAM Controller with adaptive bank management and command pipeline
// 
// Project Nick : HSSDRC
// 
// Version      : 1.0-beta 
//  
// Revision     : $Revision: 1.1 $ 
// 
// Date         : $Date: 2008-03-06 13:54:00 $ 
// 
// Workfile     : hssdrc_driver_class.sv
// 
// Description  : low level API driver for hssdrc_controller
// 
// HSSDRC is licensed under MIT License
// 
// Copyright (c) 2007-2008, Denis V.Shekhalev (des00@opencores.org) 
// 
// Permission  is hereby granted, free of charge, to any person obtaining a copy of
// this  software  and  associated documentation files (the "Software"), to deal in
// the  Software  without  restriction,  including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the  Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// 
// The  above  copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// 
// THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR  A  PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT  HOLDERS  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN  AN  ACTION  OF  CONTRACT,  TORT  OR  OTHERWISE,  ARISING  FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//



`include "hssdrc_tb_sys_if.vh"

`include "hssdrc_define.vh"

`include "tb_define.svh"

`include "hssrdc_driver_cbs_class.sv"

`ifndef __HSSDRC_DRIVER_SV__

  `define __HSSDRC_DRIVER_SV__

  class hssrdc_driver_class; 
  
    // callback quene 
    hssrdc_driver_cbs_class cbs[$];
  
    // mailboxes to connect with transaction agent
    sdram_tr_mbx in_mbx; 
  
    // mailbox for connect command path with data path of this driver   
    sdram_tr_mbx wdata_mbx;
    sdram_tr_mbx rdata_mbx; 
  
    // 
    virtual hssdrc_tb_sys_if sys_if;
  
    // acknowledge mailbox for agent. used in locked transaction only 
    sdram_tr_ack_mbx done_mbx; 

    // feedback to tb for waiting event 
    event write_done; 
    event read_done; 

    // driver work modes 
    bit random_delay_mode = 0;
    bit debug             = 0;

    //
    //
    //

    function new (virtual hssdrc_tb_sys_if sys_if,  sdram_tr_mbx in_mbx, sdram_tr_ack_mbx done_mbx);
  
      this.sys_if   = sys_if;
  
      this.in_mbx   = in_mbx;
  
      this.done_mbx = done_mbx;
  
      // internal not sized mailboxes : all must be controlled via in_mbx, out_mbx size
      wdata_mbx = new; 
      rdata_mbx = new;
      
    endfunction
  
    //
    // init interface task 
    //

    task init; 
      sys_if.cb.write   <= 1'b0;
      sys_if.cb.read    <= 1'b0;
      sys_if.cb.refr    <= 1'b0; 
      sys_if.cb.cola    <= '0;
      sys_if.cb.rowa    <= '0;
      sys_if.cb.ba      <= '0;
      sys_if.cb.chid_i  <= '0;
      sys_if.cb.burst   <= '0;
      sys_if.cb.wdata   <= '0;
      sys_if.cb.wdatam  <= '0;    
    endtask

    //
    // start driver task 
    // 

    task run; 
      init ();
      fork 
        CommandDriver   (); 
        WriteDataDriver (); 
        ReadDataDriver  ();
      join_none; 
    endtask

    //
    // stop driver task 
    // 

    task stop (); 
      disable this.CommandDriver;
      disable this.WriteDataDriver;
      disable this.ReadDataDriver;
    endtask

    //-----------------------------------------------------------------------
    // command driver 
    //-----------------------------------------------------------------------

    task CommandDriver; 
      sdram_transaction_class tr; 
  
      bit [4:0] delay;  // max delay is 32 bit 
      
    begin     
  
      @(sys_if.cb); 
      forever begin
  
        // syncronize mailbox to clock 
        if ( !in_mbx.try_get(tr) ) begin 
          @(sys_if.cb); 
          continue;
        end 
  
        if (debug) begin 
          if ((tr.tr_type == cTR_READ) || (tr.tr_type == cTR_READ_LOCKED)) 
            $display("%0t cmd get READ transaction id = %0d", $time, tr.id);
          else if ((tr.tr_type == cTR_WRITE) || (tr.tr_type == cTR_WRITE_LOCKED))
            $display("%0t cmd get WRITE transaction id = %0d", $time, tr.id);
        end  
  
        if (random_delay_mode) begin
          assert (std::randomize(delay) with {delay dist {0 := 1, !0 :/ 2};}) else 
            $error ("random delay generate error");
          
          repeat (delay) @(sys_if.cb);
        end
        
        
        // set command on interface
        SetCommand(tr);
  
        // if need callbacks
        foreach ( cbs [i] ) cbs[i].post_Command ($realtime);
  
        // set command for write/read drivers
        case (tr.tr_type)
          cTR_WRITE, cTR_WRITE_LOCKED : wdata_mbx.put (tr);
          cTR_READ , cTR_READ_LOCKED  : rdata_mbx.put (tr);
        endcase
  
        // for locked transactions wait done and set acknowledge
        case (tr.tr_type)
          cTR_WRITE_LOCKED : begin
            @(write_done);
            done_mbx.put (cTR_WRITE_LOCKED);
          end
          cTR_READ_LOCKED  : begin
            @(read_done);
            done_mbx.put(cTR_READ_LOCKED);
          end
          cTR_REFR_LOCKED : begin
            done_mbx.put (cTR_WRITE_LOCKED);
          end
        endcase
  
      end
    end 
    endtask
  
    //
    //
    //
  
    task SetCommand (sdram_transaction_class tr); 
  
      case (tr.tr_type)
        cTR_WRITE, cTR_WRITE_LOCKED : begin 
          sys_if.cb.write <= 1'b1;
          sys_if.cb.read  <= 1'b0;
          sys_if.cb.refr  <= 1'b0;
        end 
        cTR_READ,  cTR_READ_LOCKED  : begin 
          sys_if.cb.write <= 1'b0;
          sys_if.cb.read  <= 1'b1;
          sys_if.cb.refr  <= 1'b0;
        end 
        cTR_REFR,  cTR_REFR_LOCKED  : begin 
          sys_if.cb.write <= 1'b0;
          sys_if.cb.read  <= 1'b0;
          sys_if.cb.refr  <= 1'b1;
        end 
      endcase
  
      sys_if.cb.rowa    <= tr.rowa;
      sys_if.cb.cola    <= tr.cola;
      sys_if.cb.ba      <= tr.ba;
      sys_if.cb.burst   <= tr.burst;
      sys_if.cb.chid_i  <= tr.chid;
     
      do
        @(sys_if.cb);
      while (sys_if.cb.ready != 1'b1);
  
      sys_if.cb.write <= 1'b0;
      sys_if.cb.read  <= 1'b0;
      sys_if.cb.refr  <= 1'b0;
  
    endtask 
  
    //-----------------------------------------------------------------------
    // write data  driver 
    //-----------------------------------------------------------------------

    task WriteDataDriver; 
  
      sdram_transaction_class tr; 
      int num;    
  
    begin 
  
      forever begin
        wdata_mbx.get (tr);
  
        if (debug) 
          $display("%0t write driver get transaction id = %0d", $time, tr.id);
  
        num = tr.burst + 1;
  
        // set data
        for (int i = 0; i < num; i++) 
          SetWrData (tr.wdata [i] , tr.wdatam [i]);        
  
        -> write_done;
  
        if (debug) 
          $display("%0t write driver done transaction id = %0d", $time, tr.id);
  
        foreach ( cbs[i] ) cbs[i].post_WriteData($realtime, tr);
  
      end
    end 
    endtask

    //
    //
    //
`ifndef HSSDRC_COMBINATIVE_USE_WDATA
    task SetWrData ( input data_t data, datam_t datam); 
      sys_if.cb.wdata   <= data;
      sys_if.cb.wdatam  <= datam;
  
      do
        @(sys_if.cb);
      while (sys_if.cb.use_wdata != 1'b1);
    endtask
`else 
    task SetWrData ( input data_t data, datam_t datam); 
      do
        @(sys_if.cb);
      while (sys_if.cb.use_wdata != 1'b1);

      sys_if.cb.wdata   <= data;
      sys_if.cb.wdatam  <= datam;  
    endtask
`endif 
    //-----------------------------------------------------------------------
    // read part of  driver 
    //-----------------------------------------------------------------------

    task ReadDataDriver;
  
      sdram_transaction_class tr;
      int num;
  
    begin
      forever begin
        rdata_mbx.get (tr);
  
        if (debug) 
          $display("%0t read driver get transaction id = %0d", $time, tr.id);
  
        num = tr.burst + 1;
  
        for (int i = 0; i < num; i++)
            GetRdData (tr.rdata [i], tr.rchid [i]);
  
        -> read_done;
  
        if (debug) 
          $display("%0t read driver done transaction id = %0d", $time, tr.id);
  
        foreach ( cbs[i] ) cbs[i].post_ReadData($realtime, tr);
  
      end
    end
    endtask

    //
    //
    //

    task GetRdData (output data_t data, chid_t chid);
  
      do
        @(sys_if.cb);
      while (sys_if.cb.vld_rdata != 1'b1);
  
      data = sys_if.cb.rdata;
      chid = sys_if.cb.chid_o;
  
    endtask
  
    //
    //
    //
    
  endclass 

`endif 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.