aboutsummaryrefslogblamecommitdiff
path: root/src/lt_bus.cc
blob: 443feb2071880c29084aa1cbc53ce0671f7f5a53 (plain) (tree)
1
2
                          
                      














                                                                                

                                                                   
                                                 
 

                                                








                                                                                

                                                                                





                                                               




                                                               










                                                         

                                       


                               



                                                                        






















                                                                                
                                                    
                                                    



                                                    

             



                      
#include "models/lt_bus.h"
#include "utils/log.h"

#include <tlm_utils/simple_initiator_socket.h>
#include <tlm_utils/simple_target_socket.h>

// -- TARGET -------------------------------------------------------------------

struct target : public sc_core::sc_module {
  explicit target(sc_core::sc_module_name nm) : sc_module(std::move(nm)) {
    p_sock.register_b_transport(this, &target::b_transport);
  }

  tlm_utils::simple_target_socket<target> p_sock{"sock"};

 private:
  void b_transport(tlm::tlm_generic_payload& tx, sc_core::sc_time& t) {
    CLOGM(YELLOW, "transport 0x%llx w: %d r: %d", tx.get_address(),
          tx.is_write(), tx.is_read());
    tx.set_response_status(tlm::TLM_OK_RESPONSE);

    CLOGM(YELLOW, "invalidate 0x00 - 0xff..ff");
    p_sock->invalidate_direct_mem_ptr(0, -1ull);
  }
};

// -- INITIATOR ----------------------------------------------------------------

struct initiator : public sc_core::sc_module {
  SC_HAS_PROCESS(initiator);

  explicit initiator(sc_core::sc_module_name nm) : sc_module(std::move(nm)) {
    p_sock.register_invalidate_direct_mem_ptr(this, &initiator::invalidate_dmi);

    SC_THREAD(run);
  }

  tlm_utils::simple_initiator_socket<initiator> p_sock{"sock"};

 private:
  void invalidate_dmi(sc_dt::uint64 start, sc_dt::uint64 end) {
    CLOGM(CYAN, "INV 0x%08llx-0x%08llx", start, end);
  }

  void send_tx(tlm::tlm_command cmd, u64 addr) {
    unsigned char data[4];
    tlm::tlm_generic_payload tx;
    tx.set_command(cmd);
    tx.set_address(addr);
    tx.set_data_ptr(data);
    tx.set_data_length(sizeof(data));
    tx.set_byte_enable_ptr(nullptr);
    tx.set_byte_enable_length(0);
    tx.set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
    tx.set_dmi_allowed(false);

    CLOGM(CYAN, "ACCESS @0x%lx", addr);

    sc_core::sc_time t;
    p_sock->b_transport(tx, t);

    CLOGM(CYAN, "ACCESS ok: %d (%s)", tx.is_response_ok(),
          tx.get_response_string().c_str());

    LOG("------------------------------------------------------------");
  }

  void run() {
    send_tx(tlm::TLM_WRITE_COMMAND, 0x1000);
    send_tx(tlm::TLM_WRITE_COMMAND, 0x3000);
    send_tx(tlm::TLM_WRITE_COMMAND, 0x4000);
    send_tx(tlm::TLM_WRITE_COMMAND, 0x9000);
    send_tx(tlm::TLM_WRITE_COMMAND, 0x80fc);
    send_tx(tlm::TLM_WRITE_COMMAND, 0x80fd);
  }
};

// -- SC_MAIN ------------------------------------------------------------------

extern "C" int sc_main(int, char*[]) {
  lt_bus bus{"bus"};

  target target1{"target1"};
  target target2{"target2"};
  target target3{"target3"};

  initiator init1{"init1"};

  bus.attach_target(target1.p_sock, 0x0000, 0x3fff);
  bus.attach_target(target2.p_sock, 0x4000, 0x4fff);
  bus.attach_target(target3.p_sock, 0x8000, 0x80ff);

  bus.attach_initiator(init1.p_sock);

  bus.dump();

  sc_core::sc_start();

  return 0;
}