scc  2022.4.0
SystemC components library
protocol_fsm.h
1 /*
2  * Copyright 2020 -2022 Arteris IP
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.axi_util.cpp
15  */
16 
17 #pragma once
18 
19 #include "types.h"
20 #include <array>
21 #include <boost/mpl/list.hpp>
22 #include <boost/statechart/custom_reaction.hpp>
23 #include <boost/statechart/event.hpp>
24 #include <boost/statechart/state.hpp>
25 #include <boost/statechart/state_machine.hpp>
26 #include <boost/statechart/transition.hpp>
27 #include <functional>
28 #include <iostream>
29 
30 namespace mpl = boost::mpl;
31 namespace bsc = boost::statechart;
32 
33 namespace axi {
34 namespace fsm {
35 // Event Declarations
36 struct WReq : bsc::event<WReq> {};
37 struct BegPartReq : bsc::event<BegPartReq> {};
38 struct EndPartReq : bsc::event<EndPartReq> {};
39 struct BegReq : bsc::event<BegReq> {};
40 struct EndReq : bsc::event<EndReq> {};
41 struct BegPartResp : bsc::event<BegPartResp> {};
42 struct EndPartResp : bsc::event<EndPartResp> {};
43 struct BegResp : bsc::event<BegResp> {};
44 struct EndResp : bsc::event<EndResp> {};
45 struct EndRespNoAck : bsc::event<EndRespNoAck> {};
46 struct AckRecv : bsc::event<AckRecv> {};
47 // State forward Declarations
48 struct Idle; // forward declaration
49 struct ATrans;
50 struct PartialRequest;
51 struct WriteIdle;
52 struct Request;
53 struct WaitForResponse;
54 struct PartialResponse;
55 struct ReadIdle;
56 struct Response;
57 struct WaitAck;
61 struct AxiProtocolFsm : bsc::state_machine<AxiProtocolFsm, Idle> {
62  void InvokeResponsePhaseBeg(const BegResp&) {
63  if(cb.at(axi::fsm::ResponsePhaseBeg))
64  cb.at(axi::fsm::ResponsePhaseBeg)();
65  };
66  void InvokeResponsePhaseBeg(const BegPartResp&) {
67  if(cb.at(axi::fsm::ResponsePhaseBeg))
68  cb.at(axi::fsm::ResponsePhaseBeg)();
69  };
70  void terminate(){
71  for(auto& f:cb) f=nullptr;
72  bsc::state_machine<AxiProtocolFsm, Idle>::terminate();
73  }
74  axi::fsm::protocol_cb cb;
75 };
77 struct Idle : bsc::state<Idle, AxiProtocolFsm> { // @suppress("Class has a virtual method and non-virtual destructor")
78  Idle(my_context ctx)
79  : my_base(ctx) {}
80  ~Idle() {
81  if(context<AxiProtocolFsm>().cb.at(axi::fsm::RequestPhaseBeg))
82  context<AxiProtocolFsm>().cb.at(axi::fsm::RequestPhaseBeg)();
83  }
84  typedef mpl::list<bsc::transition<BegPartReq, PartialRequest>, bsc::transition<BegReq, Request>,
85  bsc::transition<WReq, ATrans>>
86  reactions;
87 };
89 struct ATrans
90 : bsc::state<ATrans, AxiProtocolFsm> { // @suppress("Class has a virtual method and non-virtual destructor")
91  ATrans(my_context ctx)
92  : my_base(ctx) {
93  if(context<AxiProtocolFsm>().cb.at(axi::fsm::WValidE))
94  context<AxiProtocolFsm>().cb.at(axi::fsm::WValidE)();
95  }
96  ~ATrans() {
97  if(context<AxiProtocolFsm>().cb.at(axi::fsm::WReadyE))
98  context<AxiProtocolFsm>().cb.at(axi::fsm::WReadyE)();
99  }
100  typedef mpl::list<bsc::transition<BegPartReq, PartialRequest>, bsc::transition<BegReq, Request>> reactions;
101 };
104 : bsc::state<PartialRequest, AxiProtocolFsm> { // @suppress("Class has a virtual method and non-virtual destructor")
105  PartialRequest(my_context ctx)
106  : my_base(ctx) {
107  if(context<AxiProtocolFsm>().cb.at(axi::fsm::BegPartReqE))
108  context<AxiProtocolFsm>().cb.at(axi::fsm::BegPartReqE)();
109  }
110  ~PartialRequest() {
111  if(context<AxiProtocolFsm>().cb.at(axi::fsm::EndPartReqE))
112  context<AxiProtocolFsm>().cb.at(axi::fsm::EndPartReqE)();
113  }
114  typedef bsc::transition<EndPartReq, WriteIdle> reactions;
115 };
117 struct WriteIdle
118 : bsc::simple_state<WriteIdle, AxiProtocolFsm> { // @suppress("Class has a virtual method and non-virtual destructor")
119  typedef mpl::list<bsc::transition<BegPartReq, PartialRequest>, bsc::transition<BegReq, Request>> reactions;
120 };
122 struct Request
123 : bsc::state<Request, AxiProtocolFsm> { // @suppress("Class has a virtual method and non-virtual destructor")
124  Request(my_context ctx)
125  : my_base(ctx) {
126  if(context<AxiProtocolFsm>().cb.at(axi::fsm::BegReqE))
127  context<AxiProtocolFsm>().cb.at(axi::fsm::BegReqE)();
128  }
129  ~Request() {
130  if(context<AxiProtocolFsm>().cb.at(axi::fsm::EndReqE))
131  context<AxiProtocolFsm>().cb.at(axi::fsm::EndReqE)();
132  }
133  typedef mpl::list<
134  bsc::transition<EndReq, WaitForResponse>,
135  bsc::transition<BegResp, Response, AxiProtocolFsm, &AxiProtocolFsm::InvokeResponsePhaseBeg>,
136  bsc::transition<BegPartResp, PartialResponse, AxiProtocolFsm, &AxiProtocolFsm::InvokeResponsePhaseBeg>>
137  reactions;
138 };
141 : bsc::state<WaitForResponse, AxiProtocolFsm> { // @suppress("Class has a virtual method and non-virtual destructor")
142  WaitForResponse(my_context ctx)
143  : my_base(ctx) {}
144  ~WaitForResponse() {
145  if(context<AxiProtocolFsm>().cb.at(axi::fsm::ResponsePhaseBeg))
146  context<AxiProtocolFsm>().cb.at(axi::fsm::ResponsePhaseBeg)();
147  }
148  typedef mpl::list<bsc::transition<BegPartResp, PartialResponse>, bsc::transition<BegResp, Response>> reactions;
149 };
152 : bsc::state<PartialResponse, AxiProtocolFsm> { // @suppress("Class has a virtual method and non-virtual destructor")
153  PartialResponse(my_context ctx)
154  : my_base(ctx) {
155  if(context<AxiProtocolFsm>().cb.at(axi::fsm::BegPartRespE))
156  context<AxiProtocolFsm>().cb.at(axi::fsm::BegPartRespE)();
157  }
158  ~PartialResponse() {
159  if(context<AxiProtocolFsm>().cb.at(axi::fsm::EndPartRespE))
160  context<AxiProtocolFsm>().cb.at(axi::fsm::EndPartRespE)();
161  }
162  typedef bsc::transition<EndPartResp, ReadIdle> reactions;
163 };
165 struct ReadIdle
166 : bsc::simple_state<ReadIdle, AxiProtocolFsm> { // @suppress("Class has a virtual method and non-virtual destructor")
167  typedef mpl::list<bsc::transition<BegPartResp, PartialResponse>, bsc::transition<BegResp, Response>> reactions;
168 };
170 struct Response
171 : bsc::state<Response, AxiProtocolFsm> { // @suppress("Class has a virtual method and non-virtual destructor")
172  Response(my_context ctx)
173  : my_base(ctx) {
174  if(context<AxiProtocolFsm>().cb.at(axi::fsm::BegRespE))
175  context<AxiProtocolFsm>().cb.at(axi::fsm::BegRespE)();
176  }
177  ~Response() {
178  if(context<AxiProtocolFsm>().cb.at(axi::fsm::EndRespE))
179  context<AxiProtocolFsm>().cb.at(axi::fsm::EndRespE)();
180  }
181  typedef mpl::list<bsc::transition<EndResp, Idle>, bsc::transition<EndRespNoAck, WaitAck>> reactions;
182 };
184 struct WaitAck
185 : bsc::state<WaitAck, AxiProtocolFsm> { // @suppress("Class has a virtual method and non-virtual destructor")
186  WaitAck(my_context ctx)
187  : my_base(ctx) {}
188  ~WaitAck() {
189  if(context<AxiProtocolFsm>().cb.at(axi::fsm::Ack))
190  context<AxiProtocolFsm>().cb.at(axi::fsm::Ack)();
191  }
192  typedef bsc::transition<AckRecv, Idle> reactions;
193 };
194 } // namespace fsm
195 } // namespace axi
TLM2.0 components modeling AHB.
Definition: axi_initiator.h:30
special state to map AWREADY/WDATA of SNPS to AXI protocol
Definition: protocol_fsm.h:90
the idle state
Definition: protocol_fsm.h:77
the beat of a burst response
Definition: protocol_fsm.h:152
the phase between 2 read burst response beats
Definition: protocol_fsm.h:166
the request, either the last beat of a write or the address phase of a read
Definition: protocol_fsm.h:123
the write response or the last read response (beat)
Definition: protocol_fsm.h:171
waiting for ack in case of ACE access
Definition: protocol_fsm.h:185
the operation state where the target can do it's stuff
Definition: protocol_fsm.h:141
the phase between 2 burst beats, should keep the link locked
Definition: protocol_fsm.h:118