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

Subversion Repositories hssdrc

[/] [hssdrc/] [trunk/] [testbench/] [tb_prog.sv] - Rev 2

Go to most recent revision | 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     : tb_prog.sv
// 
// Description  : testbench program for all cases
// 
// 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_timescale.vh"
`include "hssdrc_define.vh"
`include "hssdrc_timing.vh"
`include "tb_define.svh"

`include "message_class.sv"

`include "hssdrc_driver_class.sv"
`include "hssrdc_bandwidth_monitor_class.sv"
`include "hssrdc_scoreboard_class.sv"

`include "sdram_transaction_class.sv"

`include "sdram_tread_class.sv"
`include "sdram_agent_class.sv"

program tb_prog (interface sys_if);

  // agent <-> driver mailbox
  sdram_tr_mbx      agent2drv_mbx;
  sdram_tr_ack_mbx  drv2agent_mbx;

  // message service
  message_class msg;

  // test program -> agent mailbox
  sdram_tr_mbx agent_write_mbx;
  sdram_tr_mbx agent_read_mbx;

  // transaction agent class
  sdram_agent_class   agent;

  // virtual sdram treads
  sdram_tread_class   tread;

  // driver to uut
  hssrdc_driver_class             driver;

  // driver callbacks
  hssdrc_bandwidth_monitor_class  bandwidth_mon;
  hssdrc_scoreboard_class         scoreboard;

  event scoreboard_event;
  event bandwidth_mon_event; 

  initial begin

    agent2drv_mbx     = new (8);
    drv2agent_mbx     = new (8);

    agent_write_mbx   = new (8);
    agent_read_mbx    = new (8);

    // init objects
    msg           = new ("tb_hssdrc.log");

    driver        = new (sys_if, agent2drv_mbx, drv2agent_mbx);

    agent         = new (agent2drv_mbx, drv2agent_mbx, agent_write_mbx, agent_read_mbx);

    tread         = new ;

    bandwidth_mon = new (sys_if, bandwidth_mon_event);

    scoreboard    = new (msg, scoreboard_event);

    driver.run();

    agent.run_write_read ();

    // calibrate bandwidth monitor 
    
    bandwidth_mon.count_mbps_mfactor(1000);

    // disable debug process inside sdram model

    force tb_top.sdram_chip.Debug = 0;

    wait (sys_if.reset == 1'b0);

    wait (sys_if.cb.ready == 1'b1);

    msg.note ("Program start");

`ifdef HSSDRC_NOT_SHARE_ACT_COMMAND
    msg.note ("Controller use HSSDRC_NOT_SHARE_ACT_COMMAND macros");
`endif 

`ifdef HSSDRC_SHARE_ONE_DECODER
    msg.note ("Controller use HSSDRC_SHARE_ONE_DECODER macros");
`endif 

`ifdef HSSDRC_SHARE_NONE_DECODER
    msg.note ("Controller use HSSDRC_SHARE_NONE_DECODER macros");
`endif 

    //test(-1,-1); // simple_debug_test
    //test(0,0);   // linear_test
    test(1,1);   // random_test 
    //test(2,2);   // bandwidth_measurement 

    agent.stop_write_read();

    driver.stop();

    msg.stop();

    $stop;
    $finish (2);

  end

  //
  // 
  //

  task test (input int start_task, end_task);
    int task_num;

    sdram_transaction_class write_tr;
    sdram_transaction_class read_tr;

    sdram_transaction_class rand_tr;
    sdram_transaction_class tr;

    int err;

    int         tr_burst;
    tr_type_e_t tr_type;
    int         tr_id;
    int         tr_chid;
    int         tr_num;

    bit tread_end;
    int next_cola;

    sdram_tread_state_s_t tread_state;  // selected tread state
    int                   tread_num;    // selected tread num

    string log_str;
  begin

    for (task_num = start_task; task_num <= end_task; task_num++)
    begin
      //
      // Task -1 : manualy checking write/read transactions 
      // 
      if (task_num == -1) begin : simple_debug_test

        msg.note ($psprintf("test %0d : simple debug test", task_num));

        //
        // test for debug only 
        // 

        tr = new (0, cTR_WRITE_LOCKED, .ba(0), .rowa(0), .cola(0), .burst(3));
        tr.GetLinearPacket();          
        agent.SetTransaction(tr); 
        
        tr = new (0, cTR_WRITE_LOCKED, .ba(0), .rowa(0), .cola(0), .burst(4));
        tr.GetLinearPacket();          
        agent.SetTransaction(tr); 

        tr = new (0, cTR_READ_LOCKED, .ba(0), .rowa(0), .cola(0), .burst(4), .chid(1));
        tr.GetLinearPacket();          
        agent.SetTransaction(tr); 
        
//      tr = new (0, cTR_READ, .ba(0), .rowa(1), .cola(0), .burst(2));
//      tr.GetLinearPacket();
//      agent.SetTransaction(tr);

        tr = new (0, cTR_REFR_LOCKED, .ba(0), .rowa(0));
        agent.SetTransaction(tr); 

        repeat (10) @(sys_if.cb);
      end : simple_debug_test

      //
      // Task 0 : linear write -> read with linear data (random burst only)
      //

      else if (task_num == 0) begin : linear_test

        msg.note ($psprintf("test %0d : linear write -> read with linear data", task_num));

        //
        // test for correctness. set scoreboard callbacks
        //

        driver.cbs = {};
        scoreboard.start();
        driver.cbs.push_back(scoreboard);

        driver.random_delay_mode = 1;
        //
        // transaction generator
        //

        tread.Init();

        msg.note ($psprintf("test %0d start_task with number of treads is %0d", task_num, tread.active_tread_state.num()));

        for (tread_num = 0; tread_num < tread.active_tread_state.num(); tread_num++) begin

          //
          // get tread state
          //

          tread_state = tread.active_tread_state [tread_num];

          msg.note ($psprintf("start tread %0d" , tread_num));

          //
          // full tread transaction
          //

          tr_num = 0;

          do begin
            //
            // generate transaction
            //
            tr_id     = tread_num;
            tr_type   = cTR_WRITE;
            tr_burst  = tread.GetBurst (tread_state);
            tr_chid   = tread_state.ba;

            write_tr = new (tr_id, tr_type, tread_state.ba, tread_state.rowa, tread_state.cola, tr_burst, tr_chid);
            write_tr.GetLinearPacket();

            read_tr = new write_tr;
            read_tr.tr_type = cTR_READ;
            //
            // set transaction
            //
            #10;
            agent_write_mbx.put (write_tr);
            #10;
            agent_read_mbx.put  (read_tr);
            //
            // update tread state
            //
            tr_num++;

            next_cola = tread_state.cola + tr_burst;

            tread_end = (next_cola >= cColaMaxValue);

            tread_state.cola = next_cola;

          end
          while (tread_end != 1);

          msg.note ($psprintf("done tread %0d. number of tread transactions %0d", tread_num, tr_num));

        end

        //
        // wait compare done
        //

        do
          @(scoreboard_event);
        while (agent.read_tr_done_num != scoreboard.checked_tr_num);

        msg.note ($psprintf("test%0d done. Number of errors = %0d", task_num, scoreboard.check_err_num));

      end : linear_test

      //
      // Task 1 : random write -> read with random data, rowa, ba, burst, linear cola 
      //

      else if (task_num == 1) begin : random_test

        msg.note ($psprintf("test %0d : random write -> read with random data", task_num));

        //
        // test for correctness. set scoreboard callbacks
        //

        driver.cbs = {};
        scoreboard.start();
        driver.cbs.push_back(scoreboard);

        driver.random_delay_mode = 1;

        //
        // transaction generator
        //

        tread.Init();

        msg.note ($psprintf("test %0d start_task with number of treads is %0d", task_num, tread.active_tread_state.num()));

        tr_num = 0;

        do begin

          //
          // select tread
          //

          assert (tread.randomize()) else $error ("generate tread selection error");

          tread_num   = tread.curr_tread_num;

          tread_state = tread.active_tread_state [tread_num];

          //
          // generate transaction
          //

          tr_burst  = tread.GetBurst (tread_state);
          tr_type   = cTR_WRITE;
          tr_id     = tread_num;
          tr_chid   = tread_state.ba;

          write_tr = new (tr_id, tr_type, tread_state.ba, tread_state.rowa, tread_state.cola, tr_burst, tr_chid);
          //write_tr.GetLinearPacket();
          write_tr.GetRandomPacket();

          read_tr = new write_tr;
          read_tr.tr_type = cTR_READ;
          //
          // set transaction
          //
          #10;
          agent_write_mbx.put (write_tr);
          #10;
          agent_read_mbx.put  (read_tr);
          //
          // update tread state
          //
          tr_num++;

          next_cola = tread_state.cola + tr_burst;

          tread_end = (next_cola >= cColaMaxValue);

          tread_state.cola = next_cola;

          tread.active_tread_state [tread_num] = tread_state;
          //
          // if tread end kill it
          //
          if (tread_end) begin
            tread.active_tread_state.delete   (tread_num);
            tread.disable_tread_num.push_back (tread_num);  // random pointer constrain update
            msg.note ($psprintf("done tread %0d", tread_num));
          end

          if (tr_num > cTransactionMaxValue) break;

          if (tr_num % cTransactionLogPeriod == 0)
            msg.note($psprintf("transaction done %0d", tr_num));

        end
        while (tread.active_tread_state.num() != 0);

        //
        // wait compare done
        //

        do
          @(scoreboard_event);
        while (agent.read_tr_done_num != scoreboard.checked_tr_num);

        msg.note ($psprintf("test%0d done. Number of errors = %0d", task_num, scoreboard.check_err_num));

      end : random_test

      //
      // Task 2 : bandwidth measurement 
      //

      else if (task_num == 2) begin : bandwidth_measurement 

        msg.note ($psprintf("test %0d : access bandwidth measurement", task_num));

        //
        // test for perfromance. set bandwidth monitor callbacks, no random delay mode 
        //

        driver.cbs = {};        
        driver.cbs.push_back(bandwidth_mon);

        driver.random_delay_mode = 0;

        //
        // generate transactions
        // 
        foreach ( test_mode [t] ) begin : test_mode_cycle

          msg.note ($psprintf("test %0d start %0s test mode", task_num, test_mode_name[test_mode[t]]));

          foreach (burst_mode [b]) begin : burst_cycle

            foreach (address_mode [a] ) begin : address_cycle 
          
              time start_time; 
              string str; 

              tr_num = 0; 
              start_time = $time;

              //
              // init tr.generator 
              // 

              rand_tr = new;
              rand_tr.burst_random_mode   = burst_mode [b];
              rand_tr.address_random_mode = address_mode [a];

              bandwidth_mon.start();

              do begin 

                assert ( rand_tr.randomize() ) else begin 
                  $error("test %0d : random transaction generate error", task_num);                  
                  $stop; 
                end 

                if ( test_mode[t].write_mode) begin 
                  write_tr          = new rand_tr; 
                  write_tr.id       = tr_num++;
                  write_tr.tr_type  = cTR_WRITE;

                  agent.SetTransaction(write_tr);
                end 

                if ( test_mode[t].read_mode) begin 
                  read_tr         = new rand_tr;
                  read_tr.id      = tr_num++;
                  read_tr.tr_type = cTR_READ;

                  agent.SetTransaction(read_tr);
                end 

                if (tr_num % cTransactionLogPeriod == 0)
                  msg.note($psprintf("task %0d transaction done %0d", task_num, tr_num));

              end 
              while (($time - start_time) < cPerfomanceInterval);

              //
              // syncronize output for measure
              // 
              do 
                @(bandwidth_mon_event); 
              while (tr_num != bandwidth_mon.measured_tr_num); 

              //
              // stop measure 
              //
              bandwidth_mon.stop();

              //
              // logs 
              // 

              str = $psprintf("task %0d done. %0s mode bandwith : %0s and %0s is :\n", task_num, 
                test_mode_name[test_mode[t]], address_mode_name [address_mode[a]], burst_mode_name [burst_mode[b]]);

              if (test_mode [t].write_mode)
                str = {str, $psprintf("\t\twrite bandwidth %0f MBps, %0f %% maximum ram bandwidth\n", 
                  bandwidth_mon.write_bandwidth, bandwidth_mon.write_bandwidth_percent)};

              if (test_mode [t].read_mode) 
                str = {str, $psprintf("\t\t read bandwidth %0f MBps, %0f %% maximum ram bandwidth\n", 
                  bandwidth_mon.read_bandwidth, bandwidth_mon.read_bandwidth_percent)};

              if (test_mode [t].read_mode & test_mode [t].write_mode) 
                str = {str, $psprintf("\t\tram bandwidth %0f MBps, %0f %% maximum ram bandwidth\n", 
                  bandwidth_mon.bandwidth, bandwidth_mon.bandwidth_percent)};

              msg.note(str); 
              
            end : address_cycle 

          end : burst_cycle 

        end : test_mode_cycle

        
      end : bandwidth_measurement

    end

    msg.note ("all test done");

    repeat (100) @(sys_if.cb);
  end

  endtask



endprogram 

Go to most recent revision | 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.