Open-drain bus

Guest
I figured out how to model an open-drain pin:

assign y = x ? 1'bZ : 0;

Now I'd like to do the same for a bus:

wire [7:0] x, [7:0] y;
assign y = x ? 1'bZ : 0;

The above clearly isn't going to work. Is this where the `for'
preprocessor statement is used? Is there any operator that looks like a
bus-oriented ?: operator?

Please cc me in your reply. Thanks!
Shaun
 
The OR and AND operators tend to give you what you need if you think in bus
terms. While I use this regularly to define always-driven bus logic, I
would expect that
1'bz & 1'b1 == 1'bz
1'bz | 1'b1 == 1'b1
1'bz & 1'b0 == 1'b0
and
1'bz | 1'b0 == 1'bz
but I haven't verified this.

If it works:
assign y = 8'bz & x;


<sjackman@gmail.com> wrote in message
news:1167951009.321435.267250@38g2000cwa.googlegroups.com...
I figured out how to model an open-drain pin:

assign y = x ? 1'bZ : 0;

Now I'd like to do the same for a bus:

wire [7:0] x, [7:0] y;
assign y = x ? 1'bZ : 0;

The above clearly isn't going to work. Is this where the `for'
preprocessor statement is used? Is there any operator that looks like a
bus-oriented ?: operator?

Please cc me in your reply. Thanks!
Shaun
 
John_H wrote:
The OR and AND operators tend to give you what you need if you think in bus
terms. While I use this regularly to define always-driven bus logic, I
would expect that
1'bz & 1'b1 == 1'bz
1'bz | 1'b1 == 1'b1
1'bz & 1'b0 == 1'b0
and
1'bz | 1'b0 == 1'bz
but I haven't verified this.

If it works:
assign y = 8'bz & x;
I tried testing with Icarus verilog and it produced the following
results:

z & 1 == x
z & 0 == 0

It was a good idea, John, but it doesn't seem to work. Too bad.

Cheers,
Shaun
 
Here's the "for loop" solution. Verified with Quartus.

module Bus_Z_Solutions(
input [7:0] BusX,
output reg [7:0] BusY
);

always begin
begin : looptheZsss
integer i;

for( i = 0 ; i < 8 ; i = i + 1) begin
BusY = BusX ? 1'h Z : 1'h 0;
end
end
end

endmodule

johnn

sjackman@gmail.com wrote:
John_H wrote:
The OR and AND operators tend to give you what you need if you think in bus
terms. While I use this regularly to define always-driven bus logic, I
would expect that
1'bz & 1'b1 == 1'bz
1'bz | 1'b1 == 1'b1
1'bz & 1'b0 == 1'b0
and
1'bz | 1'b0 == 1'bz
but I haven't verified this.

If it works:
assign y = 8'bz & x;

I tried testing with Icarus verilog and it produced the following
results:

z & 1 == x
z & 0 == 0

It was a good idea, John, but it doesn't seem to work. Too bad.

Cheers,
Shaun
 
If you don't have to synthesize the result (at least I don't think it
will synthesize correctly), you could use something like the
following...

----------------------------------
module t;

wire [7:0] x;
reg [7:0] a, b;

pullup p[7:0](x);
assign (highz1, strong0) x = a;
assign (highz1, strong0) x = b;

initial begin
a = 0;
b = 0;
#100 a = 'h55;
#100 b = 'hFF;
#100 a = 'hAA;
#100 b = 'h55;
#100 a = 'hFF;
#100 $finish;
end

endmodule
----------------------------------

David Walker

sjackman@gmail.com wrote:
I figured out how to model an open-drain pin:

assign y = x ? 1'bZ : 0;

Now I'd like to do the same for a bus:

wire [7:0] x, [7:0] y;
assign y = x ? 1'bZ : 0;

The above clearly isn't going to work. Is this where the `for'
preprocessor statement is used? Is there any operator that looks like a
bus-oriented ?: operator?

Please cc me in your reply. Thanks!
Shaun
 
There are three solutions:

1.
module my_tri_state_buf(control, data, out);
input control, data;
inout out;
assign out = control ? 1'bz : data;
endmodule

then

my_tri_state_buf my_tri_state_buf[7:0] (x, 8'b0, y);

2.
bufif0 my_buffers[7:0] (y, x, 8'b0);

3. Make instantiation of tri-state-buffer from your library (which is
similar to #1):

tri_state_buf_from_lib my_buffers[7:0] (y, x, 8'b0);
 
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

sjackman@gmail.com wrote:
I figured out how to model an open-drain pin:

assign y = x ? 1'bZ : 0;

Now I'd like to do the same for a bus:

wire [7:0] x, [7:0] y;
assign y = x ? 1'bZ : 0;

The above clearly isn't going to work. Is this where the `for'
preprocessor statement is used? Is there any operator that looks like a
bus-oriented ?: operator?
Maybe something like this:

bufif0 x[7:0] (y, 8'b0, x);


- --
Steve Williams "The woods are lovely, dark and deep.
steve at icarus.com But I have promises to keep,
http://www.icarus.com and lines to code before I sleep,
http://www.picturel.com And lines to code before I sleep."
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)
Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org

iD8DBQFFnpJ+rPt1Sc2b3ikRAkzdAKDeZx6/Jq1apRIfBG8Al7hln7SGjQCfSubw
dUNEqN4mRvKS6AEj40q4XFI=
=ZXBh
-----END PGP SIGNATURE-----
 
I usually use this technique rather than the for-loop version.
(personal preference)

But the OP asked for an OC, not a 3-state.
----
module my_oc_buf(data, out);
input data;
output out;

assign out = data ? 1'bz : 1'b0;

endmodule

my_oc_buf my_oc_buf [7:0] (x,y);
-----
GH

Michael wrote:
There are three solutions:

1.
module my_tri_state_buf(control, data, out);
input control, data;
inout out;
assign out = control ? 1'bz : data;
endmodule

then

my_tri_state_buf my_tri_state_buf[7:0] (x, 8'b0, y);

2.
bufif0 my_buffers[7:0] (y, x, 8'b0);

3. Make instantiation of tri-state-buffer from your library (which is
similar to #1):

tri_state_buf_from_lib my_buffers[7:0] (y, x, 8'b0);
 
Stephen Williams wrote:
Maybe something like this:

bufif0 x[7:0] (y, 8'b0, x);
Perfect! That's exactly what I wanted. Thanks, Stephen (and others who
suggested the same thing).

I looked over this list of primitive instances [1] and found that the
basic 2-input multiplexer is missing. As in the primitive version of
out = sel ? a : b.

mux foo(out, sel, a, b);

Is there a particular reason for this omission?

Cheers,
Shaun

[1]
http://www.sutherland-hdl.com/on-line_ref_guide/vlog_ref_body.html#9.0
Primitive Instances
 
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Shaun wrote:
Stephen Williams wrote:
Maybe something like this:

bufif0 x[7:0] (y, 8'b0, x);

Perfect! That's exactly what I wanted. Thanks, Stephen (and others who
suggested the same thing).

I looked over this list of primitive instances [1] and found that the
basic 2-input multiplexer is missing. As in the primitive version of
out = sel ? a : b.

mux foo(out, sel, a, b);

Is there a particular reason for this omission?
You can create a simple user defined primitive to do that, and
you can array them in the same way.

- --
Steve Williams "The woods are lovely, dark and deep.
steve at icarus.com But I have promises to keep,
http://www.icarus.com and lines to code before I sleep,
http://www.picturel.com And lines to code before I sleep."
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)
Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org

iD8DBQFFpbgZrPt1Sc2b3ikRAtqZAKCE+EzxlAkmsQGAZ74LxUyza1DMuwCcDzsJ
4y5agFAuo86E3a0mIxp7hho=
=2dvX
-----END PGP SIGNATURE-----
 
sjackman@gmail.com wrote:
I figured out how to model an open-drain pin:

assign y = x ? 1'bZ : 0;
As David Walker described, the more straightforward way to model this
for simulation is by specifying the high/low drive strengths of the
driver (continuous assignment or gate). This capability is in the
language for this purpose.

However, I don't know about synthesis.
 

Welcome to EDABoard.com

Sponsor

Back
Top