Skip to content

Commit 3558cb1

Browse files
committed
QSFP Controller: make power control and readback separate
1 parent e317723 commit 3558cb1

File tree

5 files changed

+66
-31
lines changed

5 files changed

+66
-31
lines changed

hdl/projects/sidecar/qsfp_x32/QSFPModule/QsfpModuleController.bsv

+2-2
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ interface QsfpModuleController;
9797
method Action lpmode(Bit#(1) val);
9898

9999
// Software controlled hot swap controller power enable
100-
method Action power_en(Bit#(1) val);
100+
method Action sw_power_en(Bit#(1) val);
101101

102102
// Power fault state from the controller
103103
method Bool pg;
@@ -388,7 +388,7 @@ module mkQsfpModuleController #(Parameters parameters) (QsfpModuleController);
388388
method modprsl = modprsl_;
389389
method intl = intl_;
390390

391-
method power_en = power_en_sw._write;
391+
method sw_power_en = power_en_sw._write;
392392
method pg = hot_swap.pin_state.good;
393393
method pg_timeout = hot_swap.timed_out;
394394
method pg_lost = hot_swap.aborted;

hdl/projects/sidecar/qsfp_x32/QSFPModule/QsfpModulesTop.bsv

+25-16
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,10 @@ interface Registers;
5252
interface ReadOnly#(I2cBusy1) i2c_busy1;
5353
interface Vector#(16, ReadOnly#(PortStatus)) mod_statuses;
5454
interface Vector#(16, Reg#(PortControl)) mod_controls;
55-
interface Reg#(PowerEn0) power_en0;
56-
interface Reg#(PowerEn1) power_en1;
55+
interface Reg#(SwPowerEn0) sw_power_en0;
56+
interface Reg#(SwPowerEn1) sw_power_en1;
57+
interface ReadOnly#(PowerEn0) power_en0;
58+
interface ReadOnly#(PowerEn1) power_en1;
5759
interface ReadOnly#(PowerGood0) power_good0;
5860
interface ReadOnly#(PowerGood1) power_good1;
5961
interface ReadOnly#(PowerGoodTimeout0) power_good_timeout0;
@@ -90,6 +92,8 @@ module mkQsfpModulesTop #(Parameters parameters) (QsfpModulesTop);
9092
Reg#(I2cBcast0) i2c_bcast0 <- mkReg(defaultValue);
9193
Reg#(I2cBcast1) i2c_bcast1 <- mkReg(defaultValue);
9294
Reg#(I2cCtrl) i2c_ctrl <- mkDReg(defaultValue);
95+
Reg#(SwPowerEn0) sw_power_en0 <- mkReg(defaultValue);
96+
Reg#(SwPowerEn1) sw_power_en1 <- mkReg(defaultValue);
9397
Reg#(PowerEn0) power_en0 <- mkReg(defaultValue);
9498
Reg#(PowerEn1) power_en1 <- mkReg(defaultValue);
9599
Reg#(ModResetl0) mod_resetl0 <- mkReg(defaultValue);
@@ -105,9 +109,9 @@ module mkQsfpModulesTop #(Parameters parameters) (QsfpModulesTop);
105109
Vector#(16, Reg#(Bool)) i2c_broadcast_enabled_r <- replicateM(mkReg(False));
106110

107111
// Vectorize all the low speed module signals mapping into local registers.
108-
Vector#(16, Bit#(1)) power_en_bits =
109-
unpack({pack(power_en1), pack(power_en0)});
110-
Vector#(16, Reg#(Bit#(1))) power_en_bits_r <- replicateM(mkReg(1));
112+
Vector#(16, Bit#(1)) sw_power_en_bits =
113+
unpack({pack(sw_power_en1), pack(sw_power_en0)});
114+
Vector#(16, Reg#(Bit#(1))) sw_power_en_bits_r <- replicateM(mkReg(1));
111115

112116
Vector#(16, Bit#(1)) resetl_bits =
113117
unpack({pack(mod_resetl1), pack(mod_resetl0)});
@@ -117,7 +121,7 @@ module mkQsfpModulesTop #(Parameters parameters) (QsfpModulesTop);
117121
unpack({pack(mod_lpmode1), pack(mod_lpmode0)});
118122
Vector#(16, Reg#(Bit#(1))) lpmode_bits_r <- replicateM(mkReg(1));
119123

120-
124+
Vector#(16, Reg#(Bit#(1))) power_en_bits_r <- replicateM(mkReg(0));
121125
Vector#(16, Reg#(Bit#(1))) pg_bits_r <- replicateM(mkReg(0));
122126
Vector#(16, Reg#(Bit#(1))) pg_timeout_bits_r <- replicateM(mkReg(0));
123127
Vector#(16, Reg#(Bit#(1))) pg_lost_bits_r <- replicateM(mkReg(0));
@@ -134,15 +138,16 @@ module mkQsfpModulesTop #(Parameters parameters) (QsfpModulesTop);
134138
(* fire_when_enabled *)
135139
rule do_module_regs;
136140
for (int i = 0; i < 16; i = i + 1) begin
137-
// control
138-
power_en_bits_r[i] <= power_en_bits[i];
139-
resetl_bits_r[i] <= resetl_bits[i];
140-
lpmode_bits_r[i] <= lpmode_bits[i];
141+
// software control
142+
sw_power_en_bits_r[i] <= sw_power_en_bits[i];
143+
resetl_bits_r[i] <= resetl_bits[i];
144+
lpmode_bits_r[i] <= lpmode_bits[i];
141145

142146
// pin state readbacks
143-
pg_bits_r[i] <= pack(qsfp_ports[i].pg);
144-
modprsl_bits_r[i] <= pack(qsfp_ports[i].modprsl);
145-
intl_bits_r[i] <= pack(qsfp_ports[i].intl);
147+
power_en_bits_r[i] <= pack(qsfp_ports[i].pins.power_en);
148+
pg_bits_r[i] <= pack(qsfp_ports[i].pg);
149+
modprsl_bits_r[i] <= pack(qsfp_ports[i].modprsl);
150+
intl_bits_r[i] <= pack(qsfp_ports[i].intl);
146151

147152
// fault state readbacks
148153
pg_timeout_bits_r[i] <= pack(qsfp_ports[i].pg_timeout);
@@ -159,7 +164,7 @@ module mkQsfpModulesTop #(Parameters parameters) (QsfpModulesTop);
159164
// software controlled bits
160165
mkConnection(qsfp_ports[i].resetl, resetl_bits_r[i]);
161166
mkConnection(qsfp_ports[i].lpmode, lpmode_bits_r[i]);
162-
mkConnection(qsfp_ports[i].power_en, power_en_bits_r[i]);
167+
mkConnection(qsfp_ports[i].sw_power_en, sw_power_en_bits_r[i]);
163168

164169
// tick fan out
165170
mkConnection(qsfp_ports[i].tick_1ms, tick_1ms_);
@@ -201,12 +206,16 @@ module mkQsfpModulesTop #(Parameters parameters) (QsfpModulesTop);
201206
map(QsfpModuleController::get_status, qsfp_ports);
202207
interface mod_controls =
203208
map(QsfpModuleController::get_control, qsfp_ports);
204-
interface Reg power_en0 = power_en0;
205-
interface Reg power_en1 = power_en1;
209+
interface Reg sw_power_en0 = sw_power_en0;
210+
interface Reg sw_power_en1 = sw_power_en1;
206211
interface Reg mod_resetl0 = mod_resetl0;
207212
interface Reg mod_resetl1 = mod_resetl1;
208213
interface Reg mod_lpmode0 = mod_lpmode0;
209214
interface Reg mod_lpmode1 = mod_lpmode1;
215+
interface ReadOnly power_en0 =
216+
valueToReadOnly(unpack(pack(map(readReg, power_en_bits_r))[7:0]));
217+
interface ReadOnly power_en1 =
218+
valueToReadOnly(unpack(pack(map(readReg, power_en_bits_r))[15:8]));
210219
interface ReadOnly power_good0 =
211220
valueToReadOnly(unpack(pack(map(readReg, pg_bits_r))[7:0]));
212221
interface ReadOnly power_good1 =

hdl/projects/sidecar/qsfp_x32/QSFPModule/qsfp_modules_top.rdl

+26-2
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,31 @@ addrmap qsfp_modules_top {
189189
port_control PORT15_CONTROL;
190190

191191
reg {
192-
name = "Ports 0 -> 7 HSC Enable. Clear bit to remove module power.";
192+
name = "Ports 0 -> 7 SW control of HSC enable. Clear bit to remove module power.";
193+
field {} PORT7[7:7] = 1;
194+
field {} PORT6[6:6] = 1;
195+
field {} PORT5[5:5] = 1;
196+
field {} PORT4[4:4] = 1;
197+
field {} PORT3[3:3] = 1;
198+
field {} PORT2[2:2] = 1;
199+
field {} PORT1[1:1] = 1;
200+
field {} PORT0[0:0] = 1;
201+
} SW_POWER_EN0;
202+
203+
reg {
204+
name = "Ports 8 -> 15 SW control of HSC enable. Clear bit to remove module power.";
205+
field {} PORT15[7:7] = 1;
206+
field {} PORT14[6:6] = 1;
207+
field {} PORT13[5:5] = 1;
208+
field {} PORT12[4:4] = 1;
209+
field {} PORT11[3:3] = 1;
210+
field {} PORT10[2:2] = 1;
211+
field {} PORT9[1:1] = 1;
212+
field {} PORT8[0:0] = 1;
213+
} SW_POWER_EN1;
214+
215+
reg {
216+
name = "Ports 0 -> 7 HSC enabled.";
193217
default sw = r;
194218
field {} PORT7[7:7] = 1;
195219
field {} PORT6[6:6] = 1;
@@ -202,7 +226,7 @@ addrmap qsfp_modules_top {
202226
} POWER_EN0;
203227

204228
reg {
205-
name = "Ports 8 -> 15 HSC Enable. Clear bit to remove module power.";
229+
name = "Ports 8 -> 15 HSC enabled.";
206230
default sw = r;
207231
field {} PORT15[7:7] = 1;
208232
field {} PORT14[6:6] = 1;

hdl/projects/sidecar/qsfp_x32/QSFPModule/test/QsfpModuleControllerTests.bsv

+7-7
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ interface Bench;
5858
// A way to expose if the I2C read/write is finished
5959
method Bool i2c_busy();
6060

61-
// Control of the hot swap power enable pin
62-
method Action set_power_en(Bit#(1) v);
61+
// Software control of the hot swap power enable pin
62+
method Action set_sw_power_en(Bit#(1) v);
6363
// Readback of the enable pin
6464
method Bool hsc_en;
6565
// Control of the hot swap power good pin
@@ -115,9 +115,9 @@ module mkBench (Bench);
115115
mkConnection(controller.lpmode, lpmode_r);
116116

117117
// Hot swap
118-
Reg#(Bit#(1)) power_en_r <- mkReg(1);
118+
Reg#(Bit#(1)) sw_power_en_r <- mkReg(1);
119119
Reg#(Bool) hsc_pg_r <- mkReg(False);
120-
mkConnection(controller.power_en, power_en_r);
120+
mkConnection(controller.sw_power_en, sw_power_en_r);
121121
mkConnection(controller.pins.power_good, hsc_pg_r);
122122

123123
Strobe#(16) tick_1khz <-
@@ -273,8 +273,8 @@ module mkBench (Bench);
273273
lpmode_r <= v;
274274
endmethod
275275

276-
method Action set_power_en(Bit#(1) v);
277-
power_en_r <= v;
276+
method Action set_sw_power_en(Bit#(1) v);
277+
sw_power_en_r <= v;
278278
endmethod
279279

280280
method Action set_hsc_pg(Bit#(1) v);
@@ -420,7 +420,7 @@ module mkRemovePowerEnableTest (Empty);
420420
assert_eq(unpack(bench.registers.port_status.error[2:0]),
421421
NoError,
422422
"NoPower should be present when attempting to communicate when the hot swap is stable.");
423-
bench.set_power_en(0);
423+
bench.set_sw_power_en(0);
424424
delay(2);
425425
bench.set_hsc_pg(0);
426426
// power good is debounced and thus won't transition immediately

hdl/projects/sidecar/qsfp_x32/QsfpX32ControllerSpiServer.bsv

+6-4
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ module mkSpiServer #(VSC8562::Registers vsc8562,
118118
fromInteger(qsfpPort14ControlOffset): read(qsfp_top.mod_controls[14]);
119119
fromInteger(qsfpPort15ControlOffset): read(qsfp_top.mod_controls[15]);
120120
fromInteger(qsfpI2cCtrlOffset): read(qsfp_top.i2c_ctrl);
121+
fromInteger(qsfpSwPowerEn0Offset): read(qsfp_top.sw_power_en0);
122+
fromInteger(qsfpSwPowerEn1Offset): read(qsfp_top.sw_power_en1);
121123
fromInteger(qsfpPowerEn0Offset): read(qsfp_top.power_en0);
122124
fromInteger(qsfpPowerEn1Offset): read(qsfp_top.power_en1);
123125
fromInteger(qsfpPowerGood0Offset): read(qsfp_top.power_good0);
@@ -199,10 +201,10 @@ module mkSpiServer #(VSC8562::Registers vsc8562,
199201
update(spi_request.op, qsfp_top.i2c_bcast0, spi_request.wdata);
200202
fromInteger(qsfpI2cCtrlOffset):
201203
update(spi_request.op, qsfp_top.i2c_ctrl, spi_request.wdata);
202-
fromInteger(qsfpPowerEn0Offset):
203-
update(spi_request.op, qsfp_top.power_en0, spi_request.wdata);
204-
fromInteger(qsfpPowerEn1Offset):
205-
update(spi_request.op, qsfp_top.power_en1, spi_request.wdata);
204+
fromInteger(qsfpSwPowerEn0Offset):
205+
update(spi_request.op, qsfp_top.sw_power_en0, spi_request.wdata);
206+
fromInteger(qsfpSwPowerEn1Offset):
207+
update(spi_request.op, qsfp_top.sw_power_en1, spi_request.wdata);
206208
fromInteger(qsfpModResetl0Offset):
207209
update(spi_request.op, qsfp_top.mod_resetl0, spi_request.wdata);
208210
fromInteger(qsfpModResetl1Offset):

0 commit comments

Comments
 (0)