Installation of required Tools
Yosys
Commands to install Yosys on Linux.
$ git clone https://github.com/YosysHQ/yosys.git
$ cd yosys-master
$ sudo apt install make (If make is not installed please install it)
$ sudo apt-get install build-essential clang bison flex \
libreadline-dev gawk tcl-dev libffi-dev git \
graphviz xdot pkg-config python3 libboost-system-dev \
libboost-python-dev libboost-filesystem-dev zlib1g-dev
$ make config-gcc
$ make
$ sudo make install
iVerilog
Commans to install iVerilog
sudo apt-get install iverilog.
gtkwave
I installed gtkwave using the following command:
sudo apt-get install gtkwave
ngspice
I downloaded the tarball from https://sourceforge.net/projects/ngspice/files/ to a local directory and unpacked it using the following commands:
tar -zxvf ngspice-37.tar.gz
cd ngspice-37
mkdir release
cd release
../configure --with-x --with-readline=yes --disable-debug
make
sudo make install
Below is the screenshot showing sucessful Launch:
magic
I installed magic using the following commands:
sudo apt-get install m4
sudo apt-get install tcsh
sudo apt-get install csh
sudo apt-get install libx11-dev
sudo apt-get install tcl-dev tk-dev
sudo apt-get install libcairo2-dev
sudo apt-get install mesa-common-dev libglu1-mesa-dev
sudo apt-get install libncurses-dev
Below is the screenshot showing sucessful Launch:
OpenSTA
I installed and built OpenSTA (including the needed packages) using the following commands:
sudo apt-get install cmake clang gcctcl swig bison flex
git clone https://github.com/The-OpenROAD-Project/OpenSTA.git
cd OpenSTA
mkdir build
cd build
cmake ..
make
Below is the screenshot showing sucessful Launch:
Introduction to iverilog, Design and Test Bench
- RTL design is checked for adherence to the spec by simulating the design
- Simulator is the tool used for simulating the design
- iverilog is the tool used for this course
- Design is the actual Verilog code or set of Verilog codes which has the intended functionality to meet with the required specifications
- Simulator looks for the changes on the input signals
- Upon change to the input the output is evaluated
- If no change to the input, no change to the output!
- Simulator is looking for change in the values of input!
Introduction to Yosys
Yosys is an open-source software framework for Verilog RTL (Register Transfer Level) synthesis. It's commonly used in digital design and electronic engineering to convert high-level hardware descriptions written in Verilog into optimized gate-level representations that can be used for ASIC (Application-Specific Integrated Circuit) or FPGA (Field-Programmable Gate Array) implementations. Yosys provides a range of synthesis tools and optimization techniques to generate efficient and compact hardware designs. It's widely used in the hardware design community and is known for its flexibility, extensibility, and ability to handle complex designs.
Labs using Yosys and Sky130 PDKs
*Note: We should be in the directory in which we have cloned the github link.
All libraries will be in myLib
Step-1: Read the Library
read_liberty -lib ../PATH
This command reads in a Liberty format library for use in technology mapping.
*Step-2: Read Design
read_verilog FILE NAME
This command reads in Verilog source files for synthesis. Replace with the actual file name.
*Step-3: Synthesis
synth -top FILE NAME
Step-4: Genetare Netlist
abc is command to convert RTL file to gate. And to what gate is need to specify is Written in the Path.
abc -liberty ../PATH
To see logic realised
show
Step-5: To write Netlist
write_verilog FILE NAME
Introduction to Timing libs
Introduction to .lib File
A .lib file, also known as a Liberty file, is a standard format used to describe the timing, power, and logical characteristics of cells in a digital library. These libraries are essential for the process of logic synthesis and technology mapping in digital design.
Hierarchical vs Flat Synthesis
Flatten
In Yosys, the "flatten" command is used to perform this flattening process. When you run the command, Yosys attempts to inline instances of submodules, removing the module hierarchy. This can be useful before performing certain types of optimizations that might work better on a flattened design.
Different versions of the same logic gate
Multiple Modules
/* Generated by Yosys 0.31+16 (git sha1 b04d0e09e, clang 14.0.0-1ubuntu1.1 -fPIC -Os) */
module multiple_modules(a, b, c, y);
input a;
wire a;
input b;
wire b;
input c;
wire c;
wire net1;
output y;
wire y;
sub_module1 u1 (
.a(a),
.b(b),
.y(net1)
);
sub_module2 u2 (
.a(net1),
.b(c),
.y(y)
);
endmodule
module sub_module1(a, b, y);
wire _0_;
wire _1_;
wire _2_;
input a;
wire a;
input b;
wire b;
output y;
wire y;
sky130_fd_sc_hd__and2_0 _3_ (
.A(_1_),
.B(_0_),
.X(_2_)
);
assign _1_ = b;
assign _0_ = a;
assign y = _2_;
endmodule
module sub_module2(a, b, y);
wire _0_;
wire _1_;
wire _2_;
input a;
wire a;
input b;
wire b;
output y;
wire y;
sky130_fd_sc_hd__or2_0 _3_ (
.A(_1_),
.B(_0_),
.X(_2_)
);
assign _1_ = b;
assign _0_ = a;
assign y = _2_;
endmodule
Flop Codings
Why Flops? They provide memory and state-holding capabilities, allowing circuits to store data and make decisions based on history and current inputs. Combinational circuits use logic gates to directly process inputs without memory elements.
Asynchronous
Synchronous
Synthesis
Combinational and sequential optimizations are two different approaches used in digital circuit design to improve the performance, efficiency, and reliability of electronic systems. These optimizations target different aspects of the design process and address various challenges that arise when designing complex digital circuits.
Combinational Optimizations
Common techniques for combinational optimization include:- Gate-Level Optimization: This involves simplifying logic expressions and minimizing the number of logic gates needed to implement a particular function.
- Technology Mapping: Selecting the optimal gate library for implementing a logic function based on the available manufacturing technology.
- Boolean Algebra Simplification: Applying algebraic identities and theorems to simplify Boolean expressions and reduce the complexity of the logic.
- Logic Synthesis: Automatically generating optimized gate-level representations of a design from a high-level description.
Example AND Gate
Example OR Gate Nand inverted and Gate
Sequential Optimizations
Sequential circuits contain memory elements, such as flip-flops and registers, which allow them to store and process data over time. Sequential optimization focuses on improving the clock frequency, reducing power consumption, and ensuring proper timing and synchronization in these circuits.
Common techniques for sequential optimization include:
- Pipeline Optimization: Breaking down a computation into smaller stages that can be processed concurrently, thus increasing throughput and reducing the critical path delay.
- Clock Gating: Disabling clock signals to specific circuit blocks when they are not needed, reducing power consumption.
- Retiming: Reordering registers within a design to optimize the timing paths and improve the clock frequency.
- State Machine Optimization: Reducing the number of states or transitions in finite state machines to simplify control logic and improve performance.
Example dff_const1
module dff_const1(input clk, input reset, output reg q);
always @(posedge clk, posedge reset)
begin
if(reset)
q <= 1'b0;
else
q <= 1'b1;
end
endmodule
Synthesis
Example dff_const2
module dff_const2(input clk, input reset, output reg q);
always @(posedge clk, posedge reset)
begin
if(reset)
q <= 1'b1;
else
q <= 1'b1;
end
endmodule
Example dff_const3
module dff_const3(input clk, input reset, output reg q);
reg q1;
always @(posedge clk, posedge reset)
begin
if(reset)
begin
q <= 1'b1;
q1 <= 1'b0;
end
else
begin
q1 <= 1'b1;
q <= q1;
end
end
endmodule
Waveform
Synthesis
Example dff_const4
module dff_const4(input clk, input reset, output reg q);
reg q1;
always @(posedge clk, posedge reset)
begin
if(reset)
begin
q <= 1'b1;
q1 <= 1'b1;
end
else
begin
q1 <= 1'b1;
q <= q1;
end
end
endmodule
Example dff_const5
module dff_const5(input clk, input reset, output reg q);
reg q1;
always @(posedge clk, posedge reset)
begin
if(reset)
begin
q <= 1'b0;
q1 <= 1'b0;
end
else
begin
q1 <= 1'b1;
q <= q1;
end
end
endmodule
Counter_opt
module counter_opt (input clk , input reset , output q);
reg [2:0] count;
assign q = count[0];
always @(posedge clk ,posedge reset)
begin
if(reset)
count <= 3'b000;
else
count <= count + 1;
end
endmodule
GLS Flow
GLS concept flow using iverilog
The GLS flow is crucial for ensuring that the gate-level netlist faithfully represents the intended behavior of the original RTL design. It helps catch issues that might have been missed during RTL simulation and ensures that the design is ready for further downstream processes.
Synthesis Simulation mismatch
Ternary Operator
module ternary_operator_mux (input i0 , input i1 , input sel , output y);
assign y = sel?i1:i0;
endmodule
Waveform
Synthesis
Waveform using Standers cells.
Bad_Mux
module bad_mux (input i0 , input i1 , input sel , output reg y);
always @ (sel)
begin
if(sel)
y <= i1;
else
y <= i0;
end
endmodule
In this Wavefrom we cannot see changes in Y as of changes in i0. It just act as a flop which changes as their are changes in select line.
Synthesis
In this Wavefrom we can see changes in Y as of changes in i0.
Blocking and Non-Blocking
Blocking_Coveat
module blocking_caveat (input a , input b , input c, output reg d);
reg x;
always @ (*)
begin
d = x & c;
x = a | b;
end
endmodule
In this waveform thier is Synthesis Simulation mismatch due to Blocking Statements.
Synthesis
Netist code after write_verilog.
Waveform using Standers cells.
If Constructs
incomp_if
module incomp_if (input i0 , input i1 , input i2 , output reg y);
always @ (*)
begin
if(i0)
y <= i1;
end
endmodule
Waveform - Here Y behaves as a Latch
Statistics - We can see here we have infered a DLATCH
Synthesis -
incomp_if2
module incomp_if2 (input i0 , input i1 , input i2 , input i3, output reg y);
always @ (*)
begin
if(i0)
y <= i1;
else if (i2)
y <= i3;
end
endmodule
Waveform- Latching when both io & i1 are zero
Statistics Infered a DLATCH
Synthesis- The OR operation of i0 &i1 will be given to enable of DLATCH
Case Constructs
incomp_case
module incomp_case (input i0 , input i1 , input i2 , input [1:0] sel, output reg y);
always @ (*)
begin
case(sel)
2'b00 : y = i0;
2'b01 : y = i1;
endcase
end
endmodule
Waveform- Latching when sel= 10 or sel= 11 It will continue matching the value of Y which was before.
Statistics
Synthesis
comp_case
module comp_case (input i0 , input i1 , input i2 , input [1:0] sel, output reg y);
always @ (*)
begin
case(sel)
2'b00 : y = i0;
2'b01 : y = i1;
default : y = i2;
endcase
end
endmodule
Waveform
Statistics- No Latch involved
Synthesis- 4x1 Mux
partial_case_assign Statistics- Only one Latch infered in Path of X
Synthesis
bad_case
module bad_mux (input i0 , input i1 , input sel , output reg y);
always @ (sel)
begin
if(sel)
y <= i1;
else
y <= i0;
end
endmodule
Waveform- Output gets confused when sel= 10 or sel=11 and hence behaves as a LATCH
Statistics- No LATCH involved
Synthesis-
Waveform- using standered cell models and testbench
For Loop and For generate
mux_generate
module mux_generate (input i0 , input i1, input i2 , input i3 , input [1:0] sel , output reg y);
wire [3:0] i_int;
assign i_int = {i3,i2,i1,i0};
integer k;
always @ (*)
begin
for(k = 0; k < 4; k=k+1) begin
if(k == sel)
y = i_int[k];
end
end
endmodule
Waveform
Synthesis
demux_case
module fa (input a , input b , input c, output co , output sum);
assign {co,sum} = a + b + c ;
endmodule
Waveform
Synthesis
demux_generate
module demux_generate (output o0 , output o1, output o2 , output o3, output o4, output o5, output o6 , output o7 , input [2:0] sel , input i);
reg [7:0]y_int;
assign {o7,o6,o5,o4,o3,o2,o1,o0} = y_int;
integer k;
always @ (*)
begin
y_int = 8'b0;
for(k = 0; k < 8; k++) begin
if(k == sel)
y_int[k] = i;
end
end
endmodule
Waveform- Here we can see that the waveform is same as of demux_case but the code is Optimised
rca
Code of Full Adder(fa).
module fa (input a , input b , input c, output co , output sum);
assign {co,sum} = a + b + c ;
endmodule
Code of Ripple Carry Adder(rca).
module rca (input [7:0] num1 , input [7:0] num2 , output [8:0] sum);
wire [7:0] int_sum;
wire [7:0]int_co;
genvar i;
generate
for (i = 1 ; i < 8; i=i+1) begin
fa u_fa_1 (.a(num1[i]),.b(num2[i]),.c(int_co[i-1]),.co(int_co[i]),.sum(int_sum[i]));
end
endgenerate
fa u_fa_0 (.a(num1[0]),.b(num2[0]),.c(1'b0),.co(int_co[0]),.sum(int_sum[0]));
assign sum[7:0] = int_sum;
assign sum[8] = int_co[7];
endmodule
Note- Here we have to read the fafile also as our code for FA is in the fa.v file
Waveform
Statistics
Synthesis of Full Adder.
Synthesis of Ripple Carry Adder.
Code of Created Netlist(rca_net.v)
/* Generated by Yosys 0.31+16 (git sha1 b04d0e09e, clang 14.0.0-1ubuntu1.1 -fPIC -Os) */
module fa(a, b, c, co, sum);
wire _0_;
wire _1_;
wire _2_;
wire _3_;
wire _4_;
wire _5_;
wire _6_;
wire _7_;
input a;
wire a;
input b;
wire b;
input c;
wire c;
output co;
wire co;
output sum;
wire sum;
sky130_fd_sc_hd__maj3_1 _8_ (
.A(_3_),
.B(_5_),
.C(_4_),
.X(_6_)
);
sky130_fd_sc_hd__xor3_1 _9_ (
.A(_3_),
.B(_5_),
.C(_4_),
.X(_7_)
);
assign _3_ = a;
assign _5_ = c;
assign _4_ = b;
assign co = _6_;
assign sum = _7_;
endmodule
module rca(num1, num2, sum);
wire [7:0] int_co;
wire [7:0] int_sum;
input [7:0] num1;
wire [7:0] num1;
input [7:0] num2;
wire [7:0] num2;
output [8:0] sum;
wire [8:0] sum;
fa \genblk1[1].u_fa_1 (
.a(num1[1]),
.b(num2[1]),
.c(int_co[0]),
.co(int_co[1]),
.sum(int_sum[1])
);
fa \genblk1[2].u_fa_1 (
.a(num1[2]),
.b(num2[2]),
.c(int_co[1]),
.co(int_co[2]),
.sum(int_sum[2])
);
fa \genblk1[3].u_fa_1 (
.a(num1[3]),
.b(num2[3]),
.c(int_co[2]),
.co(int_co[3]),
.sum(int_sum[3])
);
fa \genblk1[4].u_fa_1 (
.a(num1[4]),
.b(num2[4]),
.c(int_co[3]),
.co(int_co[4]),
.sum(int_sum[4])
);
fa \genblk1[5].u_fa_1 (
.a(num1[5]),
.b(num2[5]),
.c(int_co[4]),
.co(int_co[5]),
.sum(int_sum[5])
);
fa \genblk1[6].u_fa_1 (
.a(num1[6]),
.b(num2[6]),
.c(int_co[5]),
.co(int_co[6]),
.sum(int_sum[6])
);
fa \genblk1[7].u_fa_1 (
.a(num1[7]),
.b(num2[7]),
.c(int_co[6]),
.co(int_co[7]),
.sum(int_sum[7])
);
fa u_fa_0 (
.a(num1[0]),
.b(num2[0]),
.c(1'h0),
.co(int_co[0]),
.sum(int_sum[0])
);
assign sum = { int_co[7], int_sum };
endmodule
Waveform of GLS.
I sciencerly thank Mr. Kunal Gosh(Founder/VSD) for helping me out to complete this flow smoothly.
- Kunal Ghosh, VSD Corp. Pvt. Ltd.
- Skywater Foundry
- Chatgtp
- Emil, Colleauge(IIIT-B)
- Alwin, Colleauge(IIIT-B)