MatchLib
AxiRemoveWriteResponse.h
1 /*
2  * Copyright (c) 2017-2019, NVIDIA CORPORATION. All rights reserved.
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 __AXIREMOVEWRITERESPONSE_H__
17 #define __AXIREMOVEWRITERESPONSE_H__
18 
19 #include <systemc.h>
20 #include <nvhls_connections.h>
21 #include <nvhls_marshaller.h>
22 #include <nvhls_assert.h>
23 #include <axi/axi4.h>
24 #include <fifo.h>
25 #include <TypeToBits.h>
26 
53 template <typename CfgMaster, typename CfgSlave, int maxInFlight>
54 class AxiRemoveWriteResponse : public sc_module {
55  static const int kDebugLevel = 6;
56  SC_HAS_PROCESS(AxiRemoveWriteResponse);
57  // Local typedefs and derived constants
58  typedef axi::axi4<CfgMaster> axiM;
59  typedef axi::axi4<CfgSlave> axiS;
60 
61  enum { maxInFlight_width = nvhls::log2_ceil<maxInFlight>::val };
62 
63  public:
64  // External interface
65  sc_in_clk clk;
66  sc_in<bool> rst;
67 
68  typename axiM::read::template slave<> axiM_read;
69  typename axiM::write::template slave<> axiM_write;
70  typename axiS::read::template master<> axiS_read;
71  typename axiS::write::template master<> axiS_write;
72 
73  private:
74  // Local state and submodules
75  typename axiM::AddrPayload AW;
76  typename axiM::WritePayload W;
77  typename axiM::AddrPayload AR;
78  typename axiS::ReadPayload R;
79  typename axiM::WRespPayload B;
80 
81  // Ideally we'd remove the B field entirely, but a stub of it still exists,
82  // so we need to connect it to something
84 
87 
88  public:
89  // Constructor
90  AxiRemoveWriteResponse(sc_module_name name)
91  : sc_module(name),
92  clk("clk"),
93  rst("rst"),
94  axiM_read("axiM_read"),
95  axiM_write("axiM_write"),
96  axiS_read("axiS_read"),
97  axiS_write("axiS_write"),
98  dummyB("dummyB")
99  {
100 
101  dummyB.clk(clk);
102  dummyB.rst(rst);
103  dummyB.in(axiS_write.b);
104 
105  SC_THREAD(axi_read_ar);
106  sensitive << clk.pos();
108 
109  SC_THREAD(axi_read_r);
110  sensitive << clk.pos();
112 
113  SC_THREAD(axi_write);
114  sensitive << clk.pos();
116  }
117 
118  private:
119  void axi_read_ar() {
120  axiM_read.ar.Reset();
121  axiS_read.ar.Reset();
122  #pragma hls_pipeline_init_interval 1
123  #pragma pipeline_stall_mode flush
124  while(1) {
125  wait();
126  if (axiM_read.ar.PopNB(AR)) {
127  axiS_read.ar.Push(BitsToType<typename axiS::AddrPayload>(TypeToBits(AR)));
128  }
129  }
130  }
131 
132  void axi_read_r() {
133  axiM_read.r.Reset();
134  axiS_read.r.Reset();
135  #pragma hls_pipeline_init_interval 1
136  #pragma pipeline_stall_mode flush
137  while(1) {
138  wait();
139  if (axiS_read.r.PopNB(R)) {
140  axiM_read.r.Push(BitsToType<typename axiM::ReadPayload>(TypeToBits(R)));
141  }
142  }
143  }
144 
145  void axi_write() {
146  B.resp = axiM::Enc::XRESP::OKAY; // Never return an error response
147 
148  axiM_write.reset();
149  axiS_write.w.Reset();
150  axiS_write.aw.Reset();
151  wresp_id_q.reset();
152  wresp_id_q_out.reset();
153 
154  bool wresp_id_q_full = 0;
155  bool wresp_id_q_empty = 0;
156  bool wresp_id_q_out_full = 0;
157  bool wresp_id_q_out_empty = 0;
158 
159  #pragma hls_pipeline_init_interval 2
160  #pragma pipeline_stall_mode flush
161  while(1) {
162  wait();
163 
164  wresp_id_q_full = wresp_id_q.isFull();
165  wresp_id_q_empty = wresp_id_q.isEmpty();
166  wresp_id_q_out_full = wresp_id_q_out.isFull();
167  wresp_id_q_out_empty = wresp_id_q_out.isEmpty();
168 
169  if (!wresp_id_q_full) {
170  if (axiM_write.aw.PopNB(AW)) {
171  axiS_write.aw.Push(BitsToType<typename axiS::AddrPayload>(TypeToBits(AW)));
172  wresp_id_q.push(AW.id);
173  }
174  }
175 
176  if (!wresp_id_q_empty && !wresp_id_q_out_full) {
177  if (axiM_write.w.PopNB(W)) {
178  axiS_write.w.Push(BitsToType<typename axiS::WritePayload>(TypeToBits(W)));
179  if (W.last == 1) wresp_id_q_out.push(wresp_id_q.pop());
180  }
181  }
182 
183  if (!wresp_id_q_out_empty) {
184  B.id = wresp_id_q_out.pop();
185  axiM_write.b.Push(B);
186  }
187  }
188  }
189 };
190 
191 
192 #endif
A simple shim that converts between two AXI configs by removing write responses.
A struct composed of the signals associated with an AXI write response.
Definition: axi4.h:236
A struct composed of the signals associated with AXI write data.
Definition: axi4.h:279
A struct composed of the signals associated with AXI read and write requests.
Definition: axi4.h:108
A struct composed of the signals associated with an AXI read response.
Definition: axi4.h:180
The base axi4 class parameterized according a valid config.
Definition: axi4.h:58
sc_lv< Wrapped< T >::width > TypeToBits(T in)
Convert Type to logic vector.
Definition: TypeToBits.h:48
Compute Celing of log2 of a constant.
Definition: nvhls_int.h:174
Configurable FIFO class.
Definition: fifo.h:65
#define NVHLS_NEG_RESET_SIGNAL_IS(port)
ENABLE_SYNC_RESET define: Select synchronous or asynchronous reset.Matchlib uses asynchronous, active-low reset by default. Defining ENABLE_SYNC_RESET will use synchronous, active-low reset instead. The macros NVHLS_NEG_RESET_SIGNAL_IS() and NVHLS_POS_RESET_SIGNAL_IS() can be used in place of SystemC&#39;s reset_signal_is() and async_reset_signal_is() so that ENABLE_SYNC_RESET can select type.
Definition: nvhls_module.h:39