- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Try this idea...
you better think of signal driving another than connectivity. remember connectivity in HDL does not mean that each side is driving the other. you will need three choices: if A master then A_sclk <= 'Z'; --driven from A chip B_sclk <= A_sclk; C_sclk <= A_sclk; elsif B master then ....- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You can't route a bidirectional signal without an explicite direction information.
I asked about the SPI master and slave roles, because I can hardly imagine a SPI network, where the peers change their role spontaneously. At least, it hasn't anything to do with known SPI standards. You have similar problems however with true bidirectional lines, e.g. an I2C bus or simply the data lines of a processor bus. If a FPGA is intended to route a signal of this kind, it must be supplied with an additional direction information, or it has to decode the communication protocol and determine the actual data direction from it's protocol knowledge, if possible at all.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks FvM and Kaz, I see your point now.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Here is my implementation. Last question, is it possible to put an internal pull-up on the chip select (CSn) signals?
-- The idea is that choose either A or B is exclusively
-- connected to O
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity bidir_SPI_switch is
port(
en, S : IN BIT;
A_CSn, A_SCLK, A_SIMO, A_SOMI : INOUT STD_LOGIC;
B_CSn, B_SCLK, B_SIMO, B_SOMI : INOUT STD_LOGIC;
O_CSn, O_SCLK, O_SIMO, O_SOMI : INOUT STD_LOGIC
);
end bidir_SPI_switch;
architecture behaviour of bidir_SPI_switch is
begin
process(en,S,
A_CSn, A_SCLK, A_SIMO, A_SOMI,
B_CSn, B_SCLK, B_SIMO, B_SOMI,
O_CSn, O_SCLK, O_SIMO, O_SOMI)
begin
-- change default state of each port depending on if
-- the port is a Master only, Slave only or both.
A_CSn <= 'Z';
A_SCLK <= 'Z';
A_SIMO <= 'Z';
A_SOMI <= 'Z';
B_CSn <= 'Z';
B_SCLK <= 'Z';
B_SIMO <= 'Z';
B_SOMI <= 'Z';
O_CSn <= 'Z';
O_SCLK <= 'Z';
O_SIMO <= 'Z';
O_SOMI <= 'Z';
-- when disabled, A <=> O
if en = '0' then
if (A_CSn = '0') then
O_CSn <= '0';
O_SCLK <= A_SCLK;
O_SIMO <= A_SIMO;
A_SOMI <= O_SOMI;
end if;
if (O_CSn = '0') then
A_CSn <= '0';
A_SCLK <= O_SCLK;
A_SIMO <= O_SIMO;
O_SOMI <= A_SOMI;
end if;
-- when enabled
else
-- S = 0, A <=> O
if (S = '0') then
if (A_CSn = '0') then
O_CSn <= '0';
O_SCLK <= A_SCLK;
O_SIMO <= A_SIMO;
A_SOMI <= O_SOMI;
end if;
if (O_CSn = '0') then
A_CSn <= '0';
A_SCLK <= O_SCLK;
A_SIMO <= O_SIMO;
O_SOMI <= A_SOMI;
end if;
-- S = 1, B <=> O
else
if (B_CSn = '0') then
O_CSn <= '0';
O_SCLK <= B_SCLK;
O_SIMO <= B_SIMO;
B_SOMI <= O_SOMI;
end if;
if (O_CSn = '0') then
B_CSn <= '0';
B_SCLK <= O_SCLK;
B_SIMO <= O_SIMO;
O_SOMI <= B_SOMI;
end if;
end if; -- S = '1'
end if; -- en = '1'
end process;
end architecture behaviour;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
That code was no good because it created a race condition.
This fixes it:
-- 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(
en, S : IN BIT;
A_CSn, A_SCLK, A_SIMO, A_SOMI : INOUT STD_LOGIC;
B_CSn, B_SCLK, B_SIMO, B_SOMI : INOUT STD_LOGIC;
O_CSn, O_SCLK, O_SIMO, O_SOMI : INOUT STD_LOGIC
);
end bidir_SPI_switch;
architecture behaviour of bidir_SPI_switch is
begin
process(en,S,
A_CSn, A_SCLK, A_SIMO, A_SOMI,
B_CSn, B_SCLK, B_SIMO, B_SOMI,
O_CSn, O_SCLK, O_SIMO, O_SOMI)
begin
-- change default state of each port depending on if
-- the port is a Master only, Slave only or both.
A_CSn <= 'Z';
A_SCLK <= 'Z';
A_SIMO <= 'Z';
A_SOMI <= 'Z';
B_CSn <= 'Z';
B_SCLK <= 'Z';
B_SIMO <= 'Z';
B_SOMI <= 'Z';
O_CSn <= 'Z';
O_SCLK <= 'Z';
O_SIMO <= 'Z';
O_SOMI <= 'Z';
-- when disabled, A <=> O
if en = '0' then
if (A_CSn = '0') then
O_CSn <= '0';
O_SCLK <= A_SCLK;
O_SIMO <= A_SIMO;
A_SOMI <= O_SOMI;
elsif (O_CSn = '0') then
A_CSn <= '0';
A_SCLK <= O_SCLK;
A_SIMO <= O_SIMO;
O_SOMI <= A_SOMI;
end if;
-- when enabled
else
-- S = 0, A <=> O
if (S = '0') then
if (A_CSn = '0') then
O_CSn <= '0';
O_SCLK <= A_SCLK;
O_SIMO <= A_SIMO;
A_SOMI <= O_SOMI;
elsif (O_CSn = '0') then
A_CSn <= '0';
A_SCLK <= O_SCLK;
A_SIMO <= O_SIMO;
O_SOMI <= A_SOMI;
end if;
-- S = 1, B <=> O
else
if (B_CSn = '0') then
O_CSn <= '0';
O_SCLK <= B_SCLK;
O_SIMO <= B_SIMO;
B_SOMI <= O_SOMI;
elsif (O_CSn = '0') then
B_CSn <= '0';
B_SCLK <= O_SCLK;
B_SIMO <= O_SIMO;
O_SOMI <= B_SOMI;
end if;
end if; -- S = '1'
end if; -- en = '1'
end process;
end architecture behaviour;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Did you look at the RTL schematic ?
Does it look OK ?- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Couldn't make full sense of what was happening. However, it did simulate it well.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This has been unsuccessful, it seems nothing is going through the switch.
Is there an example code out there that shows how to build a Bidirectional bus and the assumptions required of the entities that connect to it. This is doing me head in.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In my opinion, the problem is a lack of clarity about the required prerequisites of a bidirectional "switch". A FPGA doesn't offer bidirectional bus switches of analog switch type. It can implement bidirectional buffers, similar e.g. to a 74HC245, that however need a control signal to decide about the actual data direction.
You have to find out, how this direction information can be deterrmined.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks FvM, I've added an extra pin in the design for direction and now it works fine in simulation with the bigger design.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page