L04 Introduction to Verilog II

Dr Ryan Robucci

Objective

  1. Introduction to Verilog
  2. Verilog basics
  3. Testbenches
  4. Coding Style
  5. Extended Introduction

References

Testbench

(same example from last lecture)

Structural:

//
  module mux_structural(d0,d1,sel,y);
  
    input d0,d1;
    input sel;
    output y;    //defaults to type wire, which is suitable for 
                 //  making connections between parts in netlists
    wire sel_n,w0,w1;
  
    not i0 (sel_n,sel);
    and i1 (w0,d0,sel_n);
    and i2 (w1,d1,sel);
    or  i3 (y,w0,w1);
  endmodule
keyword module begins a modulemodule identifierport list comma-separated list of port namesThe ports are then declared to be input,output, or inoutInstantiations of Verilog primitives and/or other modules concurrent, order does not matter`endmodule` keyword to conclude the module definition

A testbench:

module tb();              //a testbench is typically self-contained and thus has no ports
                          //Internal Signals
  reg d0,d1,sel;          //reg:  signals that will be assigned within the same
                          //       hierarchy level using procedural code
  wire y;                 //wire: signals for connections
                          //In SystemVerilog, use: logic d0,d1,sel,y;
                          //Instantiation of module, referred to as Device Under Test
  mux_structural dut(.*); //SystemVerilog default connection syntax
                          // for standard Verilog use explicit port mapping
                          //   mux_structural dut(.d0(d0),.d1(d1),.sel(sel),.y(y));

  integer count;          //working integer variable
  
  initial begin           //produral code is typically used to generate input stimulus
    count = 0;            //   unless a test-jig module 
    forever #1 count++;   //   is instantiated to interact with the DUT
  end

  assign {d0,d1,sel}=count;

  initial #0 $display("d0 d1 sel  y"); // zero-delay #0 ensures that printing
                                       // after circuit initialization is completed 
  initial    $monitor("%2b ",d0,"%2b ",d1,"%2b ",sel," ","%2b ",y);

  initial #7 $finish;   //terminates simulation
  
endmodule

The highlighted code lines with the DUT instantiation, the assign statement, the run-once initial lines, and the block of code in lines 14-17 may be provided in any order since the base level of code is concurrent.

The lines within begin end statements, lines 15-16, are sequntial code and only there does order matter.

The $monitor is a printing task supporting multiple inputs, as well as formatting strings followed by the arguments satisfying inputs to the formatting string. The monitor task automatically re-triggers and prints when any mutable input changes.

Results: (iverilog ‘-Wall’ ‘-g2012’ design.sv testbench.sv && unbuffer vvp a.out)

d0 d1 sel  y
 0  0  0   0 
 0  0  1   0 
 0  1  0   0 
 0  1  1   1 
 1  0  0   1 
 1  0  1   0 
 1  1  0   1 
 1  1  1   1 

Sensitivity List

Simple Testbench with a Clock

module mydevice_tb();
  reg clk, rst; // many signals will be reg since they are driven by procedural code in the testbench
  reg x1, x2; 
  wire y1, y2; // Outputs from the module under test are simply structural connections at this level so wires are used


  
  mydevice DUT(clk,rst, y1,y2, x1,x2); //An instance of the device under test

  
  initial clk = 0; // An initial statement or block can set initial values of signals

  always begin  //A always block with delays can be used to drive cyclic signals
    #50; //delay 
    clk = ~clk;
  end

  initial begin //Stops simulation at T=1000
    #1000 
    $finish;
  end

  // Initial value  and a change at T=10
  initial begin 
    rst = 1;
    #10; //delay 
    rst = 0;
  end

  /* Intialize signals immediately if not otherwise initialized, 
     then add delays and assignments We'll see other examples later, 
     but at first avoid changing signals input to clocked blocks at 
     the same time as the clock edge it is sensitive to
  */

  initial begin 
    y1=0;
    y2=0;

    #50; //delay 
    y1=1;
    #50; //delay
    y1=0;
    y2=1;
    #50; //delay 
    y1=1;
    y2=0;
  end

// This testbench includes no print or output statements, so it is assumed 
that a results waveform viewer (GUI) is used

endmodule //end testbench module

Basic Unsigned Literals

Some examples quoted from https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=8299595 IEEE Std 1800-2017

Logic Primatives

Continuous assignment

Gotcha: initial procedural assignment vs implicit assignment

because the following uses logic/reg (or if had used real), the following causes a one-time assignment, not a continuous assignment that changes x when a and b change

logic x = a | b; //intial procedural assignment

this could be a gotcha if replacing keyword wire with logic

Alias

I won’t ask you to know this, but it is convenient

➕ aliases

  • could be used to assign new names to signals/nets or parts of a bus in some parts of code

  • serves as a bidirectional association, in contrast to assign which is unidirectional

  • forms alias list of signals that share the same physical nets

    alias bus[7:0] = low_byte;
    
    alias low_byte = bus[7:0];
    
  • quoted from IEEE manual:

    • This example strips out the least and most significant bytes from a four byte bus
    module byte_rip (inout wire [31:0] W, inout wire [7:0] LSB, MSB);
      alias W[7:0] = LSB;
      alias W[31:24] = MSB;
    endmodule
    
  • forbidden to redefine alias, e.g. same net may not be registered to be an alias more than once in code

  • forbidden to somehow alias signal back to itself

Behavioral code for Procedural Assignment

Structural Data Types: wire and reg and the others

Verilog 2000: renamed reg to variable but no keyword change

Register data type is renamed to a variable, since the previous name of register created a lot of confusion for beginners, but keyword remained as reg.

Verilog 2000: reg initial assignment

One-time procedural assignmnet: it is possible to specify an initial value for the register/variable data type through a one-time assignment

reg a = 0; // v2k allows to init variables
reg b, c, d = 0; //just init d

Verilog 2000: signed reg type

reg data type can be signed since v2k

// We can assign with signed-type literals
reg signed [7:0] data = 8'shFF; // -1

SystemVerilog logic

(System Verilog is an extention to Verilog 2001)

Undeclared Nets

In Verilog 1995, default data type is net and its width is always 1 bit.
This can be dangerous for two
reasons…

     wire [7:0] a; wire [7:0] b; wire [7:0] d;
     wire [7:0] e;
     c=a+b; //one bit!!!!
     e=c+d;

In Verilog 2001 the width may be adjusted automatically if used in a port
In Verilog 2001, we can disable default data type by using a
special directive at the top of the code (old Xilinx tools):
`default net_type none

`default net_type none
...
wire a,b,c,d,y;
mylib_and2(w1,a,b);  //w1 is undeclared
mylib_and2(w2,c,d);  //w2 is undeclared
mylib_and2(y,w1,w2); //w1 and w2 are undeclared

Beginner Tips for Procedural Code for Hardware Synthesis

  1. For the purpose of coding, a reg, wire, or logic should be thought of as label for the the physical wire that is the output of a logic block, not the gate or register itself.
  2. Don’t try to describe hardware that you can’t first draw a representative circuit for…better yet, draw the circuit before coding.
  3. When modeling sequential logic, use non-blocking assignments q <= a+b; to assign the output of a register (here the input to the register is a+b)
  4. When modeling latches, use non-blocking assignments. (actually don’t code any latches for now. If you see any synthesis message for latches, eliminate them.)
  5. When modeling combinatorial logic with procedural code always block, use blocking assignments to assign the output. y=a+b;
  6. Separate combinatorial and sequential logic into separate always blocks (as much as reasonably possible) to avoid accidental registers and latches. Masters of the art do not need follow this rule
  7. When modeling both sequential and combinatorial logic within the same always block, use non-blocking assignments for registers and minimally use blocking statements for intermediate combinatorial logic. y=a+b;q<=y;q_prev<q;
  8. Do not mix blocking and non-blocking assignments to the same variable.
  9. Do not make assignments to the same variable from more than one always block.

Realizing Equivalent Functional Behavior in Pre-Synthesis Simulation, Pre-Synthesis Simulation, and Synthesized Hardware

Data Pipeline and Coding for Consistent Sim and Synth RTL

What we want:

🥅 Goal: Matching Pre-Synth Sim and Hardware
• want same behavior for sim and synth/hardware, prefer no source code differences
• where source differences for simulation and synthesis are necessary, the difference should be minimized

🌪️ Avoid Distinct Source Code for Simulation vs Synthesis
• Want to avoid creating different models(code) for simulation and synthesis that must be maintained and checked for equivalence with every update

Suggested Procedural RTL Coding Practices

Reference/Related Guidelines Found : http://www.sunburst-design.com/papers/

Guidelines

Course Guideline/Requirement: Use non-blocking assignment for EVERY output of a register

Poor, uses blocking Assignment

module dffb (q, d, clk, rst);
  output q;
  input d, clk, rst;
  logic q;
  always @(posedge clk)
    if (rst) q = 1'b0;
    else q = d;
endmodule

Good, uses Non-blocking Assignment

module dffx (q, d, clk, rst);
  output q;
  input d, clk, rst;
  logic q;
  always @(posedge clk)
    if (rst) q <= 1'b0; //coding all sequential always blocks, even simple single-block modules, using nonblocking assignments.
    else q <= d;
endmodule

In-class drawing

Combinatorial and Registered-Output Logic

Course Guideline/Requirement: Use blocking assignment for any output of combinational logic, regardless of the trigger type

Combinatorial:

logic y;
always @(a,b)
   y = a & b;

In this isolated block you might have have alternatively tried and used
y <= a & b;
but we will follow a convention explained later whereby we use blocking for all combinatorial logic

Sequential (registered-output combinatorial logic):

logic q;
always @(posedge clk)
   q <= a & b;

Examples

Cycle-Accurate Models

VHDL

  • In VHDL, Variables update immediately upon assignment and do not facilitate communication between processes (proceduarl blocks). Signals are used to communicate between processes and are updated at the end of a simulation cycle.

Verilog

  • In Verilog, we can adopt a coding conventions that mimic this by using named blocks

Guideline: Avoid declaring what could be block-local variables needlessly outside the block

Enforced Guileline on Using Block Scope

This guideline is enforced in this Course: Avoid declaring block-local variables needlessly outside the block. Name blocks as needed to allow new scope for variables.

Trimmable-Logic Style

logic y; //reg y;
always @(posedge clk, negedge clr_n) 
  begin: blockY                 
    logic _y,partial; //reg                              
    _y=1'bx;partial=1'bx;                       
    if (!clr_n) y <= 1'b0;                      
    else begin                                  
      partial = a & b;                          
      _y = ~a | partial;                        
      y <= _y;                                  
    end                                         
  end
Depends on a,b, current value of y, clr_nOutput: block updates value of ySide effect: updates to _y and partial

*** Running vivado
    with args -log top.vds -m64 -product Vivado -mode batch -messageDb vivado.pb -notrace -source top.tcl


****** Vivado v2023.2 (64-bit)
  **** SW Build 4029153 on Fri Oct 13 20:13:54 MDT 2023
  **** IP Build 4028589 on Sat Oct 14 00:45:43 MDT 2023
  **** SharedData Build 4025554 on Tue Oct 10 17:18:54 MDT 2023
    ** Copyright 1986-2022 Xilinx, Inc. All Rights Reserved.
    ** Copyright 2022-2023 Advanced Micro Devices, Inc. All Rights Reserved.

source top.tcl -notrace
create_project: Time (s): cpu = 00:00:04 ; elapsed = 00:00:05 . Memory (MB): peak = 1339.598 ; gain = 36.840 ; free physical = 95294 ; free virtual = 103498
Command: read_checkpoint -auto_incremental -incremental /home/robucci/verilog/code_tests/code_tests.srcs/utils_1/imports/synth_1/top.dcp
INFO: [Vivado 12-5825] Read reference checkpoint from /home/robucci/verilog/code_tests/code_tests.srcs/utils_1/imports/synth_1/top.dcp for incremental synthesis
INFO: [Vivado 12-7989] Please ensure there are no constraint changes
Command: synth_design -top top -part xa7a35tcpg236-2I
Starting synth_design
Attempting to get a license for feature 'Synthesis' and/or device 'xa7a35t'
INFO: [Common 17-349] Got license for feature 'Synthesis' and/or device 'xa7a35t'
INFO: [Designutils 20-5440] No compile time benefit to using incremental synthesis; A full resynthesis will be run
INFO: [Designutils 20-4379] Flow is switching to default flow due to incremental criteria not met. If you would like to alter this behaviour and have the flow terminate instead, please set the following parameter config_implementation {autoIncr.Synth.RejectBehavior Terminate}
INFO: [Synth 8-7079] Multithreading enabled for synth_design using a maximum of 4 processes.
INFO: [Synth 8-7078] Launching helper process for spawning children vivado processes
INFO: [Synth 8-7075] Helper process launched with PID 3650419
---------------------------------------------------------------------------------
Starting Synthesize : Time (s): cpu = 00:00:03 ; elapsed = 00:00:03 . Memory (MB): peak = 1764.039 ; gain = 409.598 ; free physical = 94590 ; free virtual = 102794
---------------------------------------------------------------------------------
INFO: [Synth 8-6157] synthesizing module 'top' [/home/robucci/verilog/code_tests/code_tests.srcs/sources_1/new/top.sv:25]
INFO: [Synth 8-6155] done synthesizing module 'top' (0#1) [/home/robucci/verilog/code_tests/code_tests.srcs/sources_1/new/top.sv:25]
WARNING: [Synth 8-6014] Unused sequential element blockY._y_reg was removed.  [/home/robucci/verilog/code_tests/code_tests.srcs/sources_1/new/top.sv:43]
WARNING: [Synth 8-6014] Unused sequential element blockY.partial_reg was removed.  [/home/robucci/verilog/code_tests/code_tests.srcs/sources_1/new/top.sv:43]
---------------------------------------------------------------------------------
Finished Synthesize : Time (s): cpu = 00:00:03 ; elapsed = 00:00:04 . Memory (MB): peak = 1839.008 ; gain = 484.566 ; free physical = 94493 ; free virtual = 102698
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
Finished Constraint Validation : Time (s): cpu = 00:00:04 ; elapsed = 00:00:04 . Memory (MB): peak = 1856.820 ; gain = 502.379 ; free physical = 94492 ; free virtual = 102696
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
Start Loading Part and Timing Information
---------------------------------------------------------------------------------
Loading part: xa7a35tcpg236-2I
---------------------------------------------------------------------------------
Finished Loading Part and Timing Information : Time (s): cpu = 00:00:04 ; elapsed = 00:00:04 . Memory (MB): peak = 1864.824 ; gain = 510.383 ; free physical = 94492 ; free virtual = 102696
---------------------------------------------------------------------------------
INFO: [Device 21-403] Loading part xa7a35tcpg236-2I
---------------------------------------------------------------------------------
Finished RTL Optimization Phase 2 : Time (s): cpu = 00:00:04 ; elapsed = 00:00:04 . Memory (MB): peak = 1873.730 ; gain = 519.289 ; free physical = 94485 ; free virtual = 102691
---------------------------------------------------------------------------------
No constraint files found.
---------------------------------------------------------------------------------
Start RTL Component Statistics 
---------------------------------------------------------------------------------
Detailed RTL Component Info : 
+---Registers : 
	                1 Bit    Registers := 1     
---------------------------------------------------------------------------------
Finished RTL Component Statistics 
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
Start Part Resource Summary
---------------------------------------------------------------------------------
Part Resources:
DSPs: 90 (col length:60)
BRAMs: 100 (col length: RAMB18 60 RAMB36 30)
---------------------------------------------------------------------------------
Finished Part Resource Summary
---------------------------------------------------------------------------------
No constraint files found.
---------------------------------------------------------------------------------
Start Cross Boundary and Area Optimization
---------------------------------------------------------------------------------
WARNING: [Synth 8-7080] Parallel synthesis criteria is not met
---------------------------------------------------------------------------------
Finished Cross Boundary and Area Optimization : Time (s): cpu = 00:00:07 ; elapsed = 00:00:10 . Memory (MB): peak = 1978.262 ; gain = 623.820 ; free physical = 94376 ; free virtual = 102584
---------------------------------------------------------------------------------
No constraint files found.
---------------------------------------------------------------------------------
Start Timing Optimization
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
Finished Timing Optimization : Time (s): cpu = 00:00:07 ; elapsed = 00:00:10 . Memory (MB): peak = 1978.262 ; gain = 623.820 ; free physical = 94375 ; free virtual = 102583
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
Start Technology Mapping
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
Finished Technology Mapping : Time (s): cpu = 00:00:07 ; elapsed = 00:00:10 . Memory (MB): peak = 1978.262 ; gain = 623.820 ; free physical = 94375 ; free virtual = 102583
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
Start IO Insertion
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
Start Flattening Before IO Insertion
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
Finished Flattening Before IO Insertion
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
Start Final Netlist Cleanup
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
Finished Final Netlist Cleanup
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
Finished IO Insertion : Time (s): cpu = 00:00:10 ; elapsed = 00:00:13 . Memory (MB): peak = 1978.262 ; gain = 623.820 ; free physical = 94373 ; free virtual = 102582
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
Start Renaming Generated Instances
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
Finished Renaming Generated Instances : Time (s): cpu = 00:00:10 ; elapsed = 00:00:13 . Memory (MB): peak = 1978.262 ; gain = 623.820 ; free physical = 94373 ; free virtual = 102582
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
Start Rebuilding User Hierarchy
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
Finished Rebuilding User Hierarchy : Time (s): cpu = 00:00:10 ; elapsed = 00:00:13 . Memory (MB): peak = 1978.262 ; gain = 623.820 ; free physical = 94373 ; free virtual = 102582
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
Start Renaming Generated Ports
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
Finished Renaming Generated Ports : Time (s): cpu = 00:00:10 ; elapsed = 00:00:13 . Memory (MB): peak = 1978.262 ; gain = 623.820 ; free physical = 94373 ; free virtual = 102582
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
Start Handling Custom Attributes
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
Finished Handling Custom Attributes : Time (s): cpu = 00:00:10 ; elapsed = 00:00:13 . Memory (MB): peak = 1978.262 ; gain = 623.820 ; free physical = 94373 ; free virtual = 102582
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
Start Renaming Generated Nets
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
Finished Renaming Generated Nets : Time (s): cpu = 00:00:10 ; elapsed = 00:00:13 . Memory (MB): peak = 1978.262 ; gain = 623.820 ; free physical = 94373 ; free virtual = 102582
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
Start Writing Synthesis Report
---------------------------------------------------------------------------------

Report BlackBoxes: 
+-+--------------+----------+
| |BlackBox name |Instances |
+-+--------------+----------+
+-+--------------+----------+

Report Cell Usage: 
+------+-----+------+
|      |Cell |Count |
+------+-----+------+
|1     |BUFG |     1|
|2     |LUT1 |     1|
|3     |LUT2 |     1|
|4     |FDCE |     1|
|5     |IBUF |     4|
|6     |OBUF |     1|
+------+-----+------+

Report Instance Areas: 
+------+---------+-------+------+
|      |Instance |Module |Cells |
+------+---------+-------+------+
|1     |top      |       |     9|
+------+---------+-------+------+

---------------------------------------------------------------------------------
Finished Writing Synthesis Report : Time (s): cpu = 00:00:10 ; elapsed = 00:00:13 . Memory (MB): peak = 1978.262 ; gain = 623.820 ; free physical = 94373 ; free virtual = 102582
---------------------------------------------------------------------------------
Synthesis finished with 0 errors, 0 critical warnings and 3 warnings.
Synthesis Optimization Runtime : Time (s): cpu = 00:00:10 ; elapsed = 00:00:13 . Memory (MB): peak = 1978.262 ; gain = 623.820 ; free physical = 94373 ; free virtual = 102582
Synthesis Optimization Complete : Time (s): cpu = 00:00:10 ; elapsed = 00:00:13 . Memory (MB): peak = 1978.270 ; gain = 623.820 ; free physical = 94373 ; free virtual = 102582
INFO: [Project 1-571] Translating synthesized netlist
Netlist sorting complete. Time (s): cpu = 00:00:00 ; elapsed = 00:00:00 . Memory (MB): peak = 1994.129 ; gain = 0.000 ; free physical = 94649 ; free virtual = 102857
INFO: [Project 1-570] Preparing netlist for logic optimization
INFO: [Opt 31-138] Pushed 0 inverter(s) to 0 load pin(s).
Netlist sorting complete. Time (s): cpu = 00:00:00 ; elapsed = 00:00:00 . Memory (MB): peak = 2072.816 ; gain = 0.000 ; free physical = 94573 ; free virtual = 102782
INFO: [Project 1-111] Unisim Transformation Summary:
No Unisim elements were transformed.

Synth Design complete | Checksum: 1e085e38
INFO: [Common 17-83] Releasing license: Synthesis
16 Infos, 3 Warnings, 0 Critical Warnings and 0 Errors encountered.
synth_design completed successfully
synth_design: Time (s): cpu = 00:00:13 ; elapsed = 00:00:14 . Memory (MB): peak = 2072.852 ; gain = 727.316 ; free physical = 94573 ; free virtual = 102782
INFO: [Common 17-2834] synth_design peak Physical Memory [PSS] (MB): overall = 1616.545; main = 1389.832; forked = 384.954
INFO: [Common 17-2834] synth_design peak Virtual Memory [VSS] (MB): overall = 2968.664; main = 2072.820; forked = 990.398
Write ShapeDB Complete: Time (s): cpu = 00:00:00 ; elapsed = 00:00:00 . Memory (MB): peak = 2096.828 ; gain = 0.000 ; free physical = 94573 ; free virtual = 102782
INFO: [Common 17-1381] The checkpoint '/home/robucci/verilog/code_tests/code_tests.runs/synth_1/top.dcp' has been generated.
INFO: [runtcl-4] Executing : report_utilization -file top_utilization_synth.rpt -pb top_utilization_synth.pb
INFO: [Common 17-206] Exiting Vivado at Wed Feb 14 10:34:28 2024...

Logic Inferred:

Implementation:

Danger

Do not attempt to use intermediate combinational logic generated within an edge-triggered block outside the block.
It will generate unintential logic, or reduce your grade.
If you need the combinational version of the signal elsewhere, code the generating logic in a separate combinational block

Combinatorial and Registered-Output Logic

Combinatorial

logic y;
always_comb //always @(a,b)
   y = a & b;
  • ✅ uses blocking assignment operator
  • ✘ In this isolated block you might have also improperly used y <= a & b; but we will follow a convention explained later whereby we use blocking for all combinatorial logic

Registered-output combinatorial logic

logic q;
always_ff @(posedge clk)
   q <= a & b;
  • ✅ uses non-blocking assignment operator

Three behavioral code organizations for sequential and combinatorial logic

🛰️ Combinational and Sequential

  1. Separate always blocks for combinatorial and sequential logic
    • Encourages conscious distinct treatment and recognition of combinatorial and sequential logic. Often this style is recommended for beginners.
  2. Sequential and combinatorial logic in same block with combinatorial logic only embedded in expressions with sequential assignments q<=a&b;
  3. Sequential and combinatorial logic in same block with both combinatorial and sequential assignments _q=a&b; q<=_q;

AND->OR->Register Study Samples

Separated Combinatorial and Sequential Logic:

logic y,y_prereg,partial;
always @(a,b,c) begin
   partial = a & b;
   y_prereg = c | partial;
end

always @(posedge clk) begin
   y <= y_prereg;
end

Mentally, associate the variable name (e.g. y) with the output of the register, not the register itself.

Implicit Mix of Combinatorial and Sequential Logic:

logic y;
always @(posedge clk) begin: blkid
   logic partial;
   partial = a & b;
   y <= c | partial;
end

Explicit Mix of Combinatorial and Sequential Logic:

logic y;
always @(posedge clk) begin: blkid
   logic y_prereg,partial;
   partial = a & b;
   y_prereg = a | partial;
   y =<= y_prereg;
end

Separated Combinatorial and Sequential Logic:

logic y,y_prereg;
always @(a,b,c) begin: blk1
   logic y,partial;
   partial = a & b;
   y_prereg = a | partial;
end

always @(posedge clk, negedge clr_n) begin:blk2 // Asynchronous control signals must appear in the sensitivity list
  if (!clr_n) y <= 1'b0;
  else y <= y_prereg;

end

Tip

Mentally learn to associate the variable name to the output of the register, not the register itself. This rule later helps distinguish the input to the register from the output. Unfortunally the generated diagram here DOES NOT follow this convention.

Tool Preferred Language Templates

Typically Templates can be found in a tool manual or through the
development GUI (Xlinx ISE shown, out-of-date, but look for simular references in modern tools/manuals)

You need to follow template statles that the tool recognizes. Check the documentation of a synthesizer for additional coding style requirements.

Review Trimmable Style

If you follow our coding guidelines, you must use blocking assignment for outputs of combinatorial logic even if within edge-triggered procedural blocks.
For any signal that is both

you

Review Use of Named Blocks and Local Variables

placing a colon and a name after the keyword begin creates a named block with a named variable scope

Local variables are preferred to disallow the mistake of using the combinatorial outputs from an edge-triggered block by keeping them declaring them locally.

(This is part of a Verilog coding style convention to softly enfore what VHDL handles more explicitly. ) This along with guidelines that will be refined in the slideset “Suggested Coding and Design Practices” allow use to represent both sequntial and combinatorial hardware in the same procedural block. The alternative is to always separate combinatorial and seqential hardware, which I don’t find practical and is limiting compared to standard coding styles in VHDL.

Use of named block and local variables to explicitly constrain use of internal variables:

logic y;
always @(posedge clk, negedge clr_n)
begin: blockY                 
 logic y_prereg,partial;              
  y_prereg=1'bx;partial=1'bx;       
  if (!clr_n) y <= 1'b0;            
  else begin                        
    partial = a & b;                
    y_prereg = ~a | partial;        
    y <= y_prereg;                  
  end                               
end

Appendix

In this code, I assigned combinatorial variables x (don’t care) at the top of the code to see if Xilinx ISE not complain, but it still does. Following it are two versions along with the Xilinx ISE synthesis report.

reg y;
always @(posedge clk, negedge clr_n)
begin: blockY
  reg y_prereg,partial;
  y_prereg=1'bx;partial=1'bx;
     if (!clr_n) y <= 1'b0;
  else begin
    partial = a & b;
    y_prereg = ~a | partial;
    y <= y_prereg;
  end
end

Trimmable Without Combinatorial Assignment to X:

module trimmable(output reg y, input a, input b, input clk,input clr_n);
always @(posedge clk, negedge clr_n)
begin: blockY
  reg y_prereg,partial;
  if (!clr_n) y <= 1'b0;
  else begin
    partial = a & b;
    y_prereg = ~a | partial;
    y <= y_prereg;
  end
end
endmodule

Started : "Synthesize - XST".
Running xst...
Command Line: xst -intstyle ise -ifn "/home/robucci/Nextcloud/covail/Courses/CMPE415/XilinxProjects/test_synth/trimmable.xst" -ofn "/home/robucci/Nextcloud/covail/Courses/CMPE415/XilinxProjects/test_synth/trimmable.syr"
Reading design: trimmable.prj

=========================================================================
*                          HDL Compilation                              *
=========================================================================
Compiling verilog file "trimmable.v" in library work
Module <trimmable> compiled
No errors in compilation
Analysis of file <"trimmable.prj"> succeeded.
 

=========================================================================
*                     Design Hierarchy Analysis                         *
=========================================================================
Analyzing hierarchy for module <trimmable> in library <work>.


=========================================================================
*                            HDL Analysis                               *
=========================================================================
Analyzing top module <trimmable>.
Module <trimmable> is correct for synthesis.
 

=========================================================================
*                           HDL Synthesis                               *
=========================================================================

Performing bidirectional port resolution...

Synthesizing Unit <trimmable>.
    Related source file is "trimmable.v".
WARNING:Xst:646 - Signal <blockY/y_prereg> is assigned but never used. This unconnected signal will be trimmed during the optimization process.
WARNING:Xst:646 - Signal <blockY/partial> is assigned but never used. This unconnected signal will be trimmed during the optimization process.
    Found 1-bit register for signal <y>.
    Summary:
inferred   1 D-type flip-flop(s).
Unit <trimmable> synthesized.


=========================================================================
HDL Synthesis Report

Macro Statistics
# Registers                                            : 1
 1-bit register                                        : 1

=========================================================================

Trimmable With Combinatorial Assignment to 'x:

module trimmable(output reg y, input a, input b, input clk,input clr_n);
always @(posedge clk, negedge clr_n)
begin: blockY
  reg y_prereg,partial;
  y_prereg=1'bx;
  partial=1'bx;
  if (!clr_n) y <= 1'b0;
  else begin
    partial = a & b;
    y_prereg = ~a | partial;
    y <= y_prereg;
  end
end
endmodule
Started : "Synthesize - XST".
Running xst...
Command Line: xst -intstyle ise -ifn "/home/robucci/Nextcloud/covail/Courses/CMPE415/XilinxProjects/test_synth/trimmable.xst" -ofn "/home/robucci/Nextcloud/covail/Courses/CMPE415/XilinxProjects/test_synth/trimmable.syr"
Reading design: trimmable.prj

=========================================================================
*                          HDL Compilation                              *
=========================================================================
Compiling verilog file "trimmable.v" in library work
Module <trimmable> compiled
No errors in compilation
Analysis of file <"trimmable.prj"> succeeded.
 

=========================================================================
*                     Design Hierarchy Analysis                         *
=========================================================================
Analyzing hierarchy for module <trimmable> in library <work>.


=========================================================================
*                            HDL Analysis                               *
=========================================================================
Analyzing top module <trimmable>.
Module <trimmable> is correct for synthesis.
 

=========================================================================
*                           HDL Synthesis                               *
=========================================================================

Performing bidirectional port resolution...

Synthesizing Unit <trimmable>.
    Related source file is "trimmable.v".
WARNING:Xst:646 - Signal <blockY/y_prereg> is assigned but never used. This unconnected signal will be trimmed during the optimization process.
WARNING:Xst:646 - Signal <blockY/partial> is assigned but never used. This unconnected signal will be trimmed during the optimization process.
    Found 1-bit register for signal <y>.
    Summary:
	inferred   1 D-type flip-flop(s).
Unit <trimmable> synthesized.


=========================================================================
HDL Synthesis Report

Macro Statistics
# Registers                                            : 1
 1-bit register                                        : 1

=========================================================================

L04 Introduction to Verilog II

Appendix

≡