@@ -16,6 +16,8 @@ module flow_standby_i2c
16
16
output logic [AcqFifoDepthWidth- 1 : 0 ] acq_fifo_depth_o,
17
17
input logic acq_fifo_wready_i,
18
18
19
+ input logic rnw_i,
20
+
19
21
output logic tx_fifo_rvalid_o,
20
22
input logic tx_fifo_rready_i,
21
23
output logic [TxFifoWidth- 1 : 0 ] tx_fifo_rdata_o,
@@ -31,12 +33,12 @@ module flow_standby_i2c
31
33
input logic response_fifo_wready_i,
32
34
33
35
// TX FIFO
34
- input logic [7 : 0 ] tx_fifo_rdata_i,
36
+ input logic [31 : 0 ] tx_fifo_rdata_i,
35
37
input logic tx_fifo_rvalid_i,
36
38
output logic tx_fifo_rready_o,
37
39
38
40
// RX FIFO
39
- output logic [7 : 0 ] rx_fifo_wdata_o,
41
+ output logic [31 : 0 ] rx_fifo_wdata_o,
40
42
output logic rx_fifo_wvalid_o,
41
43
input logic rx_fifo_wready_i,
42
44
@@ -59,6 +61,8 @@ module flow_standby_i2c
59
61
state_t state_d, state_q;
60
62
// Buffer for holding elements returned by I2C target FSM
61
63
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;
62
66
// Are we currently mid-transfer?
63
67
logic transfer_active;
64
68
// Number of data bytes held in `fifo_buf`
@@ -86,31 +90,65 @@ module flow_standby_i2c
86
90
logic is_start_read;
87
91
logic xfer_read;
88
92
logic pop_command_from_tti;
93
+ logic pop_dword_from_tti;
89
94
logic pop_data_from_tti;
95
+ logic acq_fifo_wvalid_d;
96
+
97
+ logic [AcqFifoWidth- 1 : 0 ] acq_fifo_wdata_d;
90
98
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 ] } ;
92
100
assign byte_count = transaction_byte_count[1 : 0 ];
93
101
94
102
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
+
112
150
assign acq_fifo_depth_o = xfer_read ? 0 : {{ (AcqFifoDepthWidth - 3 ){ 1'b0 }} ,
113
- state_d == PushDWordToTTIQueue,
151
+ state_q == PushDWordToTTIQueue,
114
152
transaction_byte_count[1 : 0 ]} ;
115
153
116
154
always_ff @ (posedge clk_i or negedge rst_ni) begin : state_transition
@@ -127,13 +165,7 @@ module flow_standby_i2c
127
165
if (! xfer_read) begin
128
166
// Write transfer
129
167
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;
137
169
end
138
170
end
139
171
end
@@ -190,7 +222,7 @@ module flow_standby_i2c
190
222
end : get_command_from_tti
191
223
192
224
// State combo logic
193
-
225
+ assign pop_data_from_tti = tx_fifo_rvalid_i & xfer_read & (push_byte | pop_dword_from_tti);
194
226
always_comb begin : state_outputs
195
227
err_o = 0 ;
196
228
rx_fifo_wvalid_o = 0 ;
@@ -204,7 +236,7 @@ module flow_standby_i2c
204
236
tx_fifo_rready_o = 0 ;
205
237
tx_fifo_rvalid_o = 0 ;
206
238
pop_command_from_tti = 0 ;
207
- pop_data_from_tti = 0 ;
239
+ pop_dword_from_tti = 0 ;
208
240
209
241
unique case (state_q)
210
242
AwaitStart: begin
@@ -226,21 +258,20 @@ module flow_standby_i2c
226
258
cmd_fifo_rready_o = 1 ;
227
259
tx_fifo_rready_o = 1 ;
228
260
pop_command_from_tti = cmd_fifo_rvalid_i;
229
- pop_data_from_tti = tx_fifo_rvalid_i;
230
261
xfer_read = 1 ;
231
262
end
232
263
PopDWordFromTTIQueue: begin
233
264
tx_fifo_rready_o = 1 ;
234
- pop_data_from_tti = tx_fifo_rvalid_i;
235
265
xfer_read = 1 ;
266
+ pop_dword_from_tti = 1 ;
236
267
end
237
268
SendByte: begin
238
269
xfer_read = 1 ;
239
- push_byte = tx_fifo_rready_i;
240
270
tx_fifo_rvalid_o = 1 ;
241
271
end
242
272
SwitchByteToSend: begin
243
273
xfer_read = 1 ;
274
+ push_byte = 1 ; // tx_fifo_rvalid_i;
244
275
end
245
276
AwaitStopOrRestart: begin
246
277
end
@@ -250,9 +281,6 @@ module flow_standby_i2c
250
281
251
282
activate_transfer = start_detected;
252
283
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 ;
256
284
end : state_outputs
257
285
258
286
always_comb begin : state_function
@@ -268,7 +296,7 @@ module flow_standby_i2c
268
296
if (stop_detected | restart_detected) begin
269
297
state_d = (byte_count != 0 ) ? PushDWordToTTIQueue : PushResponseToTTIQueue;
270
298
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;
272
300
end
273
301
PushDWordToTTIQueue:
274
302
if (rx_fifo_wready_i) state_d = transfer_active ? ReceiveByte : PushResponseToTTIQueue;
@@ -278,18 +306,18 @@ module flow_standby_i2c
278
306
// but invalidated one cycle later.
279
307
if (stop_detected | restart_detected)
280
308
state_d = PushDWordToTTIQueue;
281
- else state_d = acq_fifo_wvalid_i ? ReportError : PushDWordToTTIQueue;
309
+ else state_d = acq_fifo_wvalid_d ? ReportError : PushDWordToTTIQueue;
282
310
PushResponseToTTIQueue: begin
283
311
state_d = PushResponseToTTIQueue;
284
312
if (response_fifo_wready_i) state_d = AwaitStart;
285
313
// 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;
287
315
end
288
316
PopCommandFromTTIQueue: begin
289
317
state_d = PopCommandFromTTIQueue;
290
318
if (cmd_fifo_rvalid_i) begin
291
319
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 ;
293
321
end
294
322
if (nack_detected) state_d = ReportError;
295
323
end
@@ -300,17 +328,20 @@ module flow_standby_i2c
300
328
end
301
329
SendByte: begin
302
330
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
305
335
else
306
336
// Let the counter increment in a another cycle, so we hold tx_fifo_rvalid
307
337
// with the correct byte set
308
338
state_d = SwitchByteToSend;
339
+ end
309
340
if (nack_detected) state_d = ReportError;
310
341
end
311
342
SwitchByteToSend: begin
312
343
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))
314
345
state_d = PopDWordFromTTIQueue;
315
346
if (nack_detected) state_d = ReportError;
316
347
end
0 commit comments