@@ -101,88 +101,80 @@ target<DATA_WIDTH, ADDR_WIDTH>::target(const sc_core::sc_module_name& nm)
101101template <unsigned DATA_WIDTH, unsigned ADDR_WIDTH> target<DATA_WIDTH, ADDR_WIDTH>::~target () = default ;
102102
103103template <unsigned DATA_WIDTH, unsigned ADDR_WIDTH> void target<DATA_WIDTH, ADDR_WIDTH>::bus_task() {
104- auto const width_exp = scc::ilog2 (DATA_WIDTH / 8 );
105104 wait (sc_core::SC_ZERO_TIME);
106- auto & psel = PSELx_i.read ();
107- auto & penable = PENABLE_i.read ();
108105 wait (PCLK_i.posedge_event ());
109106 while (true ) {
110107 if (!PRESETn_i.read ()) {
111108 wait (PRESETn_i.posedge_event ());
112109 wait (PCLK_i.posedge_event ());
113110 } else {
114111 PREADY_o.write (false );
115- wait (1_ps);
116- if (psel) { // HTRANS/BUSY or IDLE check
117- PREADY_o.write (false );
118- SCCDEBUG (SCMOD) << " Starting APB setup phase" ;
119- unsigned length = DATA_WIDTH / 8 ;
120- auto trans = tlm::scc::tlm_mm<>::get ().allocate <apb::apb_extension>(length);
121- trans->acquire ();
122- trans->set_streaming_width (length);
123- trans->set_address (PADDR_i.read ());
124- auto * ext = trans->get_extension <apb_extension>();
125- if (PPROT_i.get_interface ())
126- ext->set_protection (PPROT_i.read ().to_uint ());
127- if (PNSE_i.get_interface ())
128- ext->set_nse (PNSE_i.read ());
129- auto start_offs = trans->get_address () & (length - 1 );
130- if (PWRITE_i.read ()) {
131- trans->set_write ();
132- auto data = PWDATA_i.read ();
133- if (PSTRB_i.get_interface ()) {
134- auto strb = PSTRB_i.read ();
135- auto dptr_begin = std::numeric_limits<unsigned >::max ();
136- auto dptr_end = 0 ;
137- for (size_t j = 0 ; j < DATA_WIDTH / 8 ; ++j) {
138- if (strb[j]) {
139- if (j < dptr_begin)
140- dptr_begin = j;
141- *(trans->get_data_ptr () + dptr_end) = data (8 * j + 7 , 8 * j).to_uint ();
142- dptr_end++;
143- }
144- }
145- trans->set_address ((trans->get_address () & ~(DATA_WIDTH / 8 - 1 )) + dptr_begin);
146- trans->set_data_length (dptr_end);
147- } else
148- for (size_t j = 0 ; j < DATA_WIDTH / 8 ; ++j)
149- *(trans->get_data_ptr () + j) = data (8 * j + 7 , 8 * j).to_uint ();
112+ wait (sc_core::SC_ZERO_TIME);
113+ while (!PSELx_i.read ())
114+ wait (PSELx_i.value_changed_event ());
115+ SCCDEBUG (SCMOD) << " Starting APB setup phase" ;
116+ unsigned length = DATA_WIDTH / 8 ;
117+ auto trans = tlm::scc::tlm_mm<>::get ().allocate <apb::apb_extension>(length);
118+ tlm::scc::tlm_gp_mm::add_data_ptr (length, trans, true );
119+ trans->acquire ();
120+ trans->set_streaming_width (length);
121+ trans->set_address (PADDR_i.read ());
122+ auto * ext = trans->get_extension <apb_extension>();
123+ if (PPROT_i.get_interface ())
124+ ext->set_protection (PPROT_i.read ().to_uint ());
125+ if (PNSE_i.get_interface ())
126+ ext->set_nse (PNSE_i.read ());
127+ if (PWRITE_i.read ()) {
128+ trans->set_write ();
129+ auto data = PWDATA_i.read ();
130+ if (PSTRB_i.get_interface ()) {
131+ auto strb = PSTRB_i.read ();
132+ // Copy all data bytes and use byte enables for sparse strobes
133+ for (size_t j = 0 ; j < DATA_WIDTH / 8 ; ++j) {
134+ *(trans->get_data_ptr () + j) = data (8 * j + 7 , 8 * j).to_uint ();
135+ *(trans->get_byte_enable_ptr () + j) = strb[j] ? 0xFF : 0x00 ;
136+ }
137+ trans->set_byte_enable_length (DATA_WIDTH / 8 );
150138 } else {
151- trans->set_read ();
152- }
153- sc_core::sc_time delay;
154- tlm::tlm_phase phase{tlm::BEGIN_REQ};
155- SCCDEBUG (SCMOD) << " Recv beg req for read to addr 0x" << std::hex << trans->get_address ();
156- auto res = isckt->nb_transport_fw (*trans, phase, delay);
157- if (res == tlm::TLM_ACCEPTED) {
158- waiting4end_req = true ;
159- wait (end_req_evt);
160- phase = tlm::END_REQ;
161- }
162- SCCDEBUG (SCMOD) << " Recv end req for " << (trans->is_write () ? " write to" : " read from" ) << " addr 0x" << std::hex
163- << trans->get_address ();
164- SCCDEBUG (SCMOD) << " APB setup phase, finished" ;
165- wait (PENABLE_i.posedge_event ());
166- if (phase != tlm::BEGIN_RESP) {
167- auto resp = wait4tx (resp_que);
168- sc_assert (trans == resp);
169- }
170- SCCDEBUG (SCMOD) << " Recv beg resp for " << (trans->is_write () ? " write to" : " read from" ) << " addr 0x" << std::hex
171- << trans->get_address () << " , starting access phase" ;
172- delay = sc_core::SC_ZERO_TIME;
173- phase = tlm::END_RESP;
174- res = isckt->nb_transport_fw (*trans, phase, delay);
175- if (trans->is_read ()) {
176- data_t data{0 };
177139 for (size_t j = 0 ; j < DATA_WIDTH / 8 ; ++j)
178- data. range (j * 8 + 7 , j * 8 ) = *(trans-> get_data_ptr () + j );
179- PRDATA_o. write (data );
140+ *(trans-> get_data_ptr () + j) = data ( 8 * j + 7 , 8 * j). to_uint ( );
141+ trans-> set_byte_enable_length ( 0 );
180142 }
181- PREADY_o.write (true );
182- PSLVERR_o.write (trans->get_response_status () != tlm::TLM_OK_RESPONSE);
183- wait (PCLK_i.posedge_event ());
184- SCCDEBUG (SCMOD) << " APB access phase finished" ;
143+ } else {
144+ trans->set_read ();
145+ }
146+ sc_core::sc_time delay;
147+ tlm::tlm_phase phase{tlm::BEGIN_REQ};
148+ SCCDEBUG (SCMOD) << " Recv beg req for read to addr 0x" << std::hex << trans->get_address ();
149+ auto res = isckt->nb_transport_fw (*trans, phase, delay);
150+ if (res == tlm::TLM_ACCEPTED) {
151+ waiting4end_req = true ;
152+ wait (end_req_evt);
153+ phase = tlm::END_REQ;
185154 }
155+ SCCDEBUG (SCMOD) << " Recv end req for " << (trans->is_write () ? " write to" : " read from" ) << " addr 0x" << std::hex
156+ << trans->get_address ();
157+ SCCDEBUG (SCMOD) << " APB setup phase, finished" ;
158+ wait (PENABLE_i.posedge_event ());
159+ if (phase != tlm::BEGIN_RESP) {
160+ auto resp = wait4tx (resp_que);
161+ sc_assert (trans == resp);
162+ }
163+ SCCDEBUG (SCMOD) << " Recv beg resp for " << (trans->is_write () ? " write to" : " read from" ) << " addr 0x" << std::hex
164+ << trans->get_address () << " , starting access phase" ;
165+ delay = sc_core::SC_ZERO_TIME;
166+ phase = tlm::END_RESP;
167+ isckt->nb_transport_fw (*trans, phase, delay);
168+ if (trans->is_read ()) {
169+ data_t data{0 };
170+ for (size_t j = 0 ; j < DATA_WIDTH / 8 ; ++j)
171+ data.range (j * 8 + 7 , j * 8 ) = *(trans->get_data_ptr () + j);
172+ PRDATA_o.write (data);
173+ }
174+ PREADY_o.write (true );
175+ PSLVERR_o.write (trans->get_response_status () != tlm::TLM_OK_RESPONSE);
176+ wait (PCLK_i.posedge_event ());
177+ SCCDEBUG (SCMOD) << " APB access phase finished" ;
186178 }
187179 }
188180}
0 commit comments