@@ -16,6 +16,8 @@ module flow_standby_i2c
1616 output logic [AcqFifoDepthWidth- 1 : 0 ] acq_fifo_depth_o,
1717 input logic acq_fifo_wready_i,
1818
19+ input logic rnw_i,
20+
1921 output logic tx_fifo_rvalid_o,
2022 input logic tx_fifo_rready_i,
2123 output logic [TxFifoWidth- 1 : 0 ] tx_fifo_rdata_o,
@@ -31,12 +33,12 @@ module flow_standby_i2c
3133 input logic response_fifo_wready_i,
3234
3335 // TX FIFO
34- input logic [7 : 0 ] tx_fifo_rdata_i,
36+ input logic [31 : 0 ] tx_fifo_rdata_i,
3537 input logic tx_fifo_rvalid_i,
3638 output logic tx_fifo_rready_o,
3739
3840 // RX FIFO
39- output logic [7 : 0 ] rx_fifo_wdata_o,
41+ output logic [31 : 0 ] rx_fifo_wdata_o,
4042 output logic rx_fifo_wvalid_o,
4143 input logic rx_fifo_wready_i,
4244
@@ -59,6 +61,8 @@ module flow_standby_i2c
5961 state_t state_d, state_q;
6062 // Buffer for holding elements returned by I2C target FSM
6163 logic [AcqFifoWidth- 1 : 0 ] fifo_buf[4 ];
64+ // FF for storing data to be sent over I2C
65+ logic [31 : 0 ] tx_fifo_rdata_d;
6266 // Are we currently mid-transfer?
6367 logic transfer_active;
6468 // Number of data bytes held in `fifo_buf`
@@ -86,31 +90,65 @@ module flow_standby_i2c
8690 logic is_start_read;
8791 logic xfer_read;
8892 logic pop_command_from_tti;
93+ logic pop_dword_from_tti;
8994 logic pop_data_from_tti;
95+ logic acq_fifo_wvalid_d;
96+
97+ logic [AcqFifoWidth- 1 : 0 ] acq_fifo_wdata_d;
9098
91- assign rx_fifo_wdata_o = fifo_buf[0 ][ 7 : 0 ];
99+ assign rx_fifo_wdata_o = { fifo_buf[3 ][ 7 : 0 ], fifo_buf[ 2 ][ 7 : 0 ], fifo_buf[ 1 ][ 7 : 0 ], fifo_buf[ 0 ][ 7 : 0 ] } ;
92100 assign byte_count = transaction_byte_count[1 : 0 ];
93101
94102 assign acq_fifo_wdata_byte_id = i2c_acq_byte_id_e ' (acq_fifo_wdata_i[AcqFifoWidth- 1 : 8 ]);
95- assign start_detected = acq_fifo_wvalid_i & (acq_fifo_wdata_byte_id == AcqStart);
96- assign stop_detected = acq_fifo_wvalid_i & (acq_fifo_wdata_byte_id == AcqStop);
97- assign data_detected = acq_fifo_wvalid_i & (acq_fifo_wdata_byte_id == AcqData);
98- assign nack_detected = acq_fifo_wvalid_i & (acq_fifo_wdata_byte_id == AcqNack);
99- assign restart_detected = acq_fifo_wvalid_i & (acq_fifo_wdata_byte_id == AcqRestart);
100- assign is_start_read = acq_fifo_wvalid_i &
101- ( acq_fifo_wdata_byte_id == AcqStart ||
102- acq_fifo_wdata_byte_id == AcqRestart ||
103- acq_fifo_wdata_byte_id == AcqNackStart );
104-
105- // TODO: Bug: Set proper ACQ FIFO depth
106- // [LINT_ERROR: CombLoop] The signal 'acq_fifo_depth_o' is on a comb loop
107- // path between the 'flow_standby_i2c' and 'i2c_target_fsm' modules, e.g.:
108- // In 'flow_standby_i2c':
109- // acq_fifo_wvalid_i -> state_d -> acq_fifo_depth_o
110- // In 'i2c_target_fsm':
111- // acq_fifo_depth_i -> stretch_addr -> acq_fifo_wvalid_o
103+ always_ff @ (posedge clk_i or negedge rst_ni) begin : control_ff
104+ if (! rst_ni) begin
105+ start_detected <= '0 ;
106+ stop_detected <= '0 ;
107+ data_detected <= '0 ;
108+ nack_detected <= '0 ;
109+ restart_detected <= '0 ;
110+ is_start_read <= '0 ;
111+ acq_fifo_wvalid_d <= '0 ;
112+ acq_fifo_wdata_d <= '0 ;
113+ end else begin
114+ start_detected <= acq_fifo_wvalid_i & (acq_fifo_wdata_byte_id == AcqStart);
115+ stop_detected <= acq_fifo_wvalid_i & (acq_fifo_wdata_byte_id == AcqStop);
116+ data_detected <= acq_fifo_wvalid_i & (acq_fifo_wdata_byte_id == AcqData);
117+ nack_detected <= acq_fifo_wvalid_i & (acq_fifo_wdata_byte_id == AcqNack);
118+ restart_detected <= acq_fifo_wvalid_i & (acq_fifo_wdata_byte_id == AcqRestart);
119+ is_start_read <= acq_fifo_wvalid_i & rnw_i;
120+ acq_fifo_wvalid_d <= acq_fifo_wvalid_i;
121+ acq_fifo_wdata_d <= acq_fifo_wdata_i;
122+ end
123+ end
124+
125+ // store data to send
126+ always_ff @ (posedge clk_i or negedge rst_ni) begin : latch_tx_data
127+ if (! rst_ni) begin
128+ tx_fifo_rdata_d <= '0 ;
129+ end else begin
130+ if (tx_fifo_rready_o) tx_fifo_rdata_d <= tx_fifo_rdata_i;
131+ end
132+ end
133+
134+ always_comb
135+ case (byte_count)
136+ 0 : begin
137+ tx_fifo_rdata_o = tx_fifo_rdata_d[7 : 0 ];
138+ end
139+ 1 : begin
140+ tx_fifo_rdata_o = tx_fifo_rdata_d[15 : 8 ];
141+ end
142+ 2 : begin
143+ tx_fifo_rdata_o = tx_fifo_rdata_d[23 : 16 ];
144+ end
145+ 3 : begin
146+ tx_fifo_rdata_o = tx_fifo_rdata_d[31 : 24 ];
147+ end
148+ endcase
149+
112150 assign acq_fifo_depth_o = xfer_read ? 0 : {{ (AcqFifoDepthWidth - 3 ){ 1'b0 }} ,
113- state_d == PushDWordToTTIQueue,
151+ state_q == PushDWordToTTIQueue,
114152 transaction_byte_count[1 : 0 ]} ;
115153
116154 always_ff @ (posedge clk_i or negedge rst_ni) begin : state_transition
@@ -127,13 +165,7 @@ module flow_standby_i2c
127165 if (! xfer_read) begin
128166 // Write transfer
129167 if (data_detected) begin
130- fifo_buf[byte_count] <= acq_fifo_wdata_i;
131- end
132- end else begin
133- // Read transfer
134- if (pop_data_from_tti) begin
135- // TODO(verilator) fails to consftify loop variable for AstSelExtract
136- fifo_buf[0 ] <= { AcqData, tx_fifo_rdata_i[7 : 0 ]} ;
168+ fifo_buf[byte_count] <= acq_fifo_wdata_d;
137169 end
138170 end
139171 end
@@ -190,7 +222,7 @@ module flow_standby_i2c
190222 end : get_command_from_tti
191223
192224 // State combo logic
193-
225+ assign pop_data_from_tti = tx_fifo_rvalid_i & xfer_read & (push_byte | pop_dword_from_tti);
194226 always_comb begin : state_outputs
195227 err_o = 0 ;
196228 rx_fifo_wvalid_o = 0 ;
@@ -204,7 +236,7 @@ module flow_standby_i2c
204236 tx_fifo_rready_o = 0 ;
205237 tx_fifo_rvalid_o = 0 ;
206238 pop_command_from_tti = 0 ;
207- pop_data_from_tti = 0 ;
239+ pop_dword_from_tti = 0 ;
208240
209241 unique case (state_q)
210242 AwaitStart: begin
@@ -226,21 +258,20 @@ module flow_standby_i2c
226258 cmd_fifo_rready_o = 1 ;
227259 tx_fifo_rready_o = 1 ;
228260 pop_command_from_tti = cmd_fifo_rvalid_i;
229- pop_data_from_tti = tx_fifo_rvalid_i;
230261 xfer_read = 1 ;
231262 end
232263 PopDWordFromTTIQueue: begin
233264 tx_fifo_rready_o = 1 ;
234- pop_data_from_tti = tx_fifo_rvalid_i;
235265 xfer_read = 1 ;
266+ pop_dword_from_tti = 1 ;
236267 end
237268 SendByte: begin
238269 xfer_read = 1 ;
239- push_byte = tx_fifo_rready_i;
240270 tx_fifo_rvalid_o = 1 ;
241271 end
242272 SwitchByteToSend: begin
243273 xfer_read = 1 ;
274+ push_byte = 1 ; // tx_fifo_rvalid_i;
244275 end
245276 AwaitStopOrRestart: begin
246277 end
@@ -250,9 +281,6 @@ module flow_standby_i2c
250281
251282 activate_transfer = start_detected;
252283 deactivate_transfer = stop_detected | restart_detected;
253-
254- if (xfer_read) tx_fifo_rdata_o = fifo_buf[byte_count][7 : 0 ];
255- else tx_fifo_rdata_o = 0 ;
256284 end : state_outputs
257285
258286 always_comb begin : state_function
@@ -268,7 +296,7 @@ module flow_standby_i2c
268296 if (stop_detected | restart_detected) begin
269297 state_d = (byte_count != 0 ) ? PushDWordToTTIQueue : PushResponseToTTIQueue;
270298 end else if (data_detected) state_d = (byte_count == 3 ) ? PushDWordToTTIQueue : ReceiveByte;
271- else if (acq_fifo_wvalid_i ) state_d = ReportError;
299+ else if (acq_fifo_wvalid_d ) state_d = ReportError;
272300 end
273301 PushDWordToTTIQueue:
274302 if (rx_fifo_wready_i) state_d = transfer_active ? ReceiveByte : PushResponseToTTIQueue;
@@ -278,18 +306,18 @@ module flow_standby_i2c
278306 // but invalidated one cycle later.
279307 if (stop_detected | restart_detected)
280308 state_d = PushDWordToTTIQueue;
281- else state_d = acq_fifo_wvalid_i ? ReportError : PushDWordToTTIQueue;
309+ else state_d = acq_fifo_wvalid_d ? ReportError : PushDWordToTTIQueue;
282310 PushResponseToTTIQueue: begin
283311 state_d = PushResponseToTTIQueue;
284312 if (response_fifo_wready_i) state_d = AwaitStart;
285313 // We can't wait any longer if there's a new byte, because we might be full
286- else if (acq_fifo_wvalid_i ) state_d = ReportError;
314+ else if (acq_fifo_wvalid_d ) state_d = ReportError;
287315 end
288316 PopCommandFromTTIQueue: begin
289317 state_d = PopCommandFromTTIQueue;
290318 if (cmd_fifo_rvalid_i) begin
291319 if (cmd_fifo_rdata_i.data_length == 0 ) state_d = ReportError;
292- else state_d = tx_fifo_rvalid_i ? SendByte : PopDWordFromTTIQueue ;
320+ else state_d = (byte_count == 3 ) ? PopDWordFromTTIQueue : SendByte ;
293321 end
294322 if (nack_detected) state_d = ReportError;
295323 end
@@ -300,17 +328,20 @@ module flow_standby_i2c
300328 end
301329 SendByte: begin
302330 state_d = SendByte;
303- if (tx_fifo_rready_i)
304- if (transaction_byte_count + 1 == read_transaction_length) state_d = AwaitStopOrRestart;
331+ if (tx_fifo_rready_i == 1'b1 ) begin
332+ if (transaction_byte_count + 1 == read_transaction_length) begin
333+ state_d = AwaitStopOrRestart;
334+ end
305335 else
306336 // Let the counter increment in a another cycle, so we hold tx_fifo_rvalid
307337 // with the correct byte set
308338 state_d = SwitchByteToSend;
339+ end
309340 if (nack_detected) state_d = ReportError;
310341 end
311342 SwitchByteToSend: begin
312343 state_d = SendByte;
313- if ((byte_count == 0 ) & (transaction_byte_count != read_transaction_length))
344+ if ((byte_count == 3 ) & (transaction_byte_count != read_transaction_length))
314345 state_d = PopDWordFromTTIQueue;
315346 if (nack_detected) state_d = ReportError;
316347 end
0 commit comments