Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
16 years ago

Bidirectional SPI switch?

This is a complex problem which I am very unsure of, the basic idea is that I want code that switches between 3 SPIs.

I was startled when I noticed the statement that I was about to write

A_SCLK <= C_SCLK

C_SCLK <= A_SCLK

both are true, but this would induce registers, all I want is a wire connection.


-- The idea is that choose either A or B is exclusively
-- connected to C
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity bidir_SPI_switch is
    port(
        A_SCLK, B_SCLK, C_SCLK        :    INOUT STD_LOGIC;
        A_SOMI, B_SOMI, C_SOMI        :    INOUT STD_LOGIC;
        A_SIMO, B_SIMO, C_SIMO        :    INOUT STD_LOGIC;
        A_CSn, B_CSn, C_CSn    :    INOUT STD_LOGIC;
        en, S    : IN BIT
    ); 
end bidir_SPI_switch;
architecture behaviour of bidir_SPI_switch is
    process(en,S)
    begin
-- MASTER enable
        if en = '0' then
            A_SCLK                   HOW??
            C_SCLK
        else
-- SELECT either A or B
        end if;
    end process;

14 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I can't make it happen. Have a look at the attachment for the results.

    Basically, it should just be a mechanical switch i.e.

    when en = 0, wire A should be connected to wire C.

    when en = 1, wire B should be connected to wire C.

    
    -- The idea is that choose either A or B is exclusively
    -- connected to C
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    entity bidir_SPI_switch is
        port(
            A_SCLK, B_SCLK, C_SCLK        :    INOUT STD_LOGIC;
            en, S    : IN BIT
        );
                
    end bidir_SPI_switch;
    architecture behaviour of bidir_SPI_switch is
    begin
        process(en,S)
        begin
    -- MASTER enable
            if en = '0' then
                A_SCLK <= C_SCLK;
                B_SCLK <= 'Z';
                C_SCLK <= A_SCLK;
            else
    -- SELECT either A or B
                A_SCLK <= 'Z';
                C_SCLK <= B_SCLK;
                B_SCLK <= C_SCLK;
            end if;
        end process;
    end architecture behaviour;
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Some points of the original post seems confused. SPI implies either master or slave role, for this reason none of the standard SPI signals would be bidirectional respectively inoout normally. It's of course possible to design an SPI interface that changes between master and slave role, but you didn't mention this.

    It's also wrong to say that a VHDL assignment involves registers. This is only the case, if it executes under a edge sensitive event condition. You can have combinational process statements as well, they infer multiplexers, as apparently intended here.

    --- Quote End ---

    Apologies for the confusion. What I intend to do is have 3 SPI ports where any of the nodes connected could either be a master or slave. it is a truly bidirectional system then.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Some points of the original post seems confused. SPI implies either master or slave role, for this reason none of the standard SPI signals would be bidirectional respectively inoout normally. It's of course possible to design an SPI interface that changes between master and slave role, but you didn't mention this.

    It's also wrong to say that a VHDL assignment involves registers. This is only the case, if it executes under a edge sensitive event condition. You can have combinational process statements as well, they infer multiplexers, as apparently intended here.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    If I have understood you, you have A,B,C SPI interfaces and you want C to talk to either A or B:

    (1) C to A or B

    Since you have chipselect then you can drive both at same time then use chipselect.

    (2) A or B to C: use your switch to drive C

    This pseudocode may explain my idea:

    
    if OE = ?
        A <= C;
        B <= C;
        C <= 'Z';
    else 
        A <= 'Z';
        B <= 'Z';
        if select = ?
            C <= A;
        else
            C <= B;
        end if;
    end if;