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!
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.
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!
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.
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?
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.
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
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