Verlilog simualte a port pin with switchable pull up

avrportverilog

I want to simulate two avr pins in verilog connected to one wire. Every avr can be in and output and also have the ability to switch its own pull up.

I found the typical way to connect to pins to one wire by something like:

assign io_port  = direction ? a : 1'bz;

where the pin can select the driving state.

But I have no idea how to set the wire to high state, if non of the pins drive active the wire but one or more of the pins have the pull up enabled. I think that there should be more then high/low/tristate/undefined for the wire. But as I know there is nothing like 'pullup'.

As a consequence I have to code all connected pins to a wire with own code. So the logic must be implemented manually and can not use the wire as it is?

I have the following code which do NOT work, because calling multiple times to my connection module will result in ?overwrite? the assignments instead of adding multiple inputs.

As you can see, it feels I have a basic misunderstanding how multiple wires or regs can be added to one wire.

Q1: How to deal with the multiple regs/wires to one wire assignments.
What I did is simply wrong. But how can I "connect" multiple ports to
my wire without writing the complete assignment manually. I simply need a starter tip on how to deal with subsequent adding regs to wires. Maybe my
idea for a wire is wrong?

Q2: How is the standard way to add an pull_up for a device IO-pin.

My source which fails because of the above mentioned problems I already know but can't be solved from myself.

module connection ( input out, input in, input output_enable, input pull_up_enable, inout net, inout pullnet );
    assign pullnet = pull_up_enable ? 1'b1 : 1'bz;
    assign net = output_enable ? out : pullnet;
endmodule

module test4;

wire testwire;

// prepare net checking
initial
    $monitor( "State change for wire %b and pull %b", testwire, pullnet );

wire pullnet;

reg port1_out=0;
reg port1_in=0;
reg port1_output_enable=0;
reg port1_pull_up_enable=0;

reg port2_out=0;
reg port2_in=0;
reg port2_output_enable=0;
reg port2_pull_up_enable=0;

connection conn1( port1_out, port1_in, port1_output_enable, port1_pull_up_enable, testwire, pullnet );
connection conn2( port2_out, port2_in, port2_output_enable, port2_pull_up_enable, testwire, pullnet );

// testing the net
initial begin
    #1 port1_out=1;
    #1 $display("Set enable, expect 1");
    #1 port1_output_enable=1;
    #1 $display("Remove out, expect z");
    #1 port1_output_enable=0;
    #1 $display("set pull up, expect 1");
    #1 port1_pull_up_enable=1;
    #1 $display("unset pull up, expect z");
    #1 port1_pull_up_enable=0;
    #1 $display("-------------");

    // ok, now going with pull up from port 2 and IO from port 1
    #1 $display("set pull up, expect 1");
    #1 port2_pull_up_enable=1;

    #1 $display("set out enable, expect 0");
    #1 port1_out=0;
    #1 port1_output_enable=1;

    #1 $display("################## END ##############");

Best Answer

There certainly is a pullup in Verilog

pullup(signal);

This will drive a "pull" strength 1 on the signal when no other drivers are on the net.

Another way is to declare the signal as a tri1 instead of a basic wire. This puts an implicit pullup on the net, but you need to be careful when making port connections of dissimilar net types. See tabe 23-1 in the 1800-2012 LRM.