Skip to content

Commit

Permalink
Start to stub out I2C
Browse files Browse the repository at this point in the history
  • Loading branch information
Aaron-Hartwig committed Dec 10, 2024
1 parent a61e7eb commit 74bc3ee
Show file tree
Hide file tree
Showing 19 changed files with 1,937 additions and 5 deletions.
8 changes: 8 additions & 0 deletions hdl/ip/vhd/common/BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ vhdl_unit(
visibility = ['PUBLIC']
)

vhdl_unit(
name = "tristate_if_pkg",
srcs = glob(["interfaces/tristate_if_pkg.vhd"]),
deps = [],
standard = "2019",
visibility = ['PUBLIC']
)

# Strobe

vhdl_unit(
Expand Down
4 changes: 2 additions & 2 deletions hdl/ip/vhd/common/interfaces/streaming_if_pkg.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ package streaming_if_pkg is
ready : std_logic;
end record;

view st_source of data_channel is
view st_source_if of data_channel is
valid, data : out;
ready : in;
end view;

alias st_sink is st_source'converse;
alias st_sink_if is st_source_if'converse;

end package;

Expand Down
25 changes: 25 additions & 0 deletions hdl/ip/vhd/common/interfaces/tristate_if_pkg.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
-- This Source Code Form is subject to the terms of the Mozilla Public
-- License, v. 2.0. If a copy of the MPL was not distributed with this
-- file, You can obtain one at https://mozilla.org/MPL/2.0/.
--
-- Copyright 2024 Oxide Computer Company

-- This package relies on the VHDL 2019 feature for "interfaces"

library ieee;
use ieee.std_logic_1164.all;

package tristate_if_pkg is

type tristate is record
i : std_logic;
o : std_logic;
oe : std_logic;
end record;

view tristate_if of tristate is
i : in;
o, oe : out;
end view;

end package;
8 changes: 8 additions & 0 deletions hdl/ip/vhd/common/strobe/sims/strobe_tb.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ begin

bench: process
alias reset is << signal th.reset : std_logic >>;
alias enable is << signal th.dut_enable : std_logic >>;
alias strobe is << signal th.dut_strobe : std_logic >>;
begin
-- Always the first thing in the process, set up things for the VUnit test runner
Expand All @@ -41,11 +42,18 @@ begin

while test_suite loop
if run("test_strobe") then
enable <= '1';
check_equal(strobe, '0', "Strobe should be low after reset");
wait for 72 ns; -- CLK_PER_NS * (TB_TICKS - 1) ns
check_equal(strobe, '0', "Strobe should be low after TB_TICKS-1");
wait for 8 ns; -- wait one more period, bringing us to TB_TICKs
check_equal(strobe, '1', "Strobe should be high once the TICKS count is reached");
elsif run("test_strobe_enable") then
wait for 80 ns; -- wait for TB_TICKs while disabled
check_equal(strobe, '0', "Strobe should be low after TB_TICKS when not enabled");
enable <= '1';
wait for 80 ns; -- wait for TB_TICKs while enabled
check_equal(strobe, '1', "Strobe should be high after TICKs when enabled");
end if;
end loop;

Expand Down
2 changes: 2 additions & 0 deletions hdl/ip/vhd/common/strobe/sims/strobe_th.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ architecture th of strobe_th is

signal clk : std_logic := '0';
signal reset : std_logic := '1';
signal dut_enable : std_logic := '0';
signal dut_strobe : std_logic;

begin
Expand All @@ -39,6 +40,7 @@ begin
port map (
clk => clk,
reset => reset,
enable => dut_enable,
strobe => dut_strobe
);

Expand Down
3 changes: 2 additions & 1 deletion hdl/ip/vhd/common/strobe/strobe.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ entity strobe is
clk : in std_logic;
reset : in std_logic;

enable : in std_logic;
strobe : out std_logic
);
end entity strobe;
Expand All @@ -34,7 +35,7 @@ begin
if strobe_counter = TICKS - 1 then
strobe <= '1';
strobe_counter <= 0;
else
elsif enable = '1' then
strobe <= '0';
strobe_counter <= strobe_counter + 1;
end if;
Expand Down
29 changes: 29 additions & 0 deletions hdl/ip/vhd/i2c/BUCK
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
load("//tools:hdl.bzl", "vhdl_unit", "vunit_sim")

vhdl_unit(
name = "i2c_txn_layer",
srcs = glob([
"link_layer/*.vhd",
"txn_layer/*.vhd",
"i2c_common_pkg.vhd"]),
deps = [
"//hdl/ip/vhd/common:countdown",
"//hdl/ip/vhd/common:strobe",
"//hdl/ip/vhd/common:streaming_if_pkg",
"//hdl/ip/vhd/common:tristate_if_pkg",
"//hdl/ip/vhd/common:time_pkg",
"//hdl/ip/vhd/synchronizers:meta_sync"
],
standard = "2019",
visibility = ['PUBLIC']
)

vunit_sim(
name = "i2c_txn_layer_tb",
srcs = glob(["sims/txn_layer/*.vhd", "sims/*.vhd"]),
deps = [
":i2c_txn_layer",
"//hdl/ip/vhd/vunit_components:basic_stream"
],
visibility = ['PUBLIC'],
)
92 changes: 92 additions & 0 deletions hdl/ip/vhd/i2c/i2c_common_pkg.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
-- This Source Code Form is subject to the terms of the Mozilla Public
-- License, v. 2.0. If a copy of the MPL was not distributed with this
-- file, You can obtain one at https://mozilla.org/MPL/2.0/.
--
-- Copyright 2024 Oxide Computer Company

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

package i2c_common_pkg is

--
-- Link Layer
--

type mode_t is (
STANDARD, -- up to 100 Kbps
FAST, -- up to 400 Kbps
FAST_PLUS -- up to 1 Mbps
);

-- A group of settings for generics to generate constants
-- all times in nanoseconds (ns)
type settings_t is record
fscl_period_ns : positive; -- SCL clock period
sda_su_ns : positive; -- data set-up time
sta_su_hd_ns : positive; -- START set-up/hold time
sto_su_ns : positive; -- STOP set-up time
sto_sta_buf_ns : positive; -- bus free time between STOP and START
end record;

function get_i2c_settings (constant mode : mode_t) return settings_t;

--
-- Transaction Layer
--

type op_t is (
READ,
WRITE,
-- RANDOM_READ will write an address byte and one more byte (intended to set an internal
-- address register on a peripheral) before issuing a repeated start for a read.
RANDOM_READ
);

type cmd_t is record
op : op_t;
addr : std_logic_vector(6 downto 0);
reg : std_logic_vector(7 downto 0);
len : unsigned(7 downto 0);
end record;
constant CMD_RESET : cmd_t := (READ, (others => '0'), (others => '0'), (others => '0'));

end package;

package body i2c_common_pkg is

function get_i2c_settings (constant mode : mode_t) return settings_t is
variable r : settings_t;
begin
case mode is
when STANDARD =>
r := (
10_000, -- 10^9 / 100_000Hz
250,
4700,
4000,
4700
);
when FAST =>
r := (
2500, -- 10^9 / 400_000Hz
100,
600,
600,
1300
);
when FAST_PLUS =>
r := (
1000, -- 10^9 / 1_000_000Hz
50,
260,
260,
500
);
end case;

return r;
end;

end package body;
52 changes: 52 additions & 0 deletions hdl/ip/vhd/i2c/i2c_core.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
-- This Source Code Form is subject to the terms of the Mozilla Public
-- License, v. 2.0. If a copy of the MPL was not distributed with this
-- file, You can obtain one at https://mozilla.org/MPL/2.0/.
--
-- Copyright 2024 Oxide Computer Company

library ieee;
use ieee.std_logic_1164.all;

use work.tristate_if_pkg;

use work.i2c_common_pkg;

entity i2c_core is
generic (
CLK_PER_NS : positive;
MODE : mode_t;
);
port (
clk : in std_logic;
reset : in std_logic;

-- Tri-state signals to I2C interface
scl_if : view tristate_if;
sda_if : view tristate_if;

-- AXI register interface
);
end entity;

architecture rtl of i2c_core is

begin

i2c_txn_layer_inst: entity work.i2c_txn_layer
generic map(
CLK_PER_NS => CLK_PER_NS,
MODE => MODE
)
port map(
clk => clk,
reset => reset,
scl_if => scl_if,
sda_if => sda_if,
cmd => cmd,
cmd_valid => cmd_valid,
core_ready => core_ready,
tx_st_if => tx_st_if,
rx_st_if => rx_st_if
);

end architecture;
Loading

0 comments on commit 74bc3ee

Please sign in to comment.