UVMag
UVMag

Reputation: 133

When shall I use the keyword "assign" in SystemVerilog?

For example, what will happen here if I do not use the assign keyword:

module dff(q,d,clear,preset,clock);
   output q;
   input d, clear, preset, clock;
   logic q;
   always @(clear or preset)
     if (!clear)
       assign q = 0;
     else if (!preset)
       assign q = 1;
     else
     deassign q;
  always @(posedge clock)
     q = d;
endmodule

Upvotes: 1

Views: 7330

Answers (2)

dave_59
dave_59

Reputation: 42616

If you don't use the assign keywords in the example you posted, then q gets written on the next posedge clock with the value of d. The state of clear or preset has no lasting affect on the value of q. Normal procedural assignments are overwritten by procedural continuous assigments.

The synthesis style of dividing the synchronous and asynchronous behaviors of sequential logic into separate always blocks turned out to be unpopular with synthesis tools, and gradually lost all support. It conflicts with the style that requests that variables be written to from only a single always block. Also, people get confused between continuous assignments and procedural continuous assignments because they both use the assign keyword.

Upvotes: 2

toolic
toolic

Reputation: 61937

The general guidelines for synthesizable Verilog code are that you should only use the assign keyword for combinational logic, not for sequential logic like a DFF.

Your code example is from the IEEE Std 1800-2017, section 10.6.1 The assign and deassign procedural statements. That coding style, while legal, is not recommended for synthesizing a DFF. In fact, just below the code is this statement:

NOTE — The procedural assign and deassign constructs are under consideration for deprecation.

Essentially, you should not use assign inside the always block.

A more traditional code for a synthesizable DFF (with only an asynchronous reset) is:

module dff (
   output logic q,
   input d, resetn, clock
);
    always @(posedge clock or negedge resetn) begin
        if (!resetn) begin
            q <= 0;
        end else begin
            q <= d;
        end
    end
endmodule

There is no need for an assign, and it uses nonblocking (<=) assignments.

Upvotes: 2

Related Questions