Skip to content

Commit a1384ff

Browse files
grapefruit: add spd proxy passthrough (#313)
This plops down the SPD block in grapefruit with the commands to the internal FPGA controller disabled, effectively making it a CPU<->DIMM passthrough (exercising the SDA arbitration logic at low speeds, at least). The ruby boots with this image in place (all the activity shows the reworked G channel 0 ACKing and all the ensuing traffic): ![image](https://github.com/user-attachments/assets/622eac46-1b8c-4568-83dc-f43704f0cb7c) I get to nanoblrs successfully. My plan is to merge this and get it put into @citrus-it's Hubris dev branch. This means no more shuffling DIMMs around for you @nathanaelhuffman!
1 parent e0d6afb commit a1384ff

File tree

3 files changed

+54
-26
lines changed

3 files changed

+54
-26
lines changed

hdl/projects/grapefruit/BUCK

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,17 @@ vhdl_unit(
7373
":gfruit_sgpio",
7474
":gfruit_black_boxes",
7575
"//hdl/projects/cosmo_seq:reset_sync",
76+
"//hdl/projects/cosmo_seq/spd_proxy:spd_proxy_top",
77+
"//hdl/ip/vhd/i2c/common:i2c_common_pkg",
7678
"//hdl/ip/vhd/info:info",
7779
"//hdl/ip/vhd/espi:espi_top",
7880
"//hdl/ip/vhd/uart:axi_fifo_uart",
7981
"//hdl/ip/vhd/axi_blocks:axil_interconnect",
8082
"//hdl/ip/vhd/spi_nor_controller:spi_nor_top",
8183
"//hdl/ip/vhd/fmc_if:stm32h7_fmc_target",
84+
"//hdl/ip/vhd/common:streaming_if_pkg",
8285
"//hdl/ip/vhd/common:time_pkg",
86+
"//hdl/ip/vhd/common:tristate_if_pkg",
8387
],
8488
standard = "2019",
8589
)

hdl/projects/grapefruit/grapefruit_pins.xdc

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,16 +130,20 @@ set_property -dict { PACKAGE_PIN Y3 IOSTANDARD LVCMOS18 } [get_ports { espi_hpm_
130130
set_property SLEW FAST [get_ports espi_hpm_to_scm_dat[*]]
131131
set_property -dict { PACKAGE_PIN AA6 IOSTANDARD LVCMOS18 } [get_ports { i3c_hpm_to_scm_dimm0_abcdef_scl }];
132132
set_property -dict { PACKAGE_PIN AB6 IOSTANDARD LVCMOS18 } [get_ports { i3c_hpm_to_scm_dimm0_abcdef_sda }];
133-
set_property -dict { PACKAGE_PIN Y6 IOSTANDARD LVCMOS18 } [get_ports { i3c_hpm_to_scm_dimm0_ghijkl_scl }];
134-
set_property -dict { PACKAGE_PIN Y5 IOSTANDARD LVCMOS18 } [get_ports { i3c_hpm_to_scm_dimm0_ghijkl_sda }];
133+
# we have pullups applied to the i3c_hpm_to_scm_dimm0_ghijkl bus for experimentation getting the SPD
134+
# proxying working with Ruby in a setup that requires a bit of rework.
135+
set_property -dict { PACKAGE_PIN Y6 IOSTANDARD LVCMOS18 PULLUP TRUE } [get_ports { i3c_hpm_to_scm_dimm0_ghijkl_scl }];
136+
set_property -dict { PACKAGE_PIN Y5 IOSTANDARD LVCMOS18 PULLUP TRUE } [get_ports { i3c_hpm_to_scm_dimm0_ghijkl_sda }];
135137
set_property -dict { PACKAGE_PIN Y4 IOSTANDARD LVCMOS18 } [get_ports { i3c_hpm_to_scm_dimm1_abcdef_scl }];
136138
set_property -dict { PACKAGE_PIN AA3 IOSTANDARD LVCMOS18 } [get_ports { i3c_hpm_to_scm_dimm1_abcdef_sda }];
137139
set_property -dict { PACKAGE_PIN AB3 IOSTANDARD LVCMOS18 } [get_ports { i3c_hpm_to_scm_dimm1_ghijkl_scl }];
138140
set_property -dict { PACKAGE_PIN AB2 IOSTANDARD LVCMOS18 } [get_ports { i3c_hpm_to_scm_dimm1_ghijkl_sda }];
139141
set_property -dict { PACKAGE_PIN AA1 IOSTANDARD LVCMOS18 } [get_ports { i3c_scm_to_dimm0_abcdef_scl }];
140142
set_property -dict { PACKAGE_PIN AB5 IOSTANDARD LVCMOS18 } [get_ports { i3c_scm_to_dimm0_abcdef_sda }];
141-
set_property -dict { PACKAGE_PIN AB4 IOSTANDARD LVCMOS18 } [get_ports { i3c_scm_to_dimm0_ghijkl_scl }];
142-
set_property -dict { PACKAGE_PIN V8 IOSTANDARD LVCMOS18 } [get_ports { i3c_scm_to_dimm0_ghijkl_sda }];
143+
# we have pullups applied to the i3c_scm_to_dimm0_ghijkl bus for experimentation getting the SPD
144+
# proxying working with Ruby in a setup that requires a bit of rework.
145+
set_property -dict { PACKAGE_PIN AB4 IOSTANDARD LVCMOS18 PULLUP TRUE } [get_ports { i3c_scm_to_dimm0_ghijkl_scl }];
146+
set_property -dict { PACKAGE_PIN V8 IOSTANDARD LVCMOS18 PULLUP TRUE } [get_ports { i3c_scm_to_dimm0_ghijkl_sda }];
143147
set_property -dict { PACKAGE_PIN W8 IOSTANDARD LVCMOS18 } [get_ports { i3c_scm_to_dimm1_abcdef_scl }];
144148
set_property -dict { PACKAGE_PIN Y8 IOSTANDARD LVCMOS18 } [get_ports { i3c_scm_to_dimm1_abcdef_sda }];
145149
set_property -dict { PACKAGE_PIN AA8 IOSTANDARD LVCMOS18 } [get_ports { i3c_scm_to_dimm1_ghijkl_scl }];

hdl/projects/grapefruit/grapefruit_top.vhd

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ use ieee.numeric_std_unsigned.all;
1313
use work.axil_common_pkg.all;
1414
use work.axil26x32_pkg;
1515
use work.axil8x32_pkg;
16+
use work.i2c_common_pkg.all;
17+
use work.stream8_pkg;
1618
use work.time_pkg.all;
19+
use work.tristate_if_pkg.all;
1720

1821
entity grapefruit_top is
1922
port (
@@ -244,7 +247,14 @@ architecture rtl of grapefruit_top is
244247
signal sp5_owns_flash : std_logic;
245248
signal spi_nor_block_data_o : std_logic_vector(3 downto 0);
246249
signal spi_nor_block_data_oe : std_logic_vector(3 downto 0);
247-
250+
251+
signal ruby_scl_if : tristate;
252+
signal ruby_sda_if : tristate;
253+
signal dimm_scl_if : tristate;
254+
signal dimm_sda_if : tristate;
255+
-- stubs
256+
signal i2c_tx_st_if : stream8_pkg.data_channel;
257+
signal i2c_rx_st_if : stream8_pkg.data_channel;
248258
begin
249259

250260
espi_scm_to_hpm_alert_l <= 'Z';
@@ -568,26 +578,36 @@ begin
568578
sgpio1_ld => sgpio_scm_to_hpm_ld(1)
569579
);
570580

571-
i3c_hpm_to_scm_dimm0_abcdef_scl <= not counter(26);
572-
i3c_hpm_to_scm_dimm0_abcdef_sda <= not counter(26);
573-
574-
i3c_hpm_to_scm_dimm1_abcdef_scl <= not counter(26);
575-
i3c_hpm_to_scm_dimm1_abcdef_sda <= not counter(26);
576-
i3c_hpm_to_scm_dimm1_ghijkl_scl <= not counter(26);
577-
i3c_hpm_to_scm_dimm1_ghijkl_sda <= not counter(26);
578-
579-
i3c_scm_to_dimm0_abcdef_scl <= not counter(26);
580-
i3c_scm_to_dimm0_abcdef_sda <= not counter(26);
581-
582-
i3c_scm_to_dimm1_abcdef_scl <= not counter(26);
583-
i3c_scm_to_dimm1_abcdef_sda <= not counter(26);
584-
i3c_scm_to_dimm1_ghijkl_scl <= not counter(26);
585-
i3c_scm_to_dimm1_ghijkl_sda <= not counter(26);
586-
587-
-- these signals are intentionally left unused due to the ruby rework on sapphire
588-
-- i3c_hpm_to_scm_dimm0_ghijkl_scl
589-
-- i3c_hpm_to_scm_dimm0_ghijkl_sda
590-
-- i3c_scm_to_dimm0_ghijkl_scl
591-
-- i3c_scm_to_dimm0_ghijkl_sda
581+
-- Ruby -> Grapefruit bus (filtered in SPD block)
582+
i3c_hpm_to_scm_dimm0_ghijkl_scl <= ruby_scl_if.o when ruby_scl_if.oe else 'Z';
583+
ruby_scl_if.i <= i3c_hpm_to_scm_dimm0_ghijkl_scl;
584+
i3c_hpm_to_scm_dimm0_ghijkl_sda <= ruby_sda_if.o when ruby_sda_if.oe else 'Z';
585+
ruby_sda_if.i <= i3c_hpm_to_scm_dimm0_ghijkl_sda;
586+
587+
-- Grapefruit -> DIMM bus (filtered in SPD block)
588+
i3c_scm_to_dimm0_ghijkl_scl <= dimm_scl_if.o when dimm_scl_if.oe else 'Z';
589+
dimm_scl_if.i <= i3c_scm_to_dimm0_ghijkl_scl;
590+
i3c_scm_to_dimm0_ghijkl_sda <= dimm_sda_if.o when dimm_sda_if.oe else 'Z';
591+
dimm_sda_if.i <= i3c_scm_to_dimm0_ghijkl_sda;
592+
593+
-- Wiring this in with the i2c_cmd interface disabled so it will just pass through the CPU/DIMM
594+
-- comminication for now.
595+
spd_proxy_top_inst: entity work.spd_proxy_top
596+
generic map(
597+
CLK_PER_NS => 8, -- clk @ 125MHz = 8ns period
598+
I2C_MODE => FAST_PLUS
599+
)
600+
port map(
601+
clk => clk_125m,
602+
reset => reset_125m,
603+
cpu_scl_if => ruby_scl_if,
604+
cpu_sda_if => ruby_sda_if,
605+
dimm_scl_if => dimm_scl_if,
606+
dimm_sda_if => dimm_sda_if,
607+
i2c_command => CMD_RESET,
608+
i2c_command_valid => '0',
609+
i2c_tx_st_if => i2c_tx_st_if,
610+
i2c_rx_st_if => i2c_rx_st_if
611+
);
592612

593613
end rtl;

0 commit comments

Comments
 (0)