Reputation: 6676
I'm trying to understand how pins should be defined in SystemVerilog.
I have:
dataBus
ramController
module which can send or receive data on its ioData
pins.ramController
(e.g. prepare a display buffer)vgaController
which mostly receives data from the ramController
but also has a command mode which allows it to be configured using data on the dataBus
The ioData
pins in the ramController
are bi-directional but also need to be tri-state so that the ramController
can be "off the bus" when dataBus
is being used to send commands to the vgaController
module RAMController(
inout wire[15 : 0 ] ioData,
..
);
..
logic [15 : 0 ] ioDataCopy;
assign ioData = ( chipSelect ) ? ioDataCopy : 16'hzzzzzzzzzzzzzzzz;
Even if vgaController never writes to the dataBus, does it's pins need to be inout in order to be input or HiZ?
module VGAController(
inout wire [15 : 0 ] iData;
);
..
logic [15 : 0 ] iDataCopy = 0;
assign iData = ( chipSelect ) ? iDataCopy : 16'bzzzzzzzzzzzzzzzz;
Is dataBus
simply a set of wire values in the top module?
module Top(
..
);
..
wire [15 : 0 ] dataBus;
I may be going about this completely wrong. Can someone please help me in defining a system containing multiple modules that share the same bus.
Upvotes: 3
Views: 1380
Reputation: 12344
It is difficult to say if you did it right or wrong without a reproducible example. However, some of your assertions are basically correct. I assume that your dataBus
is same as your ioData
at the controller level. In this case if both controllers are instantiated in 'top' and are connected correctly, you should be all set. You have to make sure that there is always only a single driver for the bus, so that 'chipSelect' prevents from multiple driving of the bus.
So, here is an example that demonstrates the above.
module Top();
wire [15 : 0 ] dataBus;
logic[1:0] select;
RAMController rc(.ioData(dataBus), .chipSelect(select == 1 ? 1 : 0));
VGAController vc(.ioData(dataBus), .chipSelect(select == 2 ? 1 : 0));
always @*
$display("%0t select: %b, data: %b", $time, select, dataBus);
initial begin
select = 0;
#1 select = 1;
#1 select = 0;
#1 select = 2;
#1 select = 0;
#1 $finish;
end
endmodule
module RAMController(
inout wire[15 : 0 ] ioData,
input logic chipSelect
//...
);
logic [15 : 0 ] ioDataCopy = 1;
assign ioData = ( chipSelect ) ? ioDataCopy : 'z;
endmodule
module VGAController(
inout wire[15 : 0 ] ioData,
input logic chipSelect
//...
);
logic [15 : 0 ] ioDataCopy = 2;
assign ioData = ( chipSelect ) ? ioDataCopy : 'z;
endmodule
and the result:
0 select: 00, data: xxxxxxxxxxxxxxxx
0 select: 00, data: zzzzzzzzzzzzzzzz
1 select: 01, data: zzzzzzzzzzzzzzzz
1 select: 01, data: 0000000000000001
2 select: 00, data: 0000000000000001
2 select: 00, data: zzzzzzzzzzzzzzzz
3 select: 10, data: zzzzzzzzzzzzzzzz
3 select: 10, data: 0000000000000010
4 select: 00, data: 0000000000000010
4 select: 00, data: zzzzzzzzzzzzzzzz
To be more verbose you could use tri
definition instead of wire
. There is no difference between them, but makes the code more readable, IMHO.
tri [15:0] dataBus;
...
tri [15:0] ioData;
Upvotes: 2