0
\$\begingroup\$

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;

  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;
\$\endgroup\$
2
  • 3
    \$\begingroup\$ Hi, first off: is this a homework question? If not, what's the actual application? \$\endgroup\$
    – TonyM
    Commented Oct 29, 2023 at 11:16
  • \$\begingroup\$ @TonyM For a personal passion project. I want to simulate a reconfigurable interconnect. \$\endgroup\$
    – mnemocron
    Commented Oct 30, 2023 at 7:46

1 Answer 1

1
\$\begingroup\$

You would need first need a "pass transistor" primitive.

In Verilog, there is tranif1 my_gate1 (net1, net2, net3); and cmos which connects net1 with net2 when net3 is high. I'm pretty sure VHDL does not have an equivalent, and can't do "switch level modelling" without some additions to the language and simulator.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Functionality Support in HDLs looks relevant, but the link to eetimes.com/functionality-support-in-hdls/www.isdmag.com/… which is supposed to contain bi-directional pass gate VHDL and Verlog models is dead. \$\endgroup\$ Commented Oct 29, 2023 at 19:39
  • \$\begingroup\$ It seems the reason VHDL doesn't support gates like this by default is the way it handles events - (From Ashenden book, pg 601) "the postponed process must not schedule transactions on signals with delta delays. If they did, they would cause another delta cycle at the current simulation time, meaning that the postponed process should not have executed. The restriction is required to avoid this paradox". - from the discussion at computer-programming-forum.com/42-vhdl/29f6b2486ee177aa.htm \$\endgroup\$
    – Miron
    Commented Oct 29, 2023 at 19:42
  • 1
    \$\begingroup\$ I tried to teach myself Verilog but figured that none of the simulators that are available to (Verilator, Vivado) me support this language feature of Verilog. I managed to implement a workaround in VHDL. At configuration time (when the en_ signals are assigned a value) the entity determines the driving port(s) that act as an input (if they have a value 0 or 1 instead of U or Z). Then the signal is propagated to the other ports from the driving ports. gist.github.com/mnemocron/d71964e86d7e84d865e9e8093412d3e1 \$\endgroup\$
    – mnemocron
    Commented Nov 1, 2023 at 7:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.