Continuous assignment vs always_comb

Can someone please explain the difference between continuous assignment using assign statement and always_comb.
I am only using logic for my variables (No! reg or wire)
what will be the difference in hardware if I am writing the same logic using assign and always_comb?
Please show me some examples where always_comb can be used and assign cannot or vice-versa

In reply to svishnu:

Can someone please explain the difference between continuous assignment using assign statement and always_comb.
I am only using logic for my variables (No! reg or wire)
what will be the difference in hardware if I am writing the same logic using assign and always_comb?
Please show me some examples where always_comb can be used and assign cannot or vice-versa

See model Edit code - EDA Playground

  • You cannot use the always_comb on wire
    wire q;
    always_comb q=!a; // ERROR
    // Net type cannot be used on the left side of this assignment.
    // The offending expression is : q
    // Source info: q = (!a);
  • You canot do multiple assign on a logic, you can on a signle object
    logic e;
    assign e= 1’b0;
    assign e= 1’b1; // ERROR
    //Variable “e” is driven by multiple structural drivers.
    //This variable is declared at
    // The first driver is at “testbench.sv”, 6: assign e = 1’b1;
    // The second driver is at “testbench.sv”, 5: assign e = 1’b0;
  • As a recommendation, use the assign for objects of type wire, and the always_comb for just combinational logic that may eventually be used as control logic or end up as the input to a FF. Thus, you’ll be using the right syntax for the intended implication of the hardware you woul like to see.
  • Synthesis tools will be forgiving, and will work OK if you use the assign once on a signal of type logic; however, you’ll be missing the intend of the language.

module m; 
  logic a, b, c, d, e; 
  wire w, q; 
  assign w=a && b; 
  assign e= 1'b0; 
  // assign e= 1'b1; // ERROR
  //Variable "e" is driven by multiple structural drivers.
  //This variable is declared at
  // The first driver is at "testbench.sv", 6: assign e = 1'b1;
  // The second driver is at "testbench.sv", 5: assign e = 1'b0;
  always_comb a= b && c; 
  //always_comb if(c) w=!d; // ERROR 
  // The offending expression is : w
  // Source info: w = (!d);
  //Net type cannot be used on the left side of this assignment.
  // always_comb if(c) a=!b; // ERROR
  /* Variable "a" is driven by an invalid combination of procedural drivers. 
  Variables written on left-hand of "always_comb" cannot be written to by any 
  other processes, including other "always_comb" processes.
  This variable is declared at "testbench.sv", 2: logic a;
  The first driver is at "testbench.sv", 16: always_comb  if (c) begin
  a = (!b);
   ...
  The second driver is at "testbench.sv", 11: always_comb  a = (b && c);
  assign w= 1'bZ; */ 
  //always_comb q=!a; // ERROR 
  // Net type cannot be used on the left side of this assignment.
  // The offending expression is : q
  // Source info: q = (!a);
endmodule

Ben Cohen
http://www.systemverilog.us/ ben@systemverilog.us