Driving with and without clocking blocks

Suppose if we consider the following pseudocode,


module test_tb
(
input logic clk,rst,
input logic[3:0]  A,B,
output logic[3:0] C
);

clocking cb @(posedge clk);
input #1 A,B;
output #1 C;
endclocking

always (@ negedge rst)
begin
C <= 0;
end

task my_task();
...
cb.C <= '1;
...//some code
endtask

endmodule

My question is, since C is of logic type it is allowed to have only one driver, but clearly I see that above code works although C is driven from the always block and also from the task. Why is that so?
Thanks for the help!

In reply to nipradee:

Your module declaration is implicitly the same as

module test_tb
(
input wire logic clk,rst,
input wire logic[3:0]  A,B,
output var logic[3:0] C
);

C is a variable, and clocking block output drives are considered procedural assignments.
You are allowed to have multiple procedural assignments to a variable.

In reply to dave_59:

HI Dave
Thanks for the reply.

when you mentioned “C is a variable, and clocking block output drives are considered procedural assignments”, does that mean output drives in CBs are always procedural and also what about the input drives is that continuous or procedural (or both are allowed).

I also read that ‘reg’ is what they usually call variable (because unlike wires it can remember/store the last written value just like variables in C++ ) and I know that reg can have only one driver, so here since var is a variable as well then how can that have multiple drivers like wires?
Thanks for the help!

In reply to nipradee:

According to section 14.16 Synchronous drives in the IEEE 1800-2017 LRM, output drives to nets act as continuous assignments, and output drives to variables act as procedural assignments.

“reg” is a datatype that is usually associated with a variable. See http://go.mentor.com/wire-vs-reg .

In reply to dave_59:

Hi Dave,
In the linked code ‘qb’ is a reg but we are continuously assigning the same.
could you please let me know why this code compiles without any issues?

code is here: Your text to link here…

Thanks for the help!

In reply to nipradee:
Lot of info
https://verificationacademy.com/forums/systemverilog/clocking-block-interface

In reply to ben@SystemVerilog.us:

Thanks Ben, this was certainly helpful.
For the moment lets consider the following code:

  1. qb is a reg which is assigned continuously. (I read this is not allowed)
  2. q is a reg procedurally assigned from 2 different always blocks. (I read that the same reg cannot be assigned from 2 different always blocks)

yet this compiles with no issue if we try on EDA playground. Could you help me understand why?


// Design
// D flip-flop
module dff (clk, reset,
  d, q);
  input      clk;
  input      reset;
  input      d;
  output     q;
  reg        qb;
  reg        q;

  assign qb = ~q;

  always @(posedge clk)
  begin
      // Assign D to Q on positive clock edge
      q <= d;
  end
  
  always @(posedge reset)
  begin
    if (reset) begin
      // Asynchronous reset when reset goes high
      q <= 1'b0;
    end
  end
endmodule

// Testbench
module test;

  reg clk;
  reg reset;
  reg d;
  wire q;
  wire qb;
  
  // Instantiate design under test
  dff DFF(.clk(clk), .reset(reset),
          .d(d), .q(q) );
          
  initial begin
    // Dump waves
    $dumpfile("dump.vcd");
    $dumpvars(1);
    
    $display("Reset flop.");
    clk = 0;
    reset = 1;
    d = 1'bx;
    display;
    
    $display("Release reset.");
    d = 1;
    reset = 0;
    display;

    $display("Toggle clk.");
    clk = 1;
    display;
  end
  
  task display;
    #1 $display("d:%0h, q:%0h,",
      d, q);
  endtask

endmodule

Same code can be run on EDA playground at this link : Your text to link here…

Thanks for the help!

In reply to curious_learner:
Comments

  1. Verilog is a language that is a bit too loose in structures and rules, and it allows you to easily get into trouble.
  2. SystemVerilog 1800’2017 provided new constructs to avoid many of those loose rules to introduce errors, particularly at the RTL level.
  3. DEFINITELY read 1800’2017 section 9.2 Structured procedures
  4. Of particular interest 9.2.2.2.2 always_comb compared to always @*
    Variables on the left-hand side of assignments within an always_comb procedure, including
    variables from the contents of a called function, shall not be written to by any other processes, whereas always @* permits multiple processes to write to the same variable.
    Thus,

always @* a = d;
always @* a = !d; // THAT IS LEGAL
always_comb w=d;  // OK, but error if another assignment
always @* w = !d; // illegal
//variable 'w' driven in a combinational block, may not be driven by any other process.

  1. 9.2.2.4 Sequential logic always_ff procedure
    The always_ff procedure can be used to model synthesizable sequential logic behavior. For example:
always_ff @(posedge clock iff reset == 0 or posedge reset) begin
r1 <= reset ? 0 : r2 + 1;
...
end

The always_ff procedure imposes the restriction that it contains one and only one event control and no blocking timing controls. Variables on the left-hand side of assignments within an always_ff procedure, including variables from the contents of a called function, shall not be written to by any other process.
Thus,

always @(posedge clk or posedge reset) begin
//Allowed !!!
if (reset) q <= 1'b0; // See below error message if always _ff is used
else  q <= d;
end
// FF Better
always_ff @(posedge clk or posedge reset) begin
// Variable 'q' driven in an always_ff block, may not be driven by any other process
if (reset) q <= 1'b0;
else  q <= d;
end
  1. Use type “logic” instead of “reg”

Recommendations: Use SystemVerilog coding styles that enforces more structured coding rules and guidelines to avoid “weird” stuff in the execution of the code. In that respect, SystemVerilog got to a closer approachment to VHDL, which is more structured and has stricter rules than Verilog.
Test code that you play with
Edit code - EDA Playground

Ben Cohen
http://www.systemverilog.us/ ben@systemverilog.us
For training, consulting, services: contact http://cvcblr.com/home.html
** SVA Handbook 4th Edition, 2016 ISBN 978-1518681448

  1. SVA Package: Dynamic and range delays and repeats SVA: Package for dynamic and range delays and repeats | Verification Academy
  2. Free books: Component Design by Example FREE BOOK: Component Design by Example … A Step-by-Step Process Using VHDL with UART as Vehicle | Verification Academy
    Real Chip Design and Verification Using Verilog and VHDL($3) Amazon.com
  3. Papers:

In reply to ben@SystemVerilog.us:

Thanks Ben for this well articulated answer :^)