~ruther/vhdl-i2c

613f3b842bb711dbeca90fd9f274d094bf51d049 — Rutherther 1 year, 5 months ago ddd2c6a
tests: add mcu tests working with slave top designs
A mcu_tests/slave_counter/.cargo/config => mcu_tests/slave_counter/.cargo/config +13 -0
@@ 0,0 1,13 @@
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
# uncomment ONE of these three option to make `cargo run` start a GDB session
# which option to pick depends on your system
runner = "arm-none-eabi-gdb -q -x openocd.gdb"
# runner = "gdb-multiarch -q -x openocd.gdb"
# runner = "gdb -q -x openocd.gdb"

rustflags = [
  "-C", "link-arg=-Tlink.x",
]

[build]
target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU)

A mcu_tests/slave_counter/.envrc => mcu_tests/slave_counter/.envrc +1 -0
@@ 0,0 1,1 @@
use flake

A mcu_tests/slave_counter/.gitignore => mcu_tests/slave_counter/.gitignore +14 -0
@@ 0,0 1,14 @@
# Generated by Cargo
# will have compiled files and executables
debug/
target/

# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock

# These are backup files generated by rustfmt
**/*.rs.bk

# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb

A mcu_tests/slave_counter/Cargo.toml => mcu_tests/slave_counter/Cargo.toml +26 -0
@@ 0,0 1,26 @@
[package]
name = "slave-counter"
version = "0.1.0"
edition = "2021"

[dependencies]
cortex-m = "0.7.7"
cortex-m-rt = "0.7.3"
cortex-m-semihosting = "0.5.0"
embedded-hal = "0.2.7"
panic-halt = "0.2.0"
tm4c-hal = "0.4.2"
tm4c123x-hal = { version = "0.10.3", features = ["rt"] }

[[bin]]
name = "slave-counter"
test = false
bench = false

[profile.release]
panic = "abort"
strip = true
codegen-units = 1
debug = false
lto = true
opt-level = "s"

A mcu_tests/slave_counter/flake.lock => mcu_tests/slave_counter/flake.lock +96 -0
@@ 0,0 1,96 @@
{
  "nodes": {
    "flake-utils": {
      "inputs": {
        "systems": "systems"
      },
      "locked": {
        "lastModified": 1681202837,
        "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=",
        "owner": "numtide",
        "repo": "flake-utils",
        "rev": "cfacdce06f30d2b68473a46042957675eebb3401",
        "type": "github"
      },
      "original": {
        "owner": "numtide",
        "repo": "flake-utils",
        "type": "github"
      }
    },
    "nixpkgs": {
      "locked": {
        "lastModified": 1703499205,
        "narHash": "sha256-lF9rK5mSUfIZJgZxC3ge40tp1gmyyOXZ+lRY3P8bfbg=",
        "owner": "NixOS",
        "repo": "nixpkgs",
        "rev": "e1fa12d4f6c6fe19ccb59cac54b5b3f25e160870",
        "type": "github"
      },
      "original": {
        "owner": "NixOS",
        "ref": "nixpkgs-unstable",
        "repo": "nixpkgs",
        "type": "github"
      }
    },
    "nixpkgs_2": {
      "locked": {
        "lastModified": 1681358109,
        "narHash": "sha256-eKyxW4OohHQx9Urxi7TQlFBTDWII+F+x2hklDOQPB50=",
        "owner": "NixOS",
        "repo": "nixpkgs",
        "rev": "96ba1c52e54e74c3197f4d43026b3f3d92e83ff9",
        "type": "github"
      },
      "original": {
        "owner": "NixOS",
        "ref": "nixpkgs-unstable",
        "repo": "nixpkgs",
        "type": "github"
      }
    },
    "root": {
      "inputs": {
        "nixpkgs": "nixpkgs",
        "rust-overlay": "rust-overlay"
      }
    },
    "rust-overlay": {
      "inputs": {
        "flake-utils": "flake-utils",
        "nixpkgs": "nixpkgs_2"
      },
      "locked": {
        "lastModified": 1703902408,
        "narHash": "sha256-qXdWvu+tlgNjeoz8yQMRKSom6QyRROfgpmeOhwbujqw=",
        "owner": "oxalica",
        "repo": "rust-overlay",
        "rev": "319f57cd2c34348c55970a4bf2b35afe82088681",
        "type": "github"
      },
      "original": {
        "owner": "oxalica",
        "repo": "rust-overlay",
        "type": "github"
      }
    },
    "systems": {
      "locked": {
        "lastModified": 1681028828,
        "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
        "owner": "nix-systems",
        "repo": "default",
        "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
        "type": "github"
      },
      "original": {
        "owner": "nix-systems",
        "repo": "default",
        "type": "github"
      }
    }
  },
  "root": "root",
  "version": 7
}

A mcu_tests/slave_counter/flake.nix => mcu_tests/slave_counter/flake.nix +29 -0
@@ 0,0 1,29 @@
{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
    rust-overlay.url = "github:oxalica/rust-overlay";
  };

  outputs = { self, nixpkgs, rust-overlay }: let
    system = "x86_64-linux";
    pkgs = import nixpkgs {
      inherit system;
      overlays = [rust-overlay.overlays.default];
    };

    toolchain = pkgs.rust-bin.fromRustupToolchainFile ./toolchain.toml;
  in {
    devShells.${system}.default = pkgs.mkShell {
      packages = [
        toolchain
        pkgs.rust-analyzer-unwrapped

        pkgs.openocd
        pkgs.gcc-arm-embedded
        pkgs.probe-rs
      ];

      RUST_SRC_PATH = "${toolchain}/lib/rustlib/src/rust/library";
    };
  };
}

A mcu_tests/slave_counter/openocd.cfg => mcu_tests/slave_counter/openocd.cfg +3 -0
@@ 0,0 1,3 @@
# Sample OpenOCD configuration for the Tiva-C Launchpad development board

source [find board/ti_ek-tm4c123gxl.cfg]

A mcu_tests/slave_counter/openocd.gdb => mcu_tests/slave_counter/openocd.gdb +33 -0
@@ 0,0 1,33 @@
target extended-remote :3333

# print demangled symbols
set print asm-demangle on

# detect unhandled exceptions, hard faults and panics
break DefaultHandler
# break UserHardFault
# break rust_begin_unwind

# *try* to stop at the user entry point (it might be gone due to inlining)
# break main

monitor arm semihosting enable

# # send captured ITM to the file itm.fifo
# # (the microcontroller SWO pin must be connected to the programmer SWO pin)
# # 8000000 must match the core clock frequency
# monitor tpiu config internal itm.txt uart off 8000000

# # OR: make the microcontroller SWO pin output compatible with UART (8N1)
# # 8000000 must match the core clock frequency
# # 2000000 is the frequency of the SWO pin
# monitor tpiu config external uart off 8000000 2000000

# # enable ITM port 0
# monitor itm port 0 on

load

# start the process but immediately halt the processor
stepi
run

A mcu_tests/slave_counter/src/main.rs => mcu_tests/slave_counter/src/main.rs +53 -0
@@ 0,0 1,53 @@
#![no_std]
#![no_main]

use cortex_m_semihosting::hprintln;
use cortex_m_semihosting::dbg;
use embedded_hal::blocking::i2c;
use hal::pwm::Timer;
use panic_halt as _;
use tm4c_hal::gpio; // you can put a breakpoint on `rust_begin_unwind` to catch panics

use cortex_m_rt::entry;
use tm4c123x_hal::{self as hal, prelude::*, delay::Delay, i2c::I2c};

#[entry]
fn main() -> ! {
    let p = hal::Peripherals::take().unwrap();
    let cp = hal::CorePeripherals::take().unwrap();

    let mut sc = p.SYSCTL.constrain();
    sc.clock_setup.oscillator = hal::sysctl::Oscillator::Main(
        hal::sysctl::CrystalFrequency::_16mhz,
        hal::sysctl::SystemClock::UsePll(hal::sysctl::PllOutputFrequency::_80_00mhz),
    );
    let clocks = sc.clock_setup.freeze();

    let mut portb = p.GPIO_PORTB.split(&sc.power_control);

    let scl = portb.pb2.into_af_push_pull::<hal::gpio::AF3>(&mut portb.control);
    let sda = portb.pb3.into_af_open_drain::<hal::gpio::AF3, gpio::Floating>(&mut portb.control);

    let mut i2c = I2c::i2c0(p.I2C0, (scl, sda), 100_000u32.hz(), &clocks, &sc.power_control);

    hprintln!("Hello world!");

    let mut delay = Delay::new(cp.SYST, &clocks);

    let mut buffer: [u8; 5] = [0; 5];
    const ADDRESS: u8 = 0b1110100;
    loop {
        let res = i2c.read(ADDRESS, &mut buffer);
        if res.is_ok() {
            for data in buffer {
                hprintln!("Got: {data}");
                dbg!(data);
            }
        }
        else {
            hprintln!("Got an error when trying to read :(");
        }

        delay.delay_ms(1000u16);
    }
}

A mcu_tests/slave_counter/toolchain.toml => mcu_tests/slave_counter/toolchain.toml +5 -0
@@ 0,0 1,5 @@
[toolchain]
channel = "nightly-2023-12-01"
components = [ "rustfmt", "rustc-dev", "rust-src" ]
targets = [ "thumbv7em-none-eabihf" ]
profile = "minimal"

A mcu_tests/slave_regs/.cargo/config => mcu_tests/slave_regs/.cargo/config +13 -0
@@ 0,0 1,13 @@
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
# uncomment ONE of these three option to make `cargo run` start a GDB session
# which option to pick depends on your system
runner = "arm-none-eabi-gdb -q -x openocd.gdb"
# runner = "gdb-multiarch -q -x openocd.gdb"
# runner = "gdb -q -x openocd.gdb"

rustflags = [
  "-C", "link-arg=-Tlink.x",
]

[build]
target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU)

A mcu_tests/slave_regs/.envrc => mcu_tests/slave_regs/.envrc +1 -0
@@ 0,0 1,1 @@
use flake

A mcu_tests/slave_regs/.gitignore => mcu_tests/slave_regs/.gitignore +14 -0
@@ 0,0 1,14 @@
# Generated by Cargo
# will have compiled files and executables
debug/
target/

# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock

# These are backup files generated by rustfmt
**/*.rs.bk

# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb

A mcu_tests/slave_regs/Cargo.toml => mcu_tests/slave_regs/Cargo.toml +26 -0
@@ 0,0 1,26 @@
[package]
name = "slave-regs"
version = "0.1.0"
edition = "2021"

[dependencies]
cortex-m = "0.7.7"
cortex-m-rt = "0.7.3"
cortex-m-semihosting = "0.5.0"
embedded-hal = "0.2.7"
panic-halt = "0.2.0"
tm4c-hal = "0.4.2"
tm4c123x-hal = { version = "0.10.3", features = ["rt"] }

[[bin]]
name = "slave-regs"
test = false
bench = false

[profile.release]
panic = "abort"
strip = true
codegen-units = 1
debug = false
lto = true
opt-level = "s"

A mcu_tests/slave_regs/flake.lock => mcu_tests/slave_regs/flake.lock +96 -0
@@ 0,0 1,96 @@
{
  "nodes": {
    "flake-utils": {
      "inputs": {
        "systems": "systems"
      },
      "locked": {
        "lastModified": 1681202837,
        "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=",
        "owner": "numtide",
        "repo": "flake-utils",
        "rev": "cfacdce06f30d2b68473a46042957675eebb3401",
        "type": "github"
      },
      "original": {
        "owner": "numtide",
        "repo": "flake-utils",
        "type": "github"
      }
    },
    "nixpkgs": {
      "locked": {
        "lastModified": 1703499205,
        "narHash": "sha256-lF9rK5mSUfIZJgZxC3ge40tp1gmyyOXZ+lRY3P8bfbg=",
        "owner": "NixOS",
        "repo": "nixpkgs",
        "rev": "e1fa12d4f6c6fe19ccb59cac54b5b3f25e160870",
        "type": "github"
      },
      "original": {
        "owner": "NixOS",
        "ref": "nixpkgs-unstable",
        "repo": "nixpkgs",
        "type": "github"
      }
    },
    "nixpkgs_2": {
      "locked": {
        "lastModified": 1681358109,
        "narHash": "sha256-eKyxW4OohHQx9Urxi7TQlFBTDWII+F+x2hklDOQPB50=",
        "owner": "NixOS",
        "repo": "nixpkgs",
        "rev": "96ba1c52e54e74c3197f4d43026b3f3d92e83ff9",
        "type": "github"
      },
      "original": {
        "owner": "NixOS",
        "ref": "nixpkgs-unstable",
        "repo": "nixpkgs",
        "type": "github"
      }
    },
    "root": {
      "inputs": {
        "nixpkgs": "nixpkgs",
        "rust-overlay": "rust-overlay"
      }
    },
    "rust-overlay": {
      "inputs": {
        "flake-utils": "flake-utils",
        "nixpkgs": "nixpkgs_2"
      },
      "locked": {
        "lastModified": 1703902408,
        "narHash": "sha256-qXdWvu+tlgNjeoz8yQMRKSom6QyRROfgpmeOhwbujqw=",
        "owner": "oxalica",
        "repo": "rust-overlay",
        "rev": "319f57cd2c34348c55970a4bf2b35afe82088681",
        "type": "github"
      },
      "original": {
        "owner": "oxalica",
        "repo": "rust-overlay",
        "type": "github"
      }
    },
    "systems": {
      "locked": {
        "lastModified": 1681028828,
        "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
        "owner": "nix-systems",
        "repo": "default",
        "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
        "type": "github"
      },
      "original": {
        "owner": "nix-systems",
        "repo": "default",
        "type": "github"
      }
    }
  },
  "root": "root",
  "version": 7
}

A mcu_tests/slave_regs/flake.nix => mcu_tests/slave_regs/flake.nix +29 -0
@@ 0,0 1,29 @@
{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
    rust-overlay.url = "github:oxalica/rust-overlay";
  };

  outputs = { self, nixpkgs, rust-overlay }: let
    system = "x86_64-linux";
    pkgs = import nixpkgs {
      inherit system;
      overlays = [rust-overlay.overlays.default];
    };

    toolchain = pkgs.rust-bin.fromRustupToolchainFile ./toolchain.toml;
  in {
    devShells.${system}.default = pkgs.mkShell {
      packages = [
        toolchain
        pkgs.rust-analyzer-unwrapped

        pkgs.openocd
        pkgs.gcc-arm-embedded
        pkgs.probe-rs
      ];

      RUST_SRC_PATH = "${toolchain}/lib/rustlib/src/rust/library";
    };
  };
}

A mcu_tests/slave_regs/openocd.cfg => mcu_tests/slave_regs/openocd.cfg +3 -0
@@ 0,0 1,3 @@
# Sample OpenOCD configuration for the Tiva-C Launchpad development board

source [find board/ti_ek-tm4c123gxl.cfg]

A mcu_tests/slave_regs/openocd.gdb => mcu_tests/slave_regs/openocd.gdb +33 -0
@@ 0,0 1,33 @@
target extended-remote :3333

# print demangled symbols
set print asm-demangle on

# detect unhandled exceptions, hard faults and panics
break DefaultHandler
# break UserHardFault
# break rust_begin_unwind

# *try* to stop at the user entry point (it might be gone due to inlining)
# break main

monitor arm semihosting enable

# # send captured ITM to the file itm.fifo
# # (the microcontroller SWO pin must be connected to the programmer SWO pin)
# # 8000000 must match the core clock frequency
# monitor tpiu config internal itm.txt uart off 8000000

# # OR: make the microcontroller SWO pin output compatible with UART (8N1)
# # 8000000 must match the core clock frequency
# # 2000000 is the frequency of the SWO pin
# monitor tpiu config external uart off 8000000 2000000

# # enable ITM port 0
# monitor itm port 0 on

load

# start the process but immediately halt the processor
stepi
run

A mcu_tests/slave_regs/src/main.rs => mcu_tests/slave_regs/src/main.rs +69 -0
@@ 0,0 1,69 @@
#![no_std]
#![no_main]

use cortex_m_semihosting::hprintln;
use cortex_m_semihosting::dbg;
use embedded_hal::blocking::i2c;
use hal::pwm::Timer;
use panic_halt as _;
use tm4c_hal::gpio; // you can put a breakpoint on `rust_begin_unwind` to catch panics

use cortex_m_rt::entry;
use tm4c123x_hal::{self as hal, prelude::*, delay::Delay, i2c::I2c};

#[entry]
fn main() -> ! {
    let p = hal::Peripherals::take().unwrap();
    let cp = hal::CorePeripherals::take().unwrap();

    let mut sc = p.SYSCTL.constrain();
    sc.clock_setup.oscillator = hal::sysctl::Oscillator::Main(
        hal::sysctl::CrystalFrequency::_16mhz,
        hal::sysctl::SystemClock::UsePll(hal::sysctl::PllOutputFrequency::_80_00mhz),
    );
    let clocks = sc.clock_setup.freeze();

    let mut portb = p.GPIO_PORTB.split(&sc.power_control);

    let scl = portb.pb2.into_af_push_pull::<hal::gpio::AF3>(&mut portb.control);
    let sda = portb.pb3.into_af_open_drain::<hal::gpio::AF3, gpio::Floating>(&mut portb.control);

    let mut i2c = I2c::i2c0(p.I2C0, (scl, sda), 100_000u32.hz(), &clocks, &sc.power_control);

    hprintln!("Hello world!");

    let mut delay = Delay::new(cp.SYST, &clocks);

    let mut buffer: [u8; 5] = [0; 5];
    let mut count: u8 = 0;
    const ADDRESS: u8 = 0b1110101;
    fn write_on(buffer: &mut [u8], address: u8, count: &mut u8) {
        for data in buffer.iter_mut() {
            *data = *count;
            *count = (*count).wrapping_add(1);
        }
        buffer[0] = address;
    }

    let mut rx_buffer: [u8; 20] = [0; 20];
    loop {
        write_on(&mut buffer, 0, &mut count);
        if i2c.write(ADDRESS, &mut buffer).is_err() {
            hprintln!("There was an error during write");
        }
        write_on(&mut buffer, 10, &mut count);
        if i2c.write(ADDRESS, &mut buffer).is_err() {
            hprintln!("There was an error during write");
        }

        let res = i2c.write_read(ADDRESS, &[0], &mut rx_buffer);
        if res.is_ok() {
            dbg!(rx_buffer);
        }
        else {
            hprintln!("Got an error when trying to read :(");
        }

        delay.delay_ms(1000u16);
    }
}

A mcu_tests/slave_regs/toolchain.toml => mcu_tests/slave_regs/toolchain.toml +5 -0
@@ 0,0 1,5 @@
[toolchain]
channel = "nightly-2023-12-01"
components = [ "rustfmt", "rustc-dev", "rust-src" ]
targets = [ "thumbv7em-none-eabihf" ]
profile = "minimal"

M src/mcu_slave/counter.vhd => src/mcu_slave/counter.vhd +3 -1
@@ 13,6 13,7 @@ entity counter is
  port (
    clk_i  : in std_logic;
    rst_i : in std_logic;
    rst_on : out std_logic;
    err_noack_o : out std_logic;
    bus_busy_o : out std_logic;
    dev_busy_o : out std_logic;


@@ 37,6 38,7 @@ architecture a1 of counter is
  signal tx_data : std_logic_vector(7 downto 0);
begin
  rst_n <= not rst_i;
  rst_on <= rst_n;

  next_count <= (curr_count + 1) mod MAX when go_next = '1' else
                curr_count;


@@ 48,7 50,7 @@ begin

  i2c_slave: entity i2c.slave
    generic map (
      SCL_FALLING_DELAY => 1)
      SCL_FALLING_DELAY => 15)
    port map (
      clk_i          => clk_i,
      rst_in         => rst_n,

M src/mcu_slave/regs.vhd => src/mcu_slave/regs.vhd +12 -5
@@ 7,12 7,10 @@ library i2c;

entity regs is

  generic (
    MAX : integer := 100);

  port (
    clk_i  : in std_logic;
    rst_i : in std_logic;
    rst_on : out std_logic;
    err_noack_o : out std_logic;
    bus_busy_o : out std_logic;
    dev_busy_o : out std_logic;


@@ 54,6 52,7 @@ architecture a1 of regs is
  signal rw : std_logic;
begin
  rst_n <= not rst_i;
  rst_on <= not rst_i;
  dev_busy_o <= dev_busy;

  next_dev_busy <= dev_busy;


@@ 85,7 84,7 @@ begin

  i2c_slave: entity i2c.slave
    generic map (
      SCL_FALLING_DELAY => 1)
      SCL_FALLING_DELAY => 15)
    port map (
      clk_i          => clk_i,
      rst_in         => rst_n,


@@ 128,9 127,17 @@ begin
  begin  -- process set_regs
    if rising_edge(clk_i) then          -- rising clock edge
      if rst_n = '0' then              -- synchronous reset (active low)
        curr_reg_address_filled <= '0';
        curr_dev_busy <= '0';
        curr_reg_address <= "00000000";
        curr_regs <= (others => (others => '0'));
      else
        curr_reg_address_filled <= next_reg_address_filled;
        curr_dev_busy <= next_dev_busy;
        curr_reg_address <= next_reg_address;
        curr_regs <= next_regs;
      end if;
    end if;
  end process set_regs;

end architecture a1;
end architecture a1;
\ No newline at end of file

M vivado/nsv_i2c.srcs/constrs_1/new/constraints.xdc => vivado/nsv_i2c.srcs/constrs_1/new/constraints.xdc +5 -5
@@ 59,7 59,7 @@ set_property -dict { PACKAGE_PIN E19   IOSTANDARD LVCMOS33 } [get_ports dev_busy

set_property -dict { PACKAGE_PIN U19   IOSTANDARD LVCMOS33 } [get_ports bus_busy_o]

#set_property -dict { PACKAGE_PIN V19   IOSTANDARD LVCMOS33 } [get_ports {led[3]}]
set_property -dict { PACKAGE_PIN V19   IOSTANDARD LVCMOS33 } [get_ports rst_on]

#set_property -dict { PACKAGE_PIN W18   IOSTANDARD LVCMOS33 } [get_ports {led[4]}]



@@ 133,9 133,9 @@ set_property -dict { PACKAGE_PIN U18   IOSTANDARD LVCMOS33 } [get_ports rst_i]

##Pmod Header JA

set_property -dict { PACKAGE_PIN J1   IOSTANDARD LVCMOS33 } [get_ports sda_io];#Sch name = JA1
#set_property -dict { PACKAGE_PIN J1   IOSTANDARD LVCMOS33 } [get_ports sda_io];#Sch name = JA1

set_property -dict { PACKAGE_PIN L2   IOSTANDARD LVCMOS33 } [get_ports scl_io];#Sch name = JA2
#set_property -dict { PACKAGE_PIN L2   IOSTANDARD LVCMOS33 } [get_ports scl_io];#Sch name = JA2

#set_property -dict { PACKAGE_PIN J2   IOSTANDARD LVCMOS33 } [get_ports {JA[2]}];#Sch name = JA3



@@ 152,9 152,9 @@ set_property -dict { PACKAGE_PIN L2   IOSTANDARD LVCMOS33 } [get_ports scl_io];#

##Pmod Header JB

#set_property -dict { PACKAGE_PIN A14   IOSTANDARD LVCMOS33 } [get_ports {JB[0]}];#Sch name = JB1
set_property -dict { PACKAGE_PIN A14   IOSTANDARD LVCMOS33 } [get_ports scl_io];#Sch name = JB1

#set_property -dict { PACKAGE_PIN A16   IOSTANDARD LVCMOS33 } [get_ports {JB[1]}];#Sch name = JB2
set_property -dict { PACKAGE_PIN A16   IOSTANDARD LVCMOS33 } [get_ports sda_io];#Sch name = JB2

#set_property -dict { PACKAGE_PIN B15   IOSTANDARD LVCMOS33 } [get_ports {JB[2]}];#Sch name = JB3


M vivado/nsv_i2c.xpr => vivado/nsv_i2c.xpr +6 -6
@@ 168,21 168,20 @@
          <Attr Name="UsedIn" Val="simulation"/>
        </FileInfo>
      </File>
      <File Path="$PPRDIR/../src/mcu_slave/counter.vhd">
      <File Path="$PPRDIR/../src/mcu_slave/regs.vhd">
        <FileInfo SFType="VHDL2008">
          <Attr Name="UsedIn" Val="synthesis"/>
          <Attr Name="UsedIn" Val="simulation"/>
        </FileInfo>
      </File>
      <File Path="$PPRDIR/../src/i2c/master.vhd">
      <File Path="$PPRDIR/../src/mcu_slave/counter.vhd">
        <FileInfo SFType="VHDL2008">
          <Attr Name="Library" Val="i2c"/>
          <Attr Name="AutoDisabled" Val="1"/>
          <Attr Name="UsedIn" Val="synthesis"/>
          <Attr Name="UsedIn" Val="simulation"/>
        </FileInfo>
      </File>
      <File Path="$PPRDIR/../src/i2c/address_generator.vhd">
      <File Path="$PPRDIR/../src/i2c/master.vhd">
        <FileInfo SFType="VHDL2008">
          <Attr Name="Library" Val="i2c"/>
          <Attr Name="AutoDisabled" Val="1"/>


@@ 190,8 189,9 @@
          <Attr Name="UsedIn" Val="simulation"/>
        </FileInfo>
      </File>
      <File Path="$PPRDIR/../src/mcu_slave/regs.vhd">
      <File Path="$PPRDIR/../src/i2c/address_generator.vhd">
        <FileInfo SFType="VHDL2008">
          <Attr Name="Library" Val="i2c"/>
          <Attr Name="AutoDisabled" Val="1"/>
          <Attr Name="UsedIn" Val="synthesis"/>
          <Attr Name="UsedIn" Val="simulation"/>


@@ 199,7 199,7 @@
      </File>
      <Config>
        <Option Name="DesignMode" Val="RTL"/>
        <Option Name="TopModule" Val="counter"/>
        <Option Name="TopModule" Val="regs"/>
      </Config>
    </FileSet>
    <FileSet Name="constrs_1" Type="Constrs" RelSrcDir="$PSRCDIR/constrs_1" RelGenDir="$PGENDIR/constrs_1">

Do not follow this link