Skip to content

Commit db99d6c

Browse files
committed
i3c_controller: Remove CLK_MOD, set SDA low at Stop
Running the core at 50MHz, even though works, provide worst performance and improper stall times. The target carrier, DE10Nano, can be configured to provide a clk near 100MHz without using a PLL. Therefore, remove this option and require 100MHz input clock. Also, simplify logic to hold SDA lane always to ground during the bit, avoiding conditions where SDA rises before SCL, not yielding a proper stop bit. Signed-off-by: Jorge Marques <jorge.marques@analog.com>
1 parent 9e93dc4 commit db99d6c

File tree

8 files changed

+14
-59
lines changed

8 files changed

+14
-59
lines changed

docs/library/i3c_controller/i3c_controller_core.rst

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,11 @@ Configuration Parameters
3333

3434
.. hdl-parameters::
3535

36-
* - CLK_MOD
37-
- Clock cycles per bus bit at maximun speed (12.5MHz), set to:
38-
39-
* 0: 8 clock cycles at 100MHz input clock.
40-
* 1: 4 clock cycles at 50MHz input clock.
4136
* - I2C_MOD
4237
- Further divide open drain speed by power of two,
4338
to support slow I2C devices.
4439

45-
For example, with input clock 100MHz and CLK_MOD=0:
40+
For example, with input clock 100MHz:
4641

4742
* 0: 1.5626MHz (no division).
4843
* 2 390.6kHz.

library/i3c_controller/i3c_controller_core/i3c_controller_bit_mod.v

Lines changed: 8 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,6 @@
3737
* SCL high time is fixed at 40ns in I3C mode:
3838
* * 4 clock cycles at 100MHz clk.
3939
* * 2 clock cycles at 50MHz clk.
40-
* Parameter CLK_MOD tunes the number of clock cycles to module one lane bus bit,
41-
* to achieve 12.5MHz at the maximum speed grade, set:
42-
* * CLK_MOD = 0, clk = 100MHz
43-
* * CLK_MOD = 1, clk = 50MHz
4440
* I3C Open drain is 1.5625MHz,while I2C speed depends on I2C_MOD, e.g.:
4541
* * I2C_MOD = 0 : 1.5626MHz
4642
* * I2C_MOD = 2: 390.6kHz
@@ -52,7 +48,6 @@
5248
`include "i3c_controller_bit_mod.vh"
5349

5450
module i3c_controller_bit_mod #(
55-
parameter CLK_MOD = 0,
5651
parameter I2C_MOD = 0
5752
) (
5853
input reset_n,
@@ -91,7 +86,6 @@ module i3c_controller_bit_mod #(
9186
localparam [1:0] SM_SCL_LOW = 2;
9287
localparam [1:0] SM_SCL_HIGH = 3;
9388

94-
localparam COUNT_INCR = CLK_MOD ? 2 : 1;
9589
localparam PRESCL = I2C_MOD+5;
9690
localparam PRESCALER_CLOG = $clog2(PRESCL);
9791

@@ -105,14 +99,13 @@ module i3c_controller_bit_mod #(
10599
reg [1:0] sm;
106100

107101
wire [`MOD_BIT_CMD_WIDTH:2] st;
108-
wire [1:CLK_MOD] count_high;
102+
wire [1:0] count_high;
109103
wire [PRESCL-2:0] scl_posedge_multi;
110104
wire t_w;
111105
wire t_w2;
112106
wire sdo_w;
113107
wire scl_posedge;
114108
wire [1:0] sr_sda;
115-
wire [1:0] p_sda;
116109
wire [1:0] sr_scl;
117110
wire i3c_scl_posedge;
118111
wire i2c_scl;
@@ -169,7 +162,7 @@ module i3c_controller_bit_mod #(
169162
end
170163

171164
if (!cmdb_ready) begin
172-
count <= count + COUNT_INCR;
165+
count <= count + 1;
173166
end
174167

175168
if (sm == SM_SETUP || st == `MOD_BIT_CMD_STOP_) begin
@@ -180,18 +173,9 @@ module i3c_controller_bit_mod #(
180173
end
181174
end
182175

183-
generate if (CLK_MOD) begin
184-
// Is short on one clock cycle at clk 50MHz, scl 12.5MHz,
185-
// but due to the lower clk frequency, timing slack to propagate is better.
186-
always @(*) begin
187-
rx = sdi === 1'b0 ? 1'b0 : 1'b1;
188-
end
189-
end else begin
190-
always @(posedge clk) begin
191-
rx <= sdi === 1'b0 ? 1'b0 : 1'b1;
192-
end
176+
always @(posedge clk) begin
177+
rx <= sdi === 1'b0 ? 1'b0 : 1'b1;
193178
end
194-
endgenerate
195179

196180
always @(posedge clk) begin
197181
// To guarantee thd_pp > 3ns.
@@ -202,12 +186,12 @@ module i3c_controller_bit_mod #(
202186
genvar i;
203187
generate
204188
for (i = 0; i < PRESCL-1; i = i+1) begin: gen_scl
205-
assign scl_posedge_multi[i] = &count[i+2:CLK_MOD];
189+
assign scl_posedge_multi[i] = &count[i+2:0];
206190
end
207191
endgenerate
208192

209193
assign scl_posedge = scl_posedge_multi[pp_sg];
210-
assign count_high = count[1:CLK_MOD];
194+
assign count_high = count[1:0];
211195
assign cmdb_ready = (sm == SM_SETUP) ||
212196
(sm == SM_STALL) ||
213197
(sm == SM_SCL_HIGH & &count_high);
@@ -216,10 +200,8 @@ module i3c_controller_bit_mod #(
216200

217201
// Used to generate Sr with generous timing (locked in open drain speed).
218202
assign sr_sda[0] = ((~count[4] & count[5]) | ~count[5]) & sm == SM_SCL_LOW;
219-
assign p_sda [0] = ~sr_sda[0];
220203
assign sr_scl[0] = count[5] | sm == SM_SCL_HIGH;
221204
assign sr_sda[1] = ~i2c_scl;
222-
assign p_sda [1] = 1'b0;
223205
assign sr_scl[1] = count[PRESCL] | sm == SM_SCL_HIGH;
224206
assign i2c_scl = count_delay[3];
225207

@@ -230,10 +212,10 @@ module i3c_controller_bit_mod #(
230212
// * 4 clks (12.5MHz, half-bit ack, 100MHz clk)
231213
// * 2 clks (12.5MHz, half-bit ack, 50MHz clk)
232214
assign rx_valid = i2c_mode_reg ? i2c_scl_posedge :
233-
CLK_MOD ? scl_posedge : i3c_scl_posedge;
215+
i3c_scl_posedge;
234216

235217
assign sdo_w = st == `MOD_BIT_CMD_START_ ? sr_sda[i2c_mode_reg] :
236-
st == `MOD_BIT_CMD_STOP_ ? p_sda[i2c_mode_reg] :
218+
st == `MOD_BIT_CMD_STOP_ ? 1'b0 :
237219
st == `MOD_BIT_CMD_WRITE_ ? ss[0] :
238220
st == `MOD_BIT_CMD_ACK_SDR_ ?
239221
(i2c_mode_reg ? 1'b1 : (sm == SM_SCL_HIGH ? rx : 1'b1)) :

library/i3c_controller/i3c_controller_core/i3c_controller_core.v

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040

4141
module i3c_controller_core #(
4242
parameter MAX_DEVS = 16,
43-
parameter CLK_MOD = 0,
4443
parameter I2C_MOD = 0
4544
) (
4645
input clk,
@@ -111,8 +110,7 @@ module i3c_controller_core #(
111110
wire i2c_mode;
112111

113112
i3c_controller_framing #(
114-
.MAX_DEVS(MAX_DEVS),
115-
.CLK_MOD(CLK_MOD)
113+
.MAX_DEVS(MAX_DEVS)
116114
) i_i3c_controller_framing (
117115
.reset_n(reset_n),
118116
.clk(clk),
@@ -171,7 +169,6 @@ module i3c_controller_core #(
171169
.rmap_ibi_config(rmap_ibi_config));
172170

173171
i3c_controller_bit_mod #(
174-
.CLK_MOD(CLK_MOD),
175172
.I2C_MOD(I2C_MOD)
176173
) i_i3c_controller_bit_mod (
177174
.reset_n(reset_n),

library/i3c_controller/i3c_controller_core/i3c_controller_core_hw.tcl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,13 @@ ad_ip_files i3c_controller_core [list \
2121
# parameters
2222

2323
ad_ip_parameter MAX_DEVS STRING "MAX_DEVS"
24-
ad_ip_parameter CLK_MOD INTEGER 1
2524
ad_ip_parameter I2C_MOD INTEGER 0
2625

2726
proc p_elaboration {} {
2827

2928
# read parameters
3029

3130
set max_devs [get_parameter_value "MAX_DEVS"]
32-
set clk_mod [get_parameter_value "CLK_MOD"]
3331
set i2c_mod [get_parameter_value "I2C_MOD"]
3432

3533
# clock and reset interface

library/i3c_controller/i3c_controller_core/i3c_controller_core_ip.tcl

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -89,13 +89,6 @@ set_property -dict [list \
8989
] \
9090
[ipx::get_user_parameters MAX_DEVS -of_objects $cc]
9191

92-
## CLK_MOD
93-
set_property -dict [list \
94-
"value_validation_type" "pairs" \
95-
"value_validation_pairs" {"8" 0 "4" 1} \
96-
] \
97-
[ipx::get_user_parameters CLK_MOD -of_objects $cc]
98-
9992
## I2C_MOD
10093
set_property -dict [list \
10194
"value_validation_type" "list" \
@@ -121,13 +114,6 @@ set_property -dict [list \
121114
"tooltip" "\[MAX_DEVS\] Maximum number of peripherals in the bus, counting the controller" \
122115
] [ipgui::get_guiparamspec -name "MAX_DEVS" -component $cc]
123116

124-
ipgui::add_param -name "CLK_MOD" -component $cc -parent $general_group
125-
set_property -dict [list \
126-
"widget" "comboBox" \
127-
"display_name" "Clock cycles per bit" \
128-
"tooltip" "\[CLK_MOD\] Adjust clock cycles required to modulate the lane bus bits. Set 8 to achieve 12.5MHz at 100Mhz input clock, and 4 at 50MHz." \
129-
] [ipgui::get_guiparamspec -name "CLK_MOD" -component $cc]
130-
131117
ipgui::add_param -name "I2C_MOD" -component $cc -parent $general_group
132118
set_property -dict [list \
133119
"widget" "comboBox" \

library/i3c_controller/i3c_controller_core/i3c_controller_framing.v

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,7 @@
6464
`include "i3c_controller_word.vh"
6565

6666
module i3c_controller_framing #(
67-
parameter MAX_DEVS = 16,
68-
parameter CLK_MOD = 0
67+
parameter MAX_DEVS = 16
6968
) (
7069
input clk,
7170
input reset_n,
@@ -117,7 +116,7 @@ module i3c_controller_framing #(
117116

118117
// Defines the bus available condition width (> 1us for target)
119118
// Setting around 0.64us for the controller.
120-
localparam BUS_AVAIL = CLK_MOD ? 4 : 5;
119+
localparam BUS_AVAIL = 5;
121120

122121
localparam [2:0] SM_SETUP = 0;
123122
localparam [2:0] SM_VALIDATE = 1;

library/i3c_controller/scripts/i3c_controller_bd.tcl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
### SPDX short identifier: ADIBSD
44
###############################################################################
55

6-
proc i3c_controller_create {{name "i3c_controller"} {async_clk 0} {clk_mod 1} {i2c_mod 0} {offload 1} {max_devs 16}} {
6+
proc i3c_controller_create {{name "i3c_controller"} {async_clk 0} {i2c_mod 0} {offload 1} {max_devs 16}} {
77

88
create_bd_cell -type hier $name
99
current_bd_instance /$name
@@ -26,7 +26,6 @@ proc i3c_controller_create {{name "i3c_controller"} {async_clk 0} {clk_mod 1} {i
2626

2727
ad_ip_instance i3c_controller_core core
2828
ad_ip_parameter core CONFIG.MAX_DEVS $max_devs
29-
ad_ip_parameter core CONFIG.CLK_MOD $clk_mod
3029
ad_ip_parameter core CONFIG.i2c_MOD $i2c_mod
3130

3231
ad_connect clk host_interface/s_axi_aclk

library/i3c_controller/scripts/i3c_controller_qsys.tcl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
### SPDX short identifier: ADIBSD
44
###############################################################################
55

6-
proc i3c_controller_create {{name "i3c_controller"} {async_clk 0} {clk_mod 1} {i2c_mod 0} {offload 1} {max_devs 16}} {
6+
proc i3c_controller_create {{name "i3c_controller"} {async_clk 0} {i2c_mod 0} {offload 1} {max_devs 16}} {
77
add_instance ${name}_host_interface i3c_controller_host_interface
88

99
set_instance_parameter_value ${name}_host_interface {ASYNC_CLK} $async_clk
@@ -12,7 +12,6 @@ proc i3c_controller_create {{name "i3c_controller"} {async_clk 0} {clk_mod 1} {i
1212
add_instance ${name}_core i3c_controller_core
1313

1414
set_instance_parameter_value ${name}_core {MAX_DEVS} $max_devs
15-
set_instance_parameter_value ${name}_core {CLK_MOD} $clk_mod
1615
set_instance_parameter_value ${name}_core {I2C_MOD} $i2c_mod
1716

1817
add_connection ${name}_host_interface.sdo ${name}_core.sdo

0 commit comments

Comments
 (0)