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

Subversion Repositories funbase_ip_library

[/] [funbase_ip_library/] [trunk/] [TUT/] [ip.hwp.communication/] [hibi/] [3.0/] [tb/] [sad_tb/] [stimuli.hh] - Rev 145

Compare with Previous | Blame | View Log

/*
 * Author: Lasse Lehtonen
 *
 * Stimuli creation for hibi
 * 
 *
 * $Id: stimuli.hh 2008 2011-10-06 13:49:53Z ege $
 *
 *
 * Most of the commands use agent position in the vector as the source
 * and destination (0-11 if you have 12 agents, which are not same as
 * wrapper ids!). Conf read commands need the receiving wrapper's id.
 * 
 * 
 *
 *
 *
 *
 *
 */

#ifndef SAD_HIBI_STIMULI_HH
#define SAD_HIBI_STIMULI_HH

#include "constants.hh"
#include "top_level.hh"
#include "packet.hh"

#include <iostream>
#include <vector>
using namespace std;

#include <systemc>
using namespace sc_core;
using namespace sc_dt;


class Stimuli : public sc_module
{
public:

   SC_HAS_PROCESS(Stimuli);

   //* Constructor, launch the main thread
   Stimuli(sc_module_name name, TopLevel& toplevel)
      : sc_module(name),
        _top(toplevel)
   {
      for(int i = 0; i < n_agents_c; ++i)
      {
         _lastAddress[i] = addresses_c[i];
      }

      SC_THREAD(thread);
   }

   //* Destructor
   ~Stimuli()
   {

   }


   //* Main stimuli creation thread that orchestrates everythingys
   void thread()
   {     
      wait(42, SC_NS);

      cout << endl << "SAD HIBI TESTBENCH STARTING" << endl << endl;

      wait(58, SC_NS);
      _top.setResetN(true); // Release reset


      /*

      for(unsigned int a = 0; a < 4; ++a)
      {
         setRxBusyChance(a, 50);
      }

      for(unsigned int i = 0; i < 625; ++i)
      {
         for(unsigned int a = 0; a < 4; ++a)
         {
            writeNpData(16, a, 3-a, true);
         }
      }
      
      waitAllPacketsReceived(sc_time(10, SC_MS));

      */

      

      // 1. two packets from agent 0 to 1 
      cout << "Phase 1. Write" << endl;
      wait(1, SC_US);
      writeNpData(4, 0, 1);      // #words, source, destination
      wait(100, SC_NS);
      writeNpData(6, 2, 1);
      
      // Wait that all sent packets packet reach their destinations (timeout)
      waitAllPacketsReceived(sc_time(100, SC_US));


      // 2. Now, agent 1 is busy with 80% chance (per clock cycle)
      cout << "Phase 2. Write but receiver partly busy" << endl;
      setRxBusyChance(1, 80);

      // and two packets again and wait that they are received
      writeNpData(8, 0, 1);
      wait(100, SC_NS);
      writeNpData(16, 2, 1);      
      waitAllPacketsReceived(sc_time(100, SC_US));



      // 3. Send lots of small packets to one target
      cout << "Phase 3. Write lots of small packets to one target" << endl;
      writeNpData(4, 0, 1);
      writeNpData(4, 0, 1);
      writeNpData(4, 0, 1);
      writeNpData(4, 0, 1);
      writeNpData(4, 0, 1);
      writeNpData(4, 0, 1);
      writeNpData(4, 0, 1);
      writeNpData(4, 0, 1);
      writeNpData(4, 0, 1);
      writeNpData(4, 0, 1);
      writeNpData(4, 0, 1);
      writeNpData(4, 0, 1);
      writeNpData(4, 0, 1);
      writeNpData(4, 2, 1);
      writeNpData(4, 2, 1);
      writeNpData(4, 2, 1);
      writeNpData(4, 2, 1);
      writeNpData(4, 2, 1);
      writeNpData(4, 2, 1);
      writeNpData(4, 2, 1);
      writeNpData(4, 2, 1);
      writeNpData(4, 2, 1);
      writeNpData(4, 2, 1);
      writeNpData(4, 2, 1);
      writeNpData(4, 2, 1);
      writeNpData(4, 2, 1);
      writeNpData(4, 2, 1);
      writeNpData(4, 2, 1);
      writeNpData(4, 2, 1);
      writeNpData(4, 2, 1);
      writeNpData(4, 3, 1);
      writeNpData(4, 3, 1);
      writeNpData(4, 3, 1);
      writeNpData(4, 3, 1);
      writeNpData(4, 3, 1);
      writeNpData(4, 3, 1);
      writeNpData(4, 3, 1);
      writeNpData(4, 3, 1);
      writeNpData(4, 3, 1);
      writeNpData(4, 3, 1);

      // Wait for all packets to be received
      waitAllPacketsReceived(sc_time(1000, SC_US));

      // Agent 1 is not busy anymore
      setRxBusyChance(1, 0);




      // 4.Read config mems: reader, dst, page, slot, expected value
      cout << "Phase 4. Read and write configurations" << endl;
      readCfg(0, 2, 1, 1, 2); // Prior should matche id
      readCfg(0, 3, 1, 1, 3);
      readCfg(0, 4, 1, 1, 4);

      waitAllPacketsReceived(sc_time(100, SC_US));     

      // Write config mem, src, dst, page, slot, data
      writeCfg(0, 2, 1, 1, 4);  // Changing priorities
      writeCfg(0, 3, 1, 1, 2);
      writeCfg(0, 4, 1, 1, 3);

      waitAllPacketsReceived(sc_time(100, SC_US));     

      // Read config mems: src, dst, page, slot, expected value
      readCfg(0, 2, 1, 1, 4);
      wait(300, SC_NS);
      readCfg(0, 3, 1, 1, 2);
      wait(300, SC_NS);
      readCfg(0, 4, 1, 1, 3);

      waitAllPacketsReceived(sc_time(100, SC_US));     

      // Write config mem, src, dst, page, slot, data
      writeCfg(0, 2, 1, 1, 2); // Changing priorities back to defaults
      writeCfg(0, 3, 1, 1, 3); 
      writeCfg(0, 4, 1, 1, 4);

      waitAllPacketsReceived(sc_time(100, SC_US));     
      
      // Read config mems: src, dst, page, slot, expected value
      readCfg(0, 2, 1, 1, 2);
      wait(300, SC_NS);
      readCfg(0, 3, 1, 1, 3);
      wait(300, SC_NS);
      readCfg(0, 4, 1, 1, 4);

      waitAllPacketsReceived(sc_time(100, SC_US));     

      // Configure all to some power mode (no idea)
      writeCfg(0, 0, 1, 4, 0);

      waitAllPacketsReceived(sc_time(100, SC_US));     
      

      // This killed the previous hibi version, agent 3 rx_ctrl went nuts
      // agents 0-2 read the power mode of agent 3
      readCfg(0, 4, 1, 4, 0);
      readCfg(1, 4, 1, 4, 0);
      readCfg(2, 4, 1, 4, 0);
      
      waitAllPacketsReceived(sc_time(100, SC_US));     
      wait(1, SC_US);    

      

      
      // 5. Reading config mem from agents that are sending
      // Read config mems: src, dst, page, slot, expected value
      cout << "Phase 5. Reading configuration from a sending wrapper" << endl;
      writeNpData(200, 1, 0);      // size, source, destination
      wait(200, SC_NS);
      readCfg(0, 2, 1, 1, 2);
      readCfg(0, 3, 1, 1, 3);
      readCfg(0, 4, 1, 1, 4);
      wait(20, SC_NS);
      writeNpData(8, 1, 0);      // size, source, destination
      wait(20, SC_NS);
      writeNpData(4, 2, 3);      // size, source, destination
      wait(20, SC_NS);
      writeNpData(4, 2, 0);      // size, source, destination
      wait(20, SC_NS);
      writeNpData(8, 3, 2);      // size, source, destination

      waitAllPacketsReceived(sc_time(100, SC_US));           

      
      // 6. Send read commands
      cout << "Phase 6. Read" << endl;
      readData(10, 0, 3);
      readData(10, 1, 3);
      readData(10, 2, 3);

      waitAllPacketsReceived(sc_time(100, SC_US));      

      // 7. Test exclusiveness
      cout << "Phase 7. Exclusive access" << endl;
      lockExclusive(0, 1);
      wait(100, SC_NS);
      writeExclusive(100, 0, 1);
      writeNpData(50, 2, 1);
      wait(1, SC_US);
      releaseExclusive(0, 1);

      waitAllPacketsReceived(sc_time(100, SC_US));      


      setRxBusyChance(1, 85);
      lockExclusive(0, 1);
      wait(100, SC_NS);
      readExclusive(10, 0, 1);
      wait(300, SC_NS);
      writeExclusive(100, 0, 1);
      writeNpData(50, 2, 1);
      wait(1, SC_US);
      releaseExclusive(0, 1);
         
      waitAllPacketsReceived(sc_time(100, SC_US));      


      setRxBusyChance(1, 85);
      writeNpData(50, 2, 1);
      wait(100, SC_NS);
      lockExclusive(0, 1);
      wait(100, SC_NS);
      readExclusive(10, 0, 1);
      wait(300, SC_NS);
      writeExclusive(10, 0, 1);      
      writeExclusive(10, 0, 1);
      writeExclusive(10, 0, 1);
      writeExclusive(10, 0, 1);
      writeExclusive(10, 0, 1);
      writeExclusive(10, 0, 1);
      writeExclusive(10, 0, 1);
      writeExclusive(10, 0, 1);
      writeExclusive(10, 0, 1);
      writeExclusive(10, 0, 1);
      writeExclusive(10, 0, 1);
      writeExclusive(10, 0, 1);
      writeExclusive(10, 0, 1);
      writeExclusive(10, 0, 1);      
      wait(300, SC_NS);
      writeExclusive(10, 0, 1);
      writeExclusive(10, 0, 1);
      writeExclusive(10, 0, 1);
      writeExclusive(10, 0, 1);
      writeExclusive(10, 0, 1);
      writeExclusive(10, 0, 1);
      writeNpData(50, 2, 1);
      wait(1, SC_US);
      releaseExclusive(0, 1);
         
      waitAllPacketsReceived(sc_time(1000, SC_US));      




      // 8. Communicate over bridge, normal commands
      cout << "Phase 8. Write over the bridges" << endl;
      setRxBusyChance(0, 85);
      setRxBusyChance(1, 85);
      setRxBusyChance(2, 85);
      setRxBusyChance(3, 85);
      setRxBusyChance(4, 85); // all agents are bit slow to read
      readData(10, 4, 0);
      readData(10, 4, 1);
      readData(10, 4, 2);
      readData(10, 4, 3);
      writeNpData(4, 0, 4);
      writeNpData(4, 1, 4);
      writeNpData(4, 2, 4);
      writeNpData(4, 3, 4);
      writeNpData(4, 0, 4);
      writeNpData(4, 1, 4);
      writeNpData(4, 2, 4);
      writeNpData(4, 3, 4);
      writeNpData(4, 0, 4);
      writeNpData(4, 1, 4);
      writeNpData(4, 2, 4);
      writeNpData(4, 3, 4);
      writeNpData(4, 0, 4);
      writeNpData(4, 1, 4);
      writeNpData(4, 2, 4);
      writeNpData(4, 3, 4);
      writeNpData(4, 4, 0);
      writeNpData(4, 4, 1);
      writeNpData(4, 4, 2);
      writeNpData(4, 4, 3);
            
      waitAllPacketsReceived(sc_time(1000, SC_US));      

      // 9. Exclusive and normal writes over bridge
      cout << "Phase 9. Normal and exclusive writes over the bridges" << endl;
      writeNpData(50, 6, 1);
      writeNpData(50, 0, 1);
      wait(200, SC_NS);

      lockExclusive(4, 1);
      writeExclusive(10, 4, 1);
      writeExclusive(10, 4, 1);
      writeExclusive(10, 4, 1);
      writeExclusive(10, 4, 1);
      writeExclusive(10, 4, 1);
      writeExclusive(10, 4, 1);
      writeExclusive(10, 4, 1);
      writeExclusive(10, 4, 1);
      writeExclusive(10, 4, 1);
      writeExclusive(10, 4, 1);
      writeExclusive(10, 4, 1);
      releaseExclusive(4, 1);
      
      writeNpData(50, 2, 5);
      writeNpData(50, 3, 5);

      wait(200, SC_NS);

      lockExclusive(1, 5);
      writeExclusive(10, 1, 5);
      writeExclusive(10, 1, 5);
      writeExclusive(10, 1, 5);
      writeExclusive(10, 1, 5);
      writeExclusive(10, 1, 5);
      releaseExclusive(1, 5);

      waitAllPacketsReceived(sc_time(1000, SC_US));      


      writeNpData(100, 8, 1);
      writeNpData(100, 5, 1);
      writeNpMsg(100, 9, 2);
      writeNpMsg(100, 4, 1);
      readCfg(0, 6, 1, 1, 1);
      readCfg(0, 7, 1, 1, 2);
      readCfg(0, 8, 1, 1, 3);
      
      wait(200, SC_NS);

      lockExclusive(11, 2);      
      writeExclusive(10, 11, 2);
      writeExclusive(10, 11, 2);
      writeExclusive(10, 11, 2);
      writeExclusive(10, 11, 2);
      writeExclusive(10, 11, 2);
      writeExclusive(10, 11, 2);
      writeExclusive(10, 11, 2);
      writeExclusive(10, 11, 2);
      writeExclusive(10, 11, 2);
      writeExclusive(10, 11, 2);
      writeExclusive(10, 11, 2);
      releaseExclusive(11, 2);

      waitAllPacketsReceived(sc_time(2, SC_MS));

      
      // 10. Regular and message to write to busy agents
      cout << "Phase 10. Many reg/Msg writes to busy agents" << endl;
      setRxBusyChance(5, 85);
      setRxBusyChance(6, 85);
      setRxBusyChance(7, 85);
      setRxBusyChance(8, 85);
      setRxBusyChance(9, 85);
      setRxBusyChance(10, 85);
      setRxBusyChance(11, 85);

      for(unsigned int i = 0; i < 100; ++i)
      {
         writeNpData(1, 8, 0);
         writeNpData(1, 9, 1);
         writeNpMsg(1, 10, 4);
         writeNpMsg(1, 11, 5);
         
         writeNpData(1, 4, 2);
         writeNpData(1, 5, 3);
         writeNpMsg(1, 6, 6);
         writeNpMsg(1, 7, 7);
         
         writeNpData(1, 0, 4);
         writeNpData(1, 1, 8);
         writeNpMsg(1, 2, 7);
         writeNpMsg(1, 3, 11);
         
         wait(200, SC_NS);
      }

      readCfg(0, 2, 1, 1, 2);
      readCfg(0, 3, 1, 1, 3);
      readCfg(0, 4, 1, 1, 4);

      for(unsigned int i = 0; i < 1000; ++i)
      {
         writeNpData(1, 8, 0);
         writeNpMsg(2, 8, 0);
         
         writeNpData(2, 9, 1);
         writeNpMsg(1, 9, 1);
         
         writeNpMsg(1, 10, 4);
         writeNpData(1, 10, 4);

         writeNpMsg(1, 11, 5);
         writeNpData(1, 11, 5);
         
         writeNpData(1, 4, 2);
         writeNpMsg(1, 4, 2);

         writeNpData(1, 5, 3);
         writeNpMsg(3, 5, 3);

         writeNpMsg(1, 6, 6);
         writeNpData(1, 6, 6);

         writeNpMsg(1, 7, 7);
         writeNpData(3, 7, 7);
         
         writeNpData(1, 0, 4);
         writeNpMsg(1, 0, 4);

         writeNpData(1, 1, 8);
         writeNpMsg(1, 1, 8);

         writeNpMsg(1, 2, 7);
         writeNpData(1, 2, 7);
         
         writeNpMsg(1, 3, 11);
         writeNpData(1, 3, 11);
         wait(600, SC_NS);
      }

      readCfg(1, 2, 1, 1, 2);
      readCfg(1, 3, 1, 1, 3);
      readCfg(1, 4, 1, 1, 4);

      readCfg(2, 3, 1, 1, 3);
      readCfg(2, 4, 1, 1, 4);
      readCfg(2, 5, 1, 1, 5);

      // 11. Regular and message to write to busy agents
      cout << "Phase 11. Lots of excl. accesses to busy agents over the bridges" << endl;

      for(unsigned int i = 0; i < 1000; ++i)
      {
         if(i % 10 == 0)
         {
            lockExclusive(10, 1);
            writeExclusive(1, 10, 1);     
            releaseExclusive(10, 1);

            lockExclusive(2, 9);
            writeExclusive(2, 2, 9);      
            releaseExclusive(2, 9);
         }

         writeNpData(1, 8, 0);
         writeNpMsg(2, 8, 0);
         
         writeNpData(2, 9, 1);
         writeNpMsg(1, 9, 1);
         
         writeNpMsg(1, 10, 4);
         writeNpData(1, 10, 4);

         writeNpMsg(1, 11, 5);
         writeNpData(1, 11, 5);
         
         writeNpData(1, 4, 2);
         writeNpMsg(1, 4, 2);

         writeNpData(1, 5, 3);
         writeNpMsg(3, 5, 3);

         writeNpMsg(1, 6, 6);
         writeNpData(1, 6, 6);

         wait(200, SC_NS);

         writeNpMsg(1, 7, 7);
         writeNpData(3, 7, 7);
         
         writeNpData(1, 0, 4);
         writeNpMsg(1, 0, 4);

         writeNpData(1, 1, 8);
         writeNpMsg(1, 1, 8);

         writeNpMsg(1, 2, 7);
         writeNpData(1, 2, 7);
         
         writeNpMsg(1, 3, 11);
         writeNpData(1, 3, 11);

         if(i % 10 == 1)
         {
            lockExclusive(10, 1);
            writeExclusive(1, 10, 1);               

            lockExclusive(2, 9);
            writeExclusive(2, 2, 9);      

            wait(8000, SC_NS);

            releaseExclusive(10, 1);
            releaseExclusive(2, 9);
         }

      }

      
      waitAllPacketsReceived(sc_time(12, SC_MS));
      
      

      cout << endl << "SAD HIBI TESTBENCH FINISHED" << endl << endl;
      cout << "Remember to grep output for warnings" << endl << endl;
      sc_stop();
   }





private:

   // 
   // Set of helper functions to create packets
   // 5 categories: excl, read, write, cfg, and wait
   // Most functions just call source and dst agents with packet params
   //

   //
   // Exclusive acecsses
   // 
   void releaseExclusive(unsigned int src, unsigned int dst)
   {
      Packet* packet = 0;
      packet = new Packet(1, addresses_c[src], addresses_c[dst], EXCL_RELEASE);
      _top.agents.at(src)->send(packet);
      _top.agents.at(dst)->expect(packet);
   }


   void lockExclusive(unsigned int src, unsigned int dst)
   {
      Packet* packet = 0;
      packet = new Packet(1, addresses_c[src], addresses_c[dst], EXCL_LOCK);
      _top.agents.at(src)->send(packet);
      _top.agents.at(dst)->expect(packet);
   }

   
   void writeExclusive(unsigned int size, unsigned int src, unsigned int dst)
   {
      Packet* packet = 0;
      packet = new Packet(size, addresses_c[src], addresses_c[dst], EXCL_WR);
      _top.agents.at(src)->send(packet);
      _top.agents.at(dst)->expect(packet);
   }


   void readExclusive(unsigned int size,  unsigned int src, unsigned int dst)
   {
      Packet* packet = 0;
      packet = new Packet(1, addresses_c[src], addresses_c[dst], 
                          EXCL_RD, size);
      _top.agents.at(src)->send(packet);
      _top.agents.at(dst)->expect(packet);
   }


   //
   // Reading 
   // 
   void readData(unsigned int size,  unsigned int src, unsigned int dst)
   {
      Packet* packet = 0;
      packet = new Packet(1, addresses_c[src], addresses_c[dst], DATA_RD, size);
      _top.agents.at(src)->send(packet);
      _top.agents.at(dst)->expect(packet);
   }


   void readMsg(unsigned int size,  unsigned int src, unsigned int dst)
   {
      Packet* packet = 0;
      packet = new Packet(1, addresses_c[src], addresses_c[dst], MSG_RD, size);
      _top.agents.at(src)->send(packet);
      _top.agents.at(dst)->expect(packet);
   }

   //  
   // Configure the agent 
   //
   //* Sets the probability for agent to be busy (per clock cycle)
   void setRxBusyChance(unsigned int agent, unsigned int chance)
   {
      _top.agents.at(agent)->setRxBusyChance(chance); 
   }

   //* Sets the probability for agent to be busy (per clock cycle)
   void setTxBusyChance(unsigned int agent, unsigned int chance)
   {
      _top.agents.at(agent)->setTxBusyChance(chance); 
   }

   //
   // Writing 
   //
   //* Sends a regular packet from agent src to agent dst, np=nonposted
   void writeNpData(unsigned int size, unsigned int src, unsigned int dst,
                    bool useDiffAddr = true)
   {
      sc_bv<addr_width_c> addr = _lastAddress[dst];

      if(useDiffAddr)
      {
         // Using different address than last time
         if(addr == addresses_max_c[dst])
         {
            addr = addresses_c[dst]; // Wrap around
         }
         else
         {
            addr = sc_bv<addr_width_c>(addr.to_uint() + 1);
         }
         _lastAddress[dst] = addr;
      }

      Packet* packet = 0;
      packet = new Packet(size, addresses_c[src], addr, DATA_WRNP);
      _top.agents.at(src)->send(packet);
      _top.agents.at(dst)->expect(packet);
   }


   //* Sends a message packet from agent src to agent dst, nonposted
   void writeNpMsg(unsigned int size, unsigned int src, unsigned int dst)
   {
      Packet* packet = 0;
      packet = new Packet(size, addresses_c[src], addresses_c[dst], MSG_WRNP);
      _top.agents.at(src)->send(packet);
      _top.agents.at(dst)->expect(packet);
   }

   //
   // Configuring the HIBI
   //
   //* Read one config mem slot
   void readCfg(unsigned int src, unsigned int dst, unsigned int page,
                unsigned int slot, unsigned int expectedData)
   {
      Packet* packet = 0;
      packet = new Packet(1, addresses_c[src], dst, CFG_RD,
                          page, slot);
      _top.agents.at(src)->send(packet);
      _top.agents.at(src)->expect(packet, expectedData);
   }


   //* write one config mem slot
   void writeCfg(unsigned int src, unsigned int dst, unsigned int page,
                 unsigned int slot, unsigned int data)
   {
      Packet* packet = 0;
      packet = new Packet(1, addresses_c[src], dst, CFG_WR,
                          page, slot, data);
      _top.agents.at(src)->send(packet);
   }


   // 
   // Waiting
   // 
   //* Waits for all packets to be received or timeout which ever comes first
   //* Returns false if timeout was first
   bool waitAllPacketsReceived(sc_time timeout)
   {
      sc_time startWaiting = sc_time_stamp();
      bool endWait = true;
      while(endWait)
      {
         wait(1, SC_US);         
         // End if all packets have been received        
         bool stillPacketsOutThereInTheVoid = false;
         for(unsigned int i = 0; i < _top.agents.size(); ++i)
         {
            if(_top.agents.at(i)->allDone() == false)
            {
               stillPacketsOutThereInTheVoid = true;
            }
         }
         endWait = stillPacketsOutThereInTheVoid;
         // End anyway when waited more than timeout
         if(sc_time_stamp() - startWaiting > timeout)
         {
            ostringstream oss;
            oss << "At " << sc_time_stamp().to_double() << " : "
                << "timeout failed when waiting for all packets to complete";
            SC_REPORT_WARNING("warning", oss.str().c_str());
            for(unsigned int i = 0; i < _top.agents.size(); ++i)
            {
               if(_top.agents.at(i)->allDone() == false)
               {
                  cout << " - Agent " << i << " excpecting packet(s)" << endl;
                  _top.agents.at(i)->printExpected();
               }
            }
            return false;
         }
      }
      wait(1, SC_US);    
      cout << "At " << setprecision(10) << sc_time_stamp().to_double()
           << " : ** All packets have been received **"  << endl;
      return true;
   }

   /*
    *  MEMBER VARIABLES
    */

   // Pointer to toplevel where the agents are
   TopLevel& _top;

   sc_bv<addr_width_c> _lastAddress[n_agents_c];

};

#endif

// Local Variables:
// mode: c++
// c-file-style: "ellemtel"
// c-basic-offset: 3
// End:

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.