@@ -13,6 +13,7 @@ export Pins(..);
13
13
export I2CCore ( ..) ;
14
14
export mkI2CCore ;
15
15
16
+ import ConfigReg :: * ;
16
17
import DefaultValue :: * ;
17
18
import DReg :: * ;
18
19
import FIFO :: * ;
@@ -105,40 +106,57 @@ module mkI2CCore#(Integer core_clk_freq,
105
106
Reg # ( Bool ) in_random_read < - mkReg( False ) ;
106
107
Reg # ( Bool ) in_write_ack_poll < - mkReg( False ) ;
107
108
Reg # ( Bool ) write_acked < - mkReg( False ) ;
108
-
109
+ ConfigReg# ( Bool ) state_cleared < - mkConfigReg( False ) ;
110
+ Reg # ( Bool ) clearing_state < - mkReg( False ) ;
111
+ PulseWire clear_state < - mkPulseWire;
109
112
PulseWire next_send_data < - mkPulseWire;
110
113
111
- // relabel this net for brevity
112
- let timed_out = bit_ctrl.scl_stretch_timeout;
113
-
114
114
(* fire_when_enabled, no_implicit_conditions *)
115
115
rule do_valid_command;
116
116
valid_command <= isValid( cur_command) ;
117
117
endrule
118
118
119
119
// when the bit controller has timed out, clear core state
120
120
(* fire_when_enabled *)
121
- rule do_handle_stretch_timeout( timed_out) ;
122
- next_command.clear() ;
123
- error_r <= tagged Invalid;
124
- state_r <= Idle;
121
+ rule do_clearing_state_reg;
122
+ clearing_state <= ( bit_ctrl.scl_stretch_timeout && ! state_cleared) || clear_state;
125
123
endrule
126
124
127
125
(* fire_when_enabled *)
128
- rule do_register_command( state_r == Idle && ! valid_command && ! timed_out) ;
129
- cur_command <= tagged Valid next_command.first;
130
- error_r <= tagged Invalid;
131
- state_r <= SendStart;
126
+ rule do_handle_stretch_timeout( clearing_state) ;
127
+ next_command.deq() ;
128
+ bytes_done <= 0 ;
129
+ in_random_read <= False ;
130
+ in_write_ack_poll <= False ;
131
+ write_acked <= False ;
132
+ cur_command <= tagged Invalid;
133
+ state_r <= Idle;
132
134
endrule
133
135
134
136
(* fire_when_enabled *)
135
- rule do_send_start ( state_r == SendStart && valid_command && ! timed_out) ;
137
+ rule do_state_cleared_reg;
138
+ if ( clearing_state) begin
139
+ state_cleared <= True ;
140
+ end else if ( valid_command && bit_ctrl.busy()) begin
141
+ state_cleared <= False ;
142
+ end
143
+ endrule
144
+
145
+ (* fire_when_enabled *)
146
+ rule do_register_command( state_r == Idle && ! valid_command && ! clearing_state) ;
147
+ cur_command <= tagged Valid next_command.first;
148
+ error_r <= tagged Invalid;
149
+ state_r <= SendStart;
150
+ endrule
151
+
152
+ (* fire_when_enabled *)
153
+ rule do_send_start ( state_r == SendStart && valid_command && ! clearing_state) ;
136
154
bit_ctrl.send.put( tagged Start) ;
137
155
state_r <= SendAddr;
138
156
endrule
139
157
140
158
(* fire_when_enabled *)
141
- rule do_send_addr ( state_r == SendAddr && valid_command && ! timed_out ) ;
159
+ rule do_send_addr ( state_r == SendAddr && valid_command && ! clearing_state ) ;
142
160
let cmd = fromMaybe( ? , cur_command) ;
143
161
let is_read = ( cmd.op == Read) || in_random_read;
144
162
let addr_byte = { cmd.i2c_addr, pack( is_read) } ;
@@ -149,21 +167,22 @@ module mkI2CCore#(Integer core_clk_freq,
149
167
(* fire_when_enabled *)
150
168
rule do_await_addr_ack ( state_r == AwaitAddrAck
151
169
&& valid_command
152
- && ! timed_out ) ;
170
+ && ! clearing_state ) ;
153
171
let ack_nack < - bit_ctrl.receive.get() ;
154
172
let cmd = fromMaybe( ? , cur_command) ;
155
173
156
174
case ( ack_nack) matches
157
175
tagged Ack: begin
158
- // Begin a Read
159
176
if ( cmd.op == Read || in_random_read) begin
177
+ // begin a Read
160
178
bytes_done <= 1 ;
161
179
bit_ctrl.send.put( tagged Read ( cmd.num_bytes == 1 )) ;
162
180
state_r <= Reading;
163
181
end else if ( in_write_ack_poll) begin
164
182
write_acked <= True ;
165
183
state_r <= Stop;
166
184
end else begin
185
+ // begin a Write
167
186
bit_ctrl.send.put( tagged Write cmd.reg_addr) ;
168
187
state_r <= AwaitWriteAck;
169
188
end
@@ -180,7 +199,7 @@ module mkI2CCore#(Integer core_clk_freq,
180
199
endrule
181
200
182
201
(* fire_when_enabled *)
183
- rule do_writing ( state_r == Writing && valid_command && ! timed_out ) ;
202
+ rule do_writing ( state_r == Writing && valid_command && ! clearing_state ) ;
184
203
bit_ctrl.send.put( tagged Write tx_data) ;
185
204
next_send_data.send() ;
186
205
state_r <= AwaitWriteAck;
@@ -189,7 +208,7 @@ module mkI2CCore#(Integer core_clk_freq,
189
208
(* fire_when_enabled *)
190
209
rule do_await_writing_ack ( state_r == AwaitWriteAck
191
210
&& valid_command
192
- && ! timed_out ) ;
211
+ && ! clearing_state ) ;
193
212
let ack_nack < - bit_ctrl.receive.get() ;
194
213
let cmd = fromMaybe( ? , cur_command) ;
195
214
@@ -215,7 +234,7 @@ module mkI2CCore#(Integer core_clk_freq,
215
234
endrule
216
235
217
236
(* fire_when_enabled *)
218
- rule do_reading ( state_r == Reading && valid_command && ! timed_out ) ;
237
+ rule do_reading ( state_r == Reading && valid_command && ! clearing_state ) ;
219
238
let rdata < - bit_ctrl.receive.get() ;
220
239
let cmd = fromMaybe( ? , cur_command) ;
221
240
@@ -233,14 +252,14 @@ module mkI2CCore#(Integer core_clk_freq,
233
252
endcase
234
253
endrule
235
254
236
- rule do_next_read ( state_r == NextRead && valid_command && ! timed_out ) ;
255
+ rule do_next_read ( state_r == NextRead && valid_command && ! clearing_state ) ;
237
256
let cmd = fromMaybe( ? , cur_command) ;
238
257
bit_ctrl.send.put( tagged Read ( cmd.num_bytes == bytes_done)) ;
239
258
state_r <= Reading;
240
259
endrule
241
260
242
261
(* fire_when_enabled *)
243
- rule do_stop ( state_r == Stop && valid_command && ! timed_out ) ;
262
+ rule do_stop ( state_r == Stop && valid_command && ! clearing_state ) ;
244
263
bit_ctrl.send.put( tagged Stop) ;
245
264
246
265
let cmd = fromMaybe( ? , cur_command) ;
@@ -253,14 +272,8 @@ module mkI2CCore#(Integer core_clk_freq,
253
272
endrule
254
273
255
274
(* fire_when_enabled *)
256
- rule do_done ( state_r == Done && valid_command && ! timed_out) ;
257
- next_command.deq() ;
258
- bytes_done <= 0 ;
259
- in_random_read <= False ;
260
- in_write_ack_poll <= False ;
261
- write_acked <= False ;
262
- cur_command <= tagged Invalid;
263
- state_r <= Idle;
275
+ rule do_done ( state_r == Done && valid_command && ! clearing_state && ! bit_ctrl.busy()) ;
276
+ clear_state.send() ;
264
277
endrule
265
278
266
279
interface pins = bit_ctrl.pins;
0 commit comments