Making output-port to bi-directional-port!

V

Vick

Guest
Hello everyone,

I am facing problems making an output-port to a bi-directional port.

//////////////////////////////////////////////////////
///// (A) Here is the code, which compiles correctly:
/////////////////////////////////////////////////////
module SRAMinterface (AD,clock, WE, RE)

input clock;
input WE;
input RE;


output [31:0] AD;
reg [31:0] AD;

reg [7:0] A;
reg [7:0] B;
reg [7:0] C;
reg [7:0] D;

reg E,F;

always @(posedge clock)
begin
if (E==F)
begin
assign AD = {A,B,C,D};
end

else assign AD = 8'hzzzzzzzz;
end
end
endmodule


/////////////////////////////////////////////////////////////////
//// (B) Here is the Code, which gives the error as shown below:
////////////////////////////////////////////////////////////////

module SRAMinterface (AD,clock, WE, RE)

input clock;
input WE;
input RE;


inout [31:0] AD; // Note: This gives error when AD declared as
inout-port //
reg [31:0] AD; // Declaring: wire [31:0] AD also didnt compile!

reg [7:0] A;
reg [7:0] B;
reg [7:0] C;
reg [7:0] D;

reg E,F;

always @(posedge clock)
begin
if (E==F)
begin
assign AD = {A,B,C,D};
//// The error is shown at this line saying Incompatible inout port
////
end

else assign AD = 8'hzzzzzzzz;
end
end
endmodule



I tried the following but none of them compiled:

(1) I know that Inout-ports both internally & externally must always
be net type. So I declared: <wire [31:0] AD > in (B) above

(2) The LRM clearly says that any continuous assignment within any
procedural-statements, namely always (or) initial, has to be a
register, So retained AD as reg while it was declared inout-port.


(3) I also rememeber reading earlier that the Conditional-assignment
needs to be used for bi-directional ports.

So I replaced the above always @(..) block to a conditional assignment
as below:

assign AD = (E==F) ? {A,B,C,D} : 8'hzzzzzzzz;


Is there soemthing very obvious, I am missing!!
 
Vick wrote:
I am facing problems making an output-port to a bi-directional port.

//////////////////////////////////////////////////////
///// (A) Here is the code, which compiles correctly:
//////////////////////////////////////////////////////
assign AD = {A,B,C,D};
Independent of what you are trying to do, you don't want to have
the keyword "assign" here. That makes this a "procedural continuous
assignment" or "quasi-continuous assignment", which is much like a
"force" statement. What you want here is a simple blocking assignment
to the reg: " AD = {A,B,C,D};" Don't use "assign" inside procedural
code (unless you understand what it means and know that is what you
really want).

I tried the following but none of them compiled:

(1) I know that Inout-ports both internally & externally must always
be net type. So I declared: <wire [31:0] AD > in (B) above
But it is illegal to assign to a wire from procedural code, as you
note in 2 below.

(2) The LRM clearly says that any continuous assignment within any
procedural-statements, namely always (or) initial, has to be a
register, So retained AD as reg while it was declared inout-port.
But it is illegal to have an inout port declared as reg, as you note
in 1 above.

You must satisfy both restrictions.

A wire must be driven by drivers (gates, continuous assignments), and
cannot be assigned in procedural code as if it were a variable. A reg
acts like a variable, but cannot be driven by drivers (which means no
multiple driver resolution), and cannot pass through a port, and cannot
be connected to an inout port. An output reg port is just short-hand
for a variable inside the module with an implicit continuous assignment
through the port to a net on the outside.

To make this work, you need an inout port which is a net, both inside
and outside the module. But then you can't use the short-hand for the
implicit continuous assignment from a reg to the net. If you want to
drive a value onto the net from the local source, you will need to do
so with an explicit continuous assignment.

(3) I also rememeber reading earlier that the Conditional-assignment
needs to be used for bi-directional ports.

So I replaced the above always @(..) block to a conditional
assignment
as below:

assign AD = (E==F) ? {A,B,C,D} : 8'hzzzzzzzz;
If you replaced the entire always block (which assigned to a reg) with
a continuous assignment that drives the wire AD, this should work.
That
would satisfy the requirements that the inout port be a net, and that
the net was driven by drivers, not procedural assignments.

Alternately, you could keep the always block and have it assign to an
intermediate reg, then have an explicit continuous assignment of the
reg value to the net.
 

Welcome to EDABoard.com

Sponsor

Back
Top