Multiplexing bidirectional IO in Verilog?

Status
Not open for further replies.

Artlav

Full Member level 2
Joined
Nov 26, 2010
Messages
144
Helped
2
Reputation
4
Reaction score
2
Trophy points
1,298
Activity points
2,723
I want to have a SPI flash chip that can do 4-bit IO to be accessible as both a memory mapped device to a soft CPU for reading, and as an SPI device for direct access to all the other commands in it, selectable by a register (fl_mem_enable).

This requires multiplexing of inout signals, and i can't quite figure out how to do it.
The code below mostly works - SPI mode works fully, but the mem mode does not get any data into it.
Apparently assignment like "assign FL_IO =fl_mem_enable?mem_FL_IO:{3'bz,gio_FL_MOSI};" only controls the output and enable parts of inout, but does not pass the input part.
However, trying to add something like "assign mem_FL_IO=FL_IO;" or "assign mem_FL_IO=fl_mem_enable?FL_IO:4'b0000;" gives out errors.

So, what am i doing wrong or how to do it right?


Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
module top(
 //...
 
 //SPI FLASH
 output FL_CS,
 output FL_SCK,
 inout [3:0] FL_IO,
 
 //...
);
 
wire mem_FL_CS;
wire mem_FL_SCK;
wire [3:0] mem_FL_IO;
 
wire gio_FL_CS;
wire gio_FL_SCK;
wire gio_FL_MOSI;
 
wire fl_mem_enable;
 
assign FL_CS =fl_mem_enable?mem_FL_CS:gio_FL_CS;
assign FL_SCK=fl_mem_enable?mem_FL_SCK:gio_FL_SCK;
assign FL_IO =fl_mem_enable?mem_FL_IO:{3'bz,gio_FL_MOSI};
 
spi_flash mem(
 //...
 .CS(mem_FL_CS),
 .SCK(mem_FL_SCK),
 .IO(mem_FL_IO),
 //...
);
 
gio sysgio(
 //...
 .FLROM_CS(gio_FL_CS),
 .FLROM_SCK(gio_FL_SCK),
 .FLROM_MISO(FL_IO[1]),
 .FLROM_MOSI(gio_FL_MOSI),
 .fl_mem_enable(fl_mem_enable),
 //...
);

 

We can only guess about the declaration of the spi_flash_mem IO port.
The point is that mem_FL_IO must not have multiple drivers, also the FL_IO pins must be tri-stated to read data.

If any FL_IO pin is used bidirectional (data direction changes on the fly), spi_flash mem must perform the direction control. This can be either done explicitly with respective OE signal(s), or implicitly by connecting spi_flash mem inout ports directly to top-level inout. In the latter case, the top level connection could look like:

Code:
assign FL_IO =fl_mem_enable?4'bz:{3'bz,gio_FL_MOSI};

spi_flash mem(
 //...
 .CS(mem_FL_CS),
 .SCK(mem_FL_SCK),
 .IO(FL_IO),
 //...
);
 

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…