Skip to content

Commit 5dfd3df

Browse files
committed
asdf
1 parent de6d3ea commit 5dfd3df

File tree

7 files changed

+258
-115
lines changed

7 files changed

+258
-115
lines changed

hdl/ip/bsv/I2C/I2CBitController.bsv

+7
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ interface I2CBitController;
4848
interface Put#(Event) send;
4949
interface Get#(Event) receive;
5050

51+
// way of indicating when there is no bus activity
52+
method Bool busy();
53+
5154
// clock stretching information sent sideband from the state machine events
5255
method Bool scl_stretch_seen();
5356
method Bool scl_stretch_timeout();
@@ -251,6 +254,8 @@ module mkI2CBitController #(
251254
(* fire_when_enabled *)
252255
rule do_scl_stretch_timeout(scl_stretch_timeout_cntr);
253256
state <= AwaitStart;
257+
scl_active <= False;
258+
sda_out_en <= 0;
254259
scl_stretch_timeout_r <= True;
255260
incoming_events.clear();
256261
endrule
@@ -416,6 +421,8 @@ module mkI2CBitController #(
416421
endinterface
417422
interface Get receive = toGet(outgoing_events);
418423

424+
method busy = state != AwaitStart;
425+
419426
method scl_stretch_seen = scl_stretch_seen_r;
420427
method scl_stretch_timeout = scl_stretch_timeout_r;
421428
endmodule

hdl/ip/bsv/I2C/I2CCore.bsv

+42-29
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export Pins(..);
1313
export I2CCore(..);
1414
export mkI2CCore;
1515

16+
import ConfigReg::*;
1617
import DefaultValue::*;
1718
import DReg::*;
1819
import FIFO::*;
@@ -105,40 +106,57 @@ module mkI2CCore#(Integer core_clk_freq,
105106
Reg#(Bool) in_random_read <- mkReg(False);
106107
Reg#(Bool) in_write_ack_poll <- mkReg(False);
107108
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;
109112
PulseWire next_send_data <- mkPulseWire;
110113

111-
// relabel this net for brevity
112-
let timed_out = bit_ctrl.scl_stretch_timeout;
113-
114114
(* fire_when_enabled, no_implicit_conditions *)
115115
rule do_valid_command;
116116
valid_command <= isValid(cur_command);
117117
endrule
118118

119119
// when the bit controller has timed out, clear core state
120120
(* 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;
125123
endrule
126124

127125
(* 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;
132134
endrule
133135

134136
(* 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);
136154
bit_ctrl.send.put(tagged Start);
137155
state_r <= SendAddr;
138156
endrule
139157

140158
(* 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);
142160
let cmd = fromMaybe(?, cur_command);
143161
let is_read = (cmd.op == Read) || in_random_read;
144162
let addr_byte = {cmd.i2c_addr, pack(is_read)};
@@ -149,21 +167,22 @@ module mkI2CCore#(Integer core_clk_freq,
149167
(* fire_when_enabled *)
150168
rule do_await_addr_ack (state_r == AwaitAddrAck
151169
&& valid_command
152-
&& !timed_out);
170+
&& !clearing_state);
153171
let ack_nack <- bit_ctrl.receive.get();
154172
let cmd = fromMaybe(?, cur_command);
155173

156174
case (ack_nack) matches
157175
tagged Ack: begin
158-
// Begin a Read
159176
if (cmd.op == Read || in_random_read) begin
177+
// begin a Read
160178
bytes_done <= 1;
161179
bit_ctrl.send.put(tagged Read (cmd.num_bytes == 1));
162180
state_r <= Reading;
163181
end else if (in_write_ack_poll) begin
164182
write_acked <= True;
165183
state_r <= Stop;
166184
end else begin
185+
// begin a Write
167186
bit_ctrl.send.put(tagged Write cmd.reg_addr);
168187
state_r <= AwaitWriteAck;
169188
end
@@ -180,7 +199,7 @@ module mkI2CCore#(Integer core_clk_freq,
180199
endrule
181200

182201
(* 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);
184203
bit_ctrl.send.put(tagged Write tx_data);
185204
next_send_data.send();
186205
state_r <= AwaitWriteAck;
@@ -189,7 +208,7 @@ module mkI2CCore#(Integer core_clk_freq,
189208
(* fire_when_enabled *)
190209
rule do_await_writing_ack (state_r == AwaitWriteAck
191210
&& valid_command
192-
&& !timed_out);
211+
&& !clearing_state);
193212
let ack_nack <- bit_ctrl.receive.get();
194213
let cmd = fromMaybe(?, cur_command);
195214

@@ -215,7 +234,7 @@ module mkI2CCore#(Integer core_clk_freq,
215234
endrule
216235

217236
(* 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);
219238
let rdata <- bit_ctrl.receive.get();
220239
let cmd = fromMaybe(?, cur_command);
221240

@@ -233,14 +252,14 @@ module mkI2CCore#(Integer core_clk_freq,
233252
endcase
234253
endrule
235254

236-
rule do_next_read (state_r == NextRead && valid_command && !timed_out);
255+
rule do_next_read (state_r == NextRead && valid_command && !clearing_state);
237256
let cmd = fromMaybe(?, cur_command);
238257
bit_ctrl.send.put(tagged Read (cmd.num_bytes == bytes_done));
239258
state_r <= Reading;
240259
endrule
241260

242261
(* 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);
244263
bit_ctrl.send.put(tagged Stop);
245264

246265
let cmd = fromMaybe(?, cur_command);
@@ -253,14 +272,8 @@ module mkI2CCore#(Integer core_clk_freq,
253272
endrule
254273

255274
(* 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();
264277
endrule
265278

266279
interface pins = bit_ctrl.pins;

hdl/ip/bsv/I2C/test/I2CBitControllerTests.bsv

+2-3
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@ module mkBench (Bench);
8989
Reg#(Vector#(3,Bit#(8))) prev_written_bytes <- mkReg(replicate(0));
9090
Reg#(UInt#(2)) bytes_done <- mkReg(0);
9191
Reg#(Bool) is_last_byte <- mkReg(False);
92-
Reg#(Bool) stretch_timeout <- mkReg(False);
9392

9493
FSM write_seq <- mkFSMWithPred(seq
9594
dut.send.put(tagged Start);
@@ -120,7 +119,7 @@ module mkBench (Bench);
120119

121120
dut.send.put(tagged Stop);
122121
check_peripheral_event(periph, tagged ReceivedStop, "Expected to receive STOP");
123-
endseq, command_r.op == Write && !stretch_timeout);
122+
endseq, command_r.op == Write && !dut.scl_stretch_timeout);
124123

125124
FSM read_seq <- mkFSMWithPred(seq
126125
dut.send.put(tagged Start);
@@ -153,7 +152,7 @@ module mkBench (Bench);
153152

154153
dut.send.put(tagged Stop);
155154
check_peripheral_event(periph, tagged ReceivedStop, "Expected to receive STOP");
156-
endseq, command_r.op == Read && !stretch_timeout);
155+
endseq, command_r.op == Read && !dut.scl_stretch_timeout);
157156

158157
FSM rnd_read_seq <- mkFSMWithPred(seq
159158
dut.send.put(tagged Start);

hdl/ip/bsv/I2C/test/I2CCoreTests.bsv

+3-3
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ module mkBench (Bench);
135135
endaction
136136
endseq
137137
check_peripheral_event(periph, tagged ReceivedStop, "Expected to receive STOP");
138-
endseq, command_r.op == Write);
138+
endseq, command_r.op == Write && !dut.scl_stretch_timeout);
139139

140140
FSM read_seq <- mkFSMWithPred(seq
141141
dut.send_command.put(command_r);
@@ -156,7 +156,7 @@ module mkBench (Bench);
156156
check_peripheral_event(periph, tagged ReceivedNack, "Expected to receive NACK to end the Read");
157157
check_peripheral_event(periph, tagged ReceivedStop, "Expected to receive STOP");
158158
bytes_done <= 0;
159-
endseq, command_r.op == Read);
159+
endseq, command_r.op == Read && !dut.scl_stretch_timeout);
160160

161161
FSM rand_read_seq <- mkFSMWithPred(seq
162162
dut.send_command.put(command_r);
@@ -181,7 +181,7 @@ module mkBench (Bench);
181181
check_peripheral_event(periph, tagged ReceivedNack, "Expected to receive NACK to end the Read");
182182
check_peripheral_event(periph, tagged ReceivedStop, "Expected to receive STOP");
183183
bytes_done <= 0;
184-
endseq, command_r.op == RandomRead);
184+
endseq, command_r.op == RandomRead && !dut.scl_stretch_timeout);
185185

186186
rule do_handle_stretch_timeout(dut.scl_stretch_timeout);
187187
write_seq.abort();

hdl/ip/bsv/I2C/test/I2CPeripheralModel.bsv

+24-10
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ interface I2CPeripheralModel;
3434
method Action nack_response(Bool ack);
3535
method Action stretch_next(Bool timeout);
3636
method Action bus_pullups(Bool present);
37+
method Action reset_device;
3738
endinterface
3839

3940
typedef union tagged {
@@ -111,7 +112,8 @@ module mkI2CPeripheralModel #(Bit#(7) i2c_address,
111112
Reg#(Bool) countdown_reset <- mkReg(False);
112113
Reg#(Bool) back_to_rx <- mkReg(False);
113114

114-
ConfigReg#(Bool) pullups_lost <- mkConfigReg(False);
115+
ConfigReg#(Bool) pullups_lost <- mkConfigReg(False);
116+
PulseWire reset_device_ <- mkPulseWire();
115117

116118
(* fire_when_enabled *)
117119
rule do_detect_scl_fedge;
@@ -149,13 +151,19 @@ module mkI2CPeripheralModel #(Bit#(7) i2c_address,
149151
scl_stretch_countdown <= 0;
150152
endrule
151153

154+
(* fire_when_enabled *)
155+
rule do_reset_state (reset_device_);
156+
state <= AwaitStartByte;
157+
outgoing_events.clear();
158+
endrule
159+
152160
(* fire_when_enabled *)
153161
rule do_scl_stretch_tick(state == SclStretch && scl_in == 1);
154162
scl_stretch_countdown.send();
155163
endrule
156164

157165
(* fire_when_enabled *)
158-
rule do_await_start (state == AwaitStartByte);
166+
rule do_await_start (!reset_device_ && state == AwaitStartByte);
159167
shift_bits <= shift_bits_reset;
160168
is_sequential <= False;
161169
if (start_detected) begin
@@ -165,7 +173,7 @@ module mkI2CPeripheralModel #(Bit#(7) i2c_address,
165173
endrule
166174

167175
(* fire_when_enabled *)
168-
rule do_receive_start_byte (state == ReceiveStartByte);
176+
rule do_receive_start_byte (!reset_device_ && state == ReceiveStartByte);
169177
addr_set <= False;
170178
if (scl_redge) begin
171179
case (last(shift_bits)) matches
@@ -189,11 +197,10 @@ module mkI2CPeripheralModel #(Bit#(7) i2c_address,
189197
end
190198
end
191199
endcase
192-
193200
endrule
194201

195202
(* fire_when_enabled *)
196-
rule do_receive_byte (state == ReceiveByte);
203+
rule do_receive_byte (!reset_device_ && state == ReceiveByte);
197204
if (stop_detected) begin
198205
state <= AwaitStartByte;
199206
outgoing_events.enq(tagged ReceivedStop);
@@ -238,7 +245,7 @@ module mkI2CPeripheralModel #(Bit#(7) i2c_address,
238245
endrule
239246

240247
(* fire_when_enabled *)
241-
rule do_transmit_byte (state == TransmitByte);
248+
rule do_transmit_byte (!reset_device_ && state == TransmitByte);
242249
if (scl_stretch_countdown.count() > 0) begin
243250
state <= SclStretch;
244251
back_to_rx <= False;
@@ -258,7 +265,7 @@ module mkI2CPeripheralModel #(Bit#(7) i2c_address,
258265
endrule
259266

260267
(* fire_when_enabled *)
261-
rule do_receive_ack (state == ReceiveAck);
268+
rule do_receive_ack (!reset_device_ && state == ReceiveAck);
262269
if (scl_redge) begin
263270
if (sda_in == 0) begin
264271
// ACK'd, set up next byte to read
@@ -276,7 +283,7 @@ module mkI2CPeripheralModel #(Bit#(7) i2c_address,
276283
endrule
277284

278285
(* fire_when_enabled *)
279-
rule do_transmit_ack (state == TransmitAck);
286+
rule do_transmit_ack (!reset_device_ && state == TransmitAck);
280287
sda_out <= pack(nack_response_);
281288
do_write <= False;
282289
do_read <= False;
@@ -293,7 +300,7 @@ module mkI2CPeripheralModel #(Bit#(7) i2c_address,
293300
endrule
294301

295302
(* fire_when_enabled *)
296-
rule do_scl_stretch (state == SclStretch);
303+
rule do_scl_stretch (!reset_device_ && state == SclStretch);
297304
if (scl_stretch_countdown) begin
298305
scl_out <= 1;
299306
if (back_to_rx) begin
@@ -307,13 +314,18 @@ module mkI2CPeripheralModel #(Bit#(7) i2c_address,
307314
endrule
308315

309316
(* fire_when_enabled *)
310-
rule do_await_stop (state == AwaitStop);
317+
rule do_await_stop (!reset_device_ && state == AwaitStop);
311318
if (stop_detected) begin
312319
state <= AwaitStartByte;
313320
outgoing_events.enq(tagged ReceivedStop);
314321
end
315322
endrule
316323

324+
(* fire_when_enabled *)
325+
rule do_pullup_sda (state != TransmitAck && state != TransmitByte);
326+
sda_out <= 1;
327+
endrule
328+
317329
method Action scl_i(Bit#(1) scl_i_next);
318330
scl_in._write(scl_i_next);
319331
if (scl_i_next == 1 && scl_in == 0) begin
@@ -354,6 +366,8 @@ module mkI2CPeripheralModel #(Bit#(7) i2c_address,
354366

355367
method Action bus_pullups(Bool present) = pullups_lost._write(!present);
356368

369+
method Action reset_device = reset_device_.send();
370+
357371
interface Get receive = toGet(outgoing_events);
358372
endmodule
359373

0 commit comments

Comments
 (0)