A SystemC productivity library for virtual platform development utilizing SCV and TLM2.0 https://www.minres.com/#opensource

tlm_signal.h 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. /*******************************************************************************
  2. * Copyright 2018 MINRES Technologies GmbH
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. *******************************************************************************/
  16. #ifndef _TLM_TLM_SIGNAL_H_
  17. #define _TLM_TLM_SIGNAL_H_
  18. #include "tlm_signal_gp.h"
  19. #include "tlm_signal_sockets.h"
  20. #include <scc/peq.h>
  21. namespace tlm {
  22. template <typename SIG = bool, typename TYPES = tlm_signal_baseprotocol_types<SIG>, int N = 32>
  23. struct tlm_signal : public sc_core::sc_module,
  24. public tlm_signal_fw_transport_if<SIG, TYPES>,
  25. public tlm_signal_bw_transport_if<SIG, TYPES>,
  26. sc_core::sc_signal_in_if<SIG> {
  27. using tlm_signal_type = SIG;
  28. using protocol_types = TYPES;
  29. using payload_type = typename TYPES::tlm_payload_type;
  30. using phase_type = typename TYPES::tlm_phase_type;
  31. SC_HAS_PROCESS(tlm_signal);// NOLINT
  32. tlm_signal_opt_target_socket<tlm_signal_type, protocol_types, N> in;
  33. tlm_signal_opt_initiator_socket<tlm_signal_type, protocol_types, N> out;
  34. tlm_signal(sc_core::sc_module_name nm)
  35. : sc_core::sc_module(nm)
  36. , in(sc_core::sc_gen_unique_name("in"))
  37. , out(sc_core::sc_gen_unique_name("out")) {
  38. in.bind(*(tlm_signal_fw_transport_if<tlm_signal_type, protocol_types> *)this);
  39. out.bind(*(tlm_signal_bw_transport_if<tlm_signal_type, protocol_types> *)this);
  40. SC_METHOD(que_cb);
  41. sensitive << que.event();
  42. }
  43. void trace(sc_core::sc_trace_file *tf) const override;
  44. const char *kind() const override { return "tlm_signal"; }
  45. tlm_sync_enum nb_transport_fw(payload_type &, phase_type &, sc_core::sc_time &) override;
  46. tlm_sync_enum nb_transport_bw(payload_type &, phase_type &, sc_core::sc_time &) override;
  47. // get the value changed event
  48. const sc_core::sc_event &value_changed_event() const override { return value.value_changed_event(); }
  49. // read the current value
  50. const SIG &read() const override { return value.read(); }
  51. // get a reference to the current value (for tracing)
  52. const SIG &get_data_ref() const override { return value.get_data_ref(); }
  53. // was there a value changed event?
  54. bool event() const override { return false; }
  55. const sc_core::sc_event &default_event() const override { return value.default_event(); }
  56. const sc_core::sc_event &posedge_event() const override { return value.posedge_event(); }
  57. const sc_core::sc_event &negedge_event() const override { return value.negedge_event(); }
  58. bool posedge() const override { return value.posedge(); }
  59. bool negedge() const override { return value.posedge(); };
  60. private:
  61. void que_cb();
  62. scc::peq<tlm_signal_type> que;
  63. sc_core::sc_signal<tlm_signal_type> value;
  64. };
  65. template <typename SIG, typename TYPES, int N> void tlm_signal<SIG, TYPES, N>::trace(sc_core::sc_trace_file *tf) const {
  66. sc_trace(tf, value, name());
  67. }
  68. template <typename SIG, typename TYPES, int N>
  69. tlm_sync_enum tlm::tlm_signal<SIG, TYPES, N>::nb_transport_fw(payload_type &gp, phase_type &phase,
  70. sc_core::sc_time &delay) {
  71. que.notify(gp.get_value(), delay);
  72. auto &p = out.get_base_port();
  73. for (size_t i = 0; i < p.size(); ++i) {
  74. p.get_interface(i)->nb_transport_fw(gp, phase, delay);
  75. }
  76. return TLM_COMPLETED;
  77. }
  78. template <typename SIG, typename TYPES, int N>
  79. tlm_sync_enum tlm::tlm_signal<SIG, TYPES, N>::nb_transport_bw(payload_type &gp, phase_type &phase,
  80. sc_core::sc_time &delay) {
  81. auto &p = in.get_base_port();
  82. for (size_t i = 0; i < p.size(); ++i) {
  83. p.get_interface(i)->nb_transport_bw(gp, phase, delay);
  84. }
  85. return TLM_COMPLETED;
  86. }
  87. template <typename SIG, typename TYPES, int N> void tlm::tlm_signal<SIG, TYPES, N>::que_cb() {
  88. while (auto oi = que.get_next()) value.write(oi.get());
  89. }
  90. }
  91. #endif /* _TLM_TLM_SIGNAL_H_ */