Skip to main content
removed unavailable entity from testbench
Source Link
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity tb_switchpoint is

end tb_switchpoint;

architecture bh of tb_switchpoint is

  component spst_xpoint is
    port(
      d_n  : inout std_logic;
      d_s  : inout std_logic;
      d_e  : inout std_logic;
      d_w  : inout std_logic;
      en_x : in    std_logic;
      en_n : in    std_logic;
      en_s : in    std_logic;
      en_e : in    std_logic;
      en_w : in    std_logic
    );
  end component;

  component bus_io_dummy is
    port(
      bus_a  : inout std_logic;
      bus_b  : inout std_logic
    );
  end component;

  constant CLK_PERIOD: TIME := 5 ns;

  signal clk        : std_logic;
  signal i_n  : std_logic := 'Z';
  signal i_s  : std_logic := 'Z';
  signal i_e  : std_logic := 'Z';
  signal i_w  : std_logic := 'Z';
  signal en_x : std_logic := '0';
  signal en_n : std_logic := '0';
  signal en_s : std_logic := '0';
  signal en_e : std_logic := '0';
  signal en_w : std_logic := '0';

  signal clk_count  : std_logic_vector(31 downto 0) := (others => '0');
begin

  -- generate clk signal
  p_clk_gen : process
  begin
   clk <= '1';
   wait for (CLK_PERIOD / 2);
   clk <= '0';
   wait for (CLK_PERIOD / 2);
   clk_count <= std_logic_vector(unsigned(clk_count) + 1);
  end process;

  p_test : process(clk)
  begin
    if unsigned(clk_count) = 7 then
      en_n <= '1';
    end if;
    if unsigned(clk_count) = 9 then
      --en_s <= '1';
    end if;
    if unsigned(clk_count) = 11 then
      en_x <= '1';
    end if;
    if unsigned(clk_count) = 13 then
      en_e <= '1';
    end if;
    if unsigned(clk_count) = 15 then
      en_w <= '1';
    end if;
  end process;

  i_n <= clk_count(0);
  xpoint_dut_raw : spst_xpoint 
    port map (
      d_n  => i_n,
      d_s  => i_s,
      d_e  => i_e,
      d_w  => i_w,
      en_x => en_x,
      en_n => en_n,
      en_s => en_s,
      en_e => en_e,
      en_w => en_w
    );
end bh;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity tb_switchpoint is

end tb_switchpoint;

architecture bh of tb_switchpoint is

  component spst_xpoint is
    port(
      d_n  : inout std_logic;
      d_s  : inout std_logic;
      d_e  : inout std_logic;
      d_w  : inout std_logic;
      en_x : in    std_logic;
      en_n : in    std_logic;
      en_s : in    std_logic;
      en_e : in    std_logic;
      en_w : in    std_logic
    );
  end component;

  component bus_io_dummy is
    port(
      bus_a  : inout std_logic;
      bus_b  : inout std_logic
    );
  end component;

  constant CLK_PERIOD: TIME := 5 ns;

  signal clk        : std_logic;
  signal i_n  : std_logic := 'Z';
  signal i_s  : std_logic := 'Z';
  signal i_e  : std_logic := 'Z';
  signal i_w  : std_logic := 'Z';
  signal en_x : std_logic := '0';
  signal en_n : std_logic := '0';
  signal en_s : std_logic := '0';
  signal en_e : std_logic := '0';
  signal en_w : std_logic := '0';

  signal clk_count  : std_logic_vector(31 downto 0) := (others => '0');
begin

  -- generate clk signal
  p_clk_gen : process
  begin
   clk <= '1';
   wait for (CLK_PERIOD / 2);
   clk <= '0';
   wait for (CLK_PERIOD / 2);
   clk_count <= std_logic_vector(unsigned(clk_count) + 1);
  end process;

  p_test : process(clk)
  begin
    if unsigned(clk_count) = 7 then
      en_n <= '1';
    end if;
    if unsigned(clk_count) = 9 then
      --en_s <= '1';
    end if;
    if unsigned(clk_count) = 11 then
      en_x <= '1';
    end if;
    if unsigned(clk_count) = 13 then
      en_e <= '1';
    end if;
    if unsigned(clk_count) = 15 then
      en_w <= '1';
    end if;
  end process;

  i_n <= clk_count(0);
  xpoint_dut_raw : spst_xpoint 
    port map (
      d_n  => i_n,
      d_s  => i_s,
      d_e  => i_e,
      d_w  => i_w,
      en_x => en_x,
      en_n => en_n,
      en_s => en_s,
      en_e => en_e,
      en_w => en_w
    );
end bh;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity tb_switchpoint is

end tb_switchpoint;

architecture bh of tb_switchpoint is

  component spst_xpoint is
    port(
      d_n  : inout std_logic;
      d_s  : inout std_logic;
      d_e  : inout std_logic;
      d_w  : inout std_logic;
      en_x : in    std_logic;
      en_n : in    std_logic;
      en_s : in    std_logic;
      en_e : in    std_logic;
      en_w : in    std_logic
    );
  end component;

  constant CLK_PERIOD: TIME := 5 ns;

  signal clk        : std_logic;
  signal i_n  : std_logic := 'Z';
  signal i_s  : std_logic := 'Z';
  signal i_e  : std_logic := 'Z';
  signal i_w  : std_logic := 'Z';
  signal en_x : std_logic := '0';
  signal en_n : std_logic := '0';
  signal en_s : std_logic := '0';
  signal en_e : std_logic := '0';
  signal en_w : std_logic := '0';

  signal clk_count  : std_logic_vector(31 downto 0) := (others => '0');
begin

  -- generate clk signal
  p_clk_gen : process
  begin
   clk <= '1';
   wait for (CLK_PERIOD / 2);
   clk <= '0';
   wait for (CLK_PERIOD / 2);
   clk_count <= std_logic_vector(unsigned(clk_count) + 1);
  end process;

  p_test : process(clk)
  begin
    if unsigned(clk_count) = 7 then
      en_n <= '1';
    end if;
    if unsigned(clk_count) = 9 then
      --en_s <= '1';
    end if;
    if unsigned(clk_count) = 11 then
      en_x <= '1';
    end if;
    if unsigned(clk_count) = 13 then
      en_e <= '1';
    end if;
    if unsigned(clk_count) = 15 then
      en_w <= '1';
    end if;
  end process;

  i_n <= clk_count(0);
  xpoint_dut_raw : spst_xpoint 
    port map (
      d_n  => i_n,
      d_s  => i_s,
      d_e  => i_e,
      d_w  => i_w,
      en_x => en_x,
      en_n => en_n,
      en_s => en_s,
      en_e => en_e,
      en_w => en_w
    );
end bh;
deleted 2 characters in body
Source Link
toolic
  • 9.8k
  • 9
  • 27
  • 35
Source Link

How to model a 4-way inout crosspoint switch in VHDL?

I want to model a crosspoint switch with 4 inout ports that can route a signal coming from any of the inout ports to any other combination of the remaining inout ports depending on a series of enable SPST switches. This is for simulation only and not for any form of hardware implementation.

It should behave like the following picture:

![Schematic view of 4-way crosspoint switch]

My approach was the following VHDL code:

library ieee;
use ieee.std_logic_1164.all;

entity spst_xpoint is
  port(
    d_n  : inout std_logic;
    d_s  : inout std_logic;
    d_e  : inout std_logic;
    d_w  : inout std_logic;
    en_x : in    std_logic;
    en_n : in    std_logic;
    en_s : in    std_logic;
    en_e : in    std_logic;
    en_w : in    std_logic
  );
end entity;

architecture arch of spst_xpoint is
begin

    d_n <= d_s when (en_n = '1' and (d_s='0' or d_s='1') and en_s = '1') else
           d_e when (en_n = '1' and (d_e='0' or d_e='1') and en_e = '1' and en_x = '1') else
           d_w when (en_n = '1' and (d_w='0' or d_w='1') and en_w = '1' and en_x = '1') else 'Z';
    d_s <= d_n when (en_s = '1' and (d_n='0' or d_n='1') and en_n = '1') else
           d_e when (en_s = '1' and (d_e='0' or d_e='1') and en_e = '1' and en_x = '1') else
           d_w when (en_s = '1' and (d_w='0' or d_w='1') and en_w = '1' and en_x = '1') else 'Z';
    d_e <= d_w when (en_e = '1' and (d_w='0' or d_w='1') and en_w = '1') else
           d_n when (en_e = '1' and (d_n='0' or d_n='1') and en_n = '1' and en_x = '1') else
           d_s when (en_e = '1' and (d_s='0' or d_s='1') and en_s = '1' and en_x = '1') else 'Z';
    d_w <= d_e when (en_w = '1' and (d_e='0' or d_e='1') and en_e = '1') else
           d_n when (en_w = '1' and (d_n='0' or d_n='1') and en_n = '1' and en_x = '1') else
           d_s when (en_w = '1' and (d_s='0' or d_s='1') and en_s = '1' and en_x = '1') else 'Z';

end architecture;

If I simulate this in the case where I drive the d_n port with a signal, and enable en_n, en_e and en_x to pass the signal to the d_e port, it works. As soon as I want to drive multiple output ports (e.g. enabling en_s together with en_e and en_x) the simulation aborts because it is caught in a delta cycle loop (ghdl:info: simulation stopped @90ns by --stop-delta=5000).

Is the simulation of such an entity in VHDL even possible having such generic inout ports where the driving source is unknown?

Are there other approaches this could be made to work? Instead of the concurrent assignment of all 4 ports, a process with a sensitivity on all 4 ports could maybe work.

Testbench for reference:

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

entity tb_switchpoint is

end tb_switchpoint;

architecture bh of tb_switchpoint is

  component spst_xpoint is
    port(
      d_n  : inout std_logic;
      d_s  : inout std_logic;
      d_e  : inout std_logic;
      d_w  : inout std_logic;
      en_x : in    std_logic;
      en_n : in    std_logic;
      en_s : in    std_logic;
      en_e : in    std_logic;
      en_w : in    std_logic
    );
  end component;

  component bus_io_dummy is
    port(
      bus_a  : inout std_logic;
      bus_b  : inout std_logic
    );
  end component;

  constant CLK_PERIOD: TIME := 5 ns;

  signal clk        : std_logic;
  signal i_n  : std_logic := 'Z';
  signal i_s  : std_logic := 'Z';
  signal i_e  : std_logic := 'Z';
  signal i_w  : std_logic := 'Z';
  signal en_x : std_logic := '0';
  signal en_n : std_logic := '0';
  signal en_s : std_logic := '0';
  signal en_e : std_logic := '0';
  signal en_w : std_logic := '0';

  signal clk_count  : std_logic_vector(31 downto 0) := (others => '0');
begin

  -- generate clk signal
  p_clk_gen : process
  begin
   clk <= '1';
   wait for (CLK_PERIOD / 2);
   clk <= '0';
   wait for (CLK_PERIOD / 2);
   clk_count <= std_logic_vector(unsigned(clk_count) + 1);
  end process;

  p_test : process(clk)
  begin
    if unsigned(clk_count) = 7 then
      en_n <= '1';
    end if;
    if unsigned(clk_count) = 9 then
      --en_s <= '1';
    end if;
    if unsigned(clk_count) = 11 then
      en_x <= '1';
    end if;
    if unsigned(clk_count) = 13 then
      en_e <= '1';
    end if;
    if unsigned(clk_count) = 15 then
      en_w <= '1';
    end if;
  end process;

  i_n <= clk_count(0);
  xpoint_dut_raw : spst_xpoint 
    port map (
      d_n  => i_n,
      d_s  => i_s,
      d_e  => i_e,
      d_w  => i_w,
      en_x => en_x,
      en_n => en_n,
      en_s => en_s,
      en_e => en_e,
      en_w => en_w
    );
end bh;