Dr Ryan Robucci
Objective
(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
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
always @ (a or b or c) begin...end
-> always @ (a, b,c) begin...end
always @ (*) begin...end
always_comb begin ...end
always_ff @ (posedge clk, posedge reset) begin ...end
always_ff @ (posedge clk, posedge reset) begin:blockName ...end
always_comb begin:blockName ...end
always begin:blockName ...end
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
Some examples quoted from https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=8299595 IEEE Std 1800-2017
Unsized, unsigned homogenious literals. Assignment using any of the following sets all bits to specified value:
'0
, '1
, 'X
, 'x
, 'Z
, 'z
Plain unsized, unsided decimal is provided without any extra decaration:
456
In general
Start with optional bit size specifier
Provide tick '
specify literal reprensentation type with b
,h
,d
or alternatives B
,H
,D
provide the value using the syntax of the literal
_
for reablity may be freed used except for the first characterleft padding rules are non-trivial and beginners are recommended to avoid, but simple use of unsized literals is reasonable '0
,'1
,'z
,'x
Examples:
4'b1001 // 4-bit binary number
8'b1001_1011 // 8-bit binary number
'h2AF // 12-bit hex
5 'D 3 // 5-bit decimal number
12'hx // 12-bit unknown number
'x // all x
?
is an alternative for z
in literals. ?
and z
have a special meaning in certain contexts, which will be explained later.
Signed Literals will be covered later.
wire
(or alernatively logic
in the case of SystemVerilog)not inv1 (out,in)
nand
,or
,and
,or
,xor
,xnor
, though other primatives exist...
wire a,b,c,d,e,x,y,z;
...
or orX (x,a,b);
or orY (y,c,d);
and i0 (z,x,y,e);
two styles: implicit continous assignment and explicit continous assignment
Continous assignment may be decribed implicity with wire/real with the wire declartion or provided explicilty later along with an assign
keyword
Example Using Wire
...
wire a,b,c,d,e;
...
wire x = a | b; //implicit continous assignment
wire z;
...
assign z = x & (c&d) & e ; //explicit
in SystemVerilog using logic/reg:
...
logic a,b,c,d,e;
...
logic x;
assign x = a | b; //implicit continous assignment
logic z;
...
assign z = x & (c&d) & e ; //explicit
real
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
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:
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
posedge
or negedge
are specified, then the type of change (edge type) that triggers evaluation is restrictedbegin
and end
may be used to encapsulate a description of an algorithm using a block of âsequential codeââŚ.the code is just a description of a desired behavior and not necessarily the implementation itself â the entire description is evaluated in one instant in time (takes 0 time to complete)begin
and end
like {
and }
in Clogic
and bit
are common)reg
type hold their values until another value is put on themalways @ (posedge clk) begin: BLOCKNAME
⌠⌠âŚ
end
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
.
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
reg data type can be signed since v2k
// We can assign with signed-type literals
reg signed [7:0] data = 8'shFF; // -1
logic
(System Verilog is an extention to Verilog 2001)
reg
supports continuous assignment through assign
keyword
reg
support either a single continous assignment through assign
keyword ORassign
keyword forbids assignment in procedural codelogic
for declaration is an alternative for reg
logic
becomes functional replacement for nets (e.g. wire
) and variables (e.g. reg
)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
SytemVerilog Use:
`default_nettype none
Vivado Example:
module top(
input a,
output u
);
assign U = a;
endmodule
Implementation Schematic:
What happened?
Starting Synthesize : Time (s): cpu = 00:00:03 ; elapsed = 00:00:04 . Memory (MB): peak = 1760.805 ; gain = 414.652 ; free physical = 96845 ; free virtual = 104717 --------------------------------------------------------------------------------- INFO: [Synth 8-11241] undeclared symbol 'U', assumed default net type 'wire' [/home/robucci/verilog/code_tests/code_tests.srcs/sources_1/new/top.sv:33] INFO: [Synth 8-6157] synthesizing module 'top' [/home/robucci/verilog/code_tests/code_tests.srcs/sources_1/new/top.sv:23] INFO: [Synth 8-6155] done synthesizing module 'top' (0#1) [/home/robucci/verilog/code_tests/code_tests.srcs/sources_1/new/top.sv:23] WARNING: [Synth 8-3848] Net u in module/entity top does not have driver. [/home/robucci/verilog/code_tests/code_tests.srcs/sources_1/new/top.sv:26] WARNING: [Synth 8-3330] design top has an empty top module WARNING: [Synth 8-7129] Port u in module top is either unconnected or has no load WARNING: [Synth 8-7129] Port a in module top is either unconnected or has no load
Using `default_nettype none
`timescale 1ns / 1ps
`default_nettype none
module top(a,u);
input a;
output u;
assign U = a;
endmodule
line 5, is the error we wanted, but also causes 3,4:
Starting Synthesize : Time (s): cpu = 00:00:03 ; elapsed = 00:00:03 . Memory (MB): peak = 1764.320 ; gain = 409.598 ; free physical = 95677 ; free virtual = 103351 --------------------------------------------------------------------------------- ERROR: [Synth 8-6735] net type must be explicitly specified for 'a' when default_nettype is none [/home/robucci/verilog/code_tests/code_tests.srcs/sources_1/new/top.sv:25] ERROR: [Synth 8-6735] net type must be explicitly specified for 'u' when default_nettype is none [/home/robucci/verilog/code_tests/code_tests.srcs/sources_1/new/top.sv:27] ERROR: [Synth 8-36] 'U' is not declared [/home/robucci/verilog/code_tests/code_tests.srcs/sources_1/new/top.sv:34] INFO: [Synth 8-10285] module 'top' is ignored due to previous errors [/home/robucci/verilog/code_tests/code_tests.srcs/sources_1/new/top.sv:37] INFO: [Synth 8-9084] Verilog file '/home/robucci/verilog/code_tests/code_tests.srcs/sources_1/new/top.sv' ignored due to errors ERROR: [Synth 8-439] module 'top' not found
final approach:
`timescale 1ns / 1ps
`default_nettype none
module top(a,u);
input logic a;
output logic u;
assign u = a;
endmodule
`default_nettype wire
any of these varints work for a
:
input logic a;
input wire a;
input wire logic a;
logical result:
implementation:
q <= a+b;
to assign the output of a register (here the input to the register is a+b)y=a+b;
y=a+b;q<=y;q_prev<q;
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
Reference/Related Guidelines Found : http://www.sunburst-design.com/papers/
Guidelines
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
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;
Combinational Logic:
logic y;
always_comb begin//always @(a,b)
y = a & b;
end
Sequential Logic mixed with Implied Combinational Logic:
logic q;
always_ff @(posedge clk) //always @(posedge clk)
q <= a & b;
Sequential mixed with Explicit Combinational Logic
logic q;
always @(posedge clk): someBlockName
logic _q;
_q = a & b;
q <= _q;
Poor, uses blocking Assignment for sequential logic outputs:
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
Coding all sequential always blocks,even simple single-block modules,using non-blocking assignments.
Good, uses Non-blocking Assignment
module dffx (q, d, clk, rst);
output q;
input d, clk, rst;
logic q;
always @(posedge clk) begin
if (rst) q <= 1'b0;
else q <= d;
end
endmodule
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
đľ Sequential Circuit with Embedded Combinatorial:
always @(posedge clk) begin
{a,b,c} <= {l|m,m|n,(n|l)&e};
end
đľ Separated Combinatorial and Sequential with explicit naming and modeling of combinatorial outputs:
logic a_prereg,b_prereg,c_prereg,c_or;
always @(l,m,n) begin
c_or = n|l;
{a_prereg,b_prereg,c_prereg} = {(l|m),(m|n),c_or&e};
end
always @(posedge clk) begin
{a,b,c} <= {a_prereg,b_prereg,c_prereg};
end
đľ Merged Style with local internal variables supporting âcycle-acurateâ hardware reprentation and simuation local variables require the use of a named block, but the advantage is that this prevents accidential use elsewhere
always @(posedge clk) begin: someBlockName
logic _a,_b,_c,_c_or; //variables indended for use in this block only
// though this is not enforced
_c_or = n|l;
{_a,_b,_c} = {l|m,m|n,_c_or&e};
{a,b,c} <= {a_prereg,b_prereg,c_prereg};
end
đ˛ Does a signal changes its value when when nothing is observing it?
Xilinx(AMD Adaptive Soc) tools, at the time of this writing, will identify extra edge-sensitive hardware for _a,_b,_c,_c_or, and then since they are not used elsewhere Xilinx will report that hardware is trimmed leaving only our inteded output. This makes many distracting warning that I hope are removed in newer software adopting the newer SystemVerilog constructs like always_ff
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.
The following is poor style. It creates potential confusion and potential mistakes of use elsewhere in the circuit by delaring _c_or,_a,_b,_c and making them available outside the block. Using _c_or outside the block would actually genrate a new register outputing a delayed version of _c_or. Using _a,_b,_c would result in a new register that would be recognized to be the same as a,b,c respectively
logic _a,_b,_c;
always @(posedge clk) begin
{_a,_b,_c} = {l|m,m|n,n|l};
{a,b,c} <= {a_prereg,b_prereg,c_prereg};
end
Good: uses named block and local scope
always @(posedge clk) begin: blockC
logic _a,_b,_c;
{_a,_b,_c} = {l|m,m|n,n|l};
{a,b,c} <= {_a,_b,_c};
end
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
*** 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
logic y; always_comb //always @(a,b) y = a & b;
y <= a & b;
but we will follow a convention explained later whereby we use blocking for all combinatorial logicRegistered-output combinatorial logic
logic q; always_ff @(posedge clk) q <= a & b;
đ°ď¸ Combinational and Sequential
q<=a&b;
_q=a&b; q<=_q;
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.
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.
Both of the following examples generate an error in Xilinx ISE:
ERROR:Xst:899 - "top.v" line 28: The logic for <partial> does not match
a known FF or Latch template. The description style you are using to describe
a register or latch is not supported in the current software release.
Problem Code 1:
logic y,partial;
always @(posedge clk, negedge clr_n) begin
partial = a & b;
if (!clr_n) y <= 1'b0;
else y <= ~a | partial;
end
Problem Code 2:
logic partial,y_prereg;
always @(posedge clk, negedge clr_n)
begin
if (!clr_n) begin
partial = a & b;
y_prereg = ~c | partial;
y <= 1'b0;
end
else begin
partial = a & b;
y_prereg = ~c | partial;
y <= y_prereg;
end
end
endmodule
The following code is more compact than the initial separated version, but leads to only warnings
logic y,y_prereg,partial;
always @(posedge clk, negedge clr_n)
//------
begin
if (!clr_n) y <= 1'b0;
else begin
partial = a & b;
y_prereg = ~a | partial;
y <= y_prereg;
end
end
//-------
Implied registers and latches are trimmed since they are only used inside this procedural code block and feed into another signal
If the are used in other processes, additional sequential logic would be generate to provide the saved values externally
The following warning tells us that these are not used externally to the procedural block and so they are trimmed
WARNING:Xst:646 - Signal <y_prereg> is assigned but never used. This unconnected signal will be trimmed during the optimization process.
WARNING:Xst:646 - Signal <partial> is assigned but never used. This unconnected signal will be trimmed during the optimization process.
Note that the variable scope used for y_prereg and partial is unessisary.
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
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
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
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 =========================================================================
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 =========================================================================