Skip to content

alfadelta10010/pes-asic-class

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

44 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

VLSI Physical Design - Lab-work Repository

This repository contains all the assignments and information from the VLSI Physical Design for ASICs special topic taught at PES University, EC Campus, for ECE students, by Kunal Ghosh from VLSI System Design

This repo has been divided into various subfolders for different days of the coursework Click on the links below to find the documents for each lab:

Set up instructions for the coursework

The software required is as follows:

For a simple set up, you can use the set-up script provided by the instructor with the following commands:

git clone https://github.com/kunalg123/riscv_workshop_collaterals.git
cd riscv_workshop_collaterals
chmod +x run.sh
./run.sh

Day - 1 Lab assignments

Assignment 1

  • Write a program to calculate sum of numbers from 1 to n, and compile with x86-gcc

  • The code is as follows: code

  • To compile and run with x86-gcc:

gcc sum1ton.c -o x86.out
./x86.out
  • This gives the following output: x86 execution

  • This summarizes assignment 1.

Assignment 2

  • Disassemble the previous program to run on RISC-V processors
  • The code can be compiled for RISC-V processors using riscv64-gcc:
#include <stdio.h>
int main()
{
	int i, sum = 0, n = 5;
	for(i = 1; i <= n; i++)
	{
		sum = sum + i;
	}
	printf("Sum of numbers from 1 to %d is %d \n", n, sum);
	return 0;
}
  • To disassemble, we run the following command:
riscv64-unknown-elf-gcc -O1 -mabi=lp64 -march=rv64i -o rv.o 1ton.c
  • This generates the following output: RV Disassembly

  • To view the output, we use the following command:

riscv64-unknown-elf-objdump -d rv.o | less
  • This generates the following output: RV Object Dump

  • Scrolling down to the main function, we see that there are 15 instructions: RV Dump Main fn

  • If we change the optimization flag to -Ofast during disassembly, the number of instructions is reduced as shown below: RV Fast Disassembly RV Fast Object Dump

  • Here, we see there are 12 instructions in main function

  • This concludes assignment 2

Assignment 3

  • Execute and debug the 1ton.c on RISC-V simulator
  • To compile with riscv64-gcc:
riscv64-unknown-elf-gcc -Ofast -mabi=lp64 -march=rv64i -o rv.out 1ton.c
  • This gives the following output: rv compile

  • To execute, we use the Spike RISC-V ISA Simulator as follows: rv execution

  • To debug, we start spike in debug mode, using:

spike -d pk rv.out
  • To move the Program counter from 0 to the first instruction, we execute all the instructions in between, using:
until pc 0 100b0
  • To find contents of the register a0 before being written, we use
reg 0 a0
  • To execute the next instruction, press enter

  • If we see the value of the register after execution, it has changed.

  • The output as follows: Debug

  • Seeing value of stack pointer update: Stack pointer

  • Upon calculating, the value has changed by 10

  • This concludes assignment 3.

Assignment 4

  • Testing the limits of long long int on RV64I, on unsigned and signed integer.
  • Write the program unsignedLimits.c shown here:
#include <stdio.h>
#include <math.h>

int main(){
	unsigned long long int max = (unsigned long long int) (pow(2,64) -1);
	unsigned long long int min = (unsigned long long int) (pow(2,64) *(-1));
	printf("lowest number represented by unsigned 64-bit integer is %llu\n",min);
	printf("highest number represented by unsigned 64-bit integer is %llu\n",max);
	return 0;
}
  • To compile and run with riscv64-gcc:
riscv64-unknown-elf-gcc -Ofast -mabi=lp64 -march=rv64i -o limits.o unsignedLimits.c
spike pk limits.o
  • The output is as follows: RV64 Long Long uint Limits

  • To test if it is the limit, we modify as follows:

unsigned long long int max = (unsigned long long int) (pow(2,127) -1);
unsigned long long int min = (unsigned long long int) (pow(2,127) *(-1));
  • The output is the same: RV64 Long Long uint, exceeding limits

  • To prove that the values do get changed, we modify as follows:

unsigned long long int max = (unsigned long long int) (pow(2,5) -1);
unsigned long long int min = (unsigned long long int) (pow(2,5) *(-1));
  • The output is as follows: RV64 Long Long uint, within limits

  • Write the program signedLimits.c shown here:

#include <stdio.h>
#include <math.h>

int main(){
	long long int max = (long long int) (pow(2,5) -1);
	long long int min = (long long int) (pow(2,5) *(-1));
	printf("lowest number represented by 64-bit integer is %lld\n",min);
	printf("highest number represented by 64-bit integer is %lld\n",max);
	return 0;
}
  • To compile and run with riscv64-gcc:
riscv64-unknown-elf-gcc -Ofast -mabi=lp64 -march=rv64i -o slimits.o signedLimits.c
spike pk slimits.o
  • The output is as follows: RV64 Long Long int Limits

  • To test if it is the limit, we modify as follows:

long long int max = (long long int) (pow(2,127) -1);
long long int min = (long long int) (pow(2,127) *(-1));
  • The output is the same: RV64 Long Long int, exceeding limits

  • To prove that the values do get changed, we modify as follows:

long long int max = (long long int) (pow(2,5) -1);
long long int min = (long long int) (pow(2,5) *(-1));
  • The output is as follows: RV64 Long Long int, within limits

  • This concludes assignment 4

Day 2 Assignments

Assignment 1

  • Write load.s and 1to9_custom.c as descibed in the algorithm
  • load.s
.section .text
.global load
.type load, @function

load:
	add	a4, a0, zero
	add	a2, a0, a1
	add	a3, a0, zero
loop:	add	a4, a3, a4
	addi	a3, a3, 1
	blt	a3, a2, loop
	add	a0, a4, zero
	ret
  • 1to9_custom.c
cat 1to9_custom.c 
#include <stdio.h>

extern int load(int x, int y);

int main()
{
	int result = 0;
	int count = 9;
	result = load(0x0, count + 1);
	printf("Sum of nos. from 1 to %d is %d\n", count, result);
}
  • This concludes assignment 1

Assignment 2

  • Compile the code with the files and options with the following command:
riscv64-unknown-elf-gcc -Ofast -mabi=lp64 -march=rv64i -o 1to9_custom.o 1to9_custom.c load.s

Compile

  • To run, use the following command:
spike pk 1to9_custom.o
  • This generates the following output: Execution

  • Inspecting the object dump: Object dump

  • This concludes assignment 2

Assignment 3

  • To run C program on PicoRV32
  • Make the set-up script executable, and execute
chmod +x rv32im.sh
./rv32im.sh

Executable Execution

  • This concludes assignment 3

Day 1 Assignments - RTL

Lab 1

  • Simulating good_mux.v and seeing outputs in gtkwave Simulation GTKWave
  • This concludes lab 1

Lab 2

  • smth good_mux.v in YoSys

  • First we read liberty file: liberty file

  • Next we read the verilog file: read verilog

  • Then we synthesize the top-level design

yosys> synth -top good_mux 

3. Executing SYNTH pass.

3.1. Executing HIERARCHY pass (managing design hierarchy).

3.1.1. Analyzing design hierarchy..
Top module:  \good_mux

3.1.2. Analyzing design hierarchy..
Top module:  \good_mux
Removed 0 unused modules.

3.2. Executing PROC pass (convert processes to netlists).

<removed extended output>

3.25. Printing statistics.

=== good_mux ===

   Number of wires:                  4
   Number of wire bits:              4
   Number of public wires:           4
   Number of public wire bits:       4
   Number of memories:               0
   Number of memory bits:            0
   Number of processes:              0
   Number of cells:                  1
     $_MUX_                          1

3.26. Executing CHECK pass (checking for obvious problems).
Checking module good_mux...
Found and reported 0 problems.
  • Next we generate gate level file:
yosys> abc -liberty ../lib/sky130_fd_sc_hd__tt_025C_1v80.lib 

4. Executing ABC pass (technology mapping using ABC).

4.1. Extracting gate netlist of module `\good_mux' to `<abc-temp-dir>/input.blif'..
Extracted 1 gates and 4 wires to a netlist network with 3 inputs and 1 outputs.

4.1.1. Executing ABC.
Running ABC command: "<yosys-exe-dir>/yosys-abc" -s -f <abc-temp-dir>/abc.script 2>&1
ABC: ABC command line: "source <abc-temp-dir>/abc.script".
ABC: 
ABC: + read_blif <abc-temp-dir>/input.blif 
ABC: + read_lib -w /home/alphadelta1803/Desktop/folder/sky130RTLDesignAndSynthesisWorkshop/verilog_files/../lib/sky130_fd_sc_hd__tt_025C_1v80.lib 
ABC: Parsing finished successfully.  Parsing time =     0.11 sec
ABC: Scl_LibertyReadGenlib() skipped cell "sky130_fd_sc_hd__decap_12" without logic function.
<removed output>
ABC: + write_blif <abc-temp-dir>/output.blif 

4.1.2. Re-integrating ABC results.
ABC RESULTS:   sky130_fd_sc_hd__mux2_1 cells:        1
ABC RESULTS:        internal signals:        0
ABC RESULTS:           input signals:        3
ABC RESULTS:          output signals:        1
Removing temp directory.
  • Part we are interested in:
ABC RESULTS:   sky130_fd_sc_hd__mux2_1 cells:        1
ABC RESULTS:        internal signals:        0
ABC RESULTS:           input signals:        3
ABC RESULTS:          output signals:        1
  • Now we use show command to view the logic diagaram: show command

Day 2 Assignments - RTL

Lab 1

  • multiple_modules.v
module sub_module2 (input a, input b, output y);
	assign y = a | b;
endmodule

module sub_module1 (input a, input b, output y);
	assign y = a&b;
endmodule


module multiple_modules (input a, input b, input c , output y);
	wire net1;
	sub_module1 u1(.a(a),.b(b),.y(net1));  //net1 = a&b
	sub_module2 u2(.a(net1),.b(c),.y(y));  //y = net1|c ,ie y = a&b + c;
endmodule
  • Synthesizing the top module:
3.25. Printing statistics.

=== multiple_modules ===

   Number of wires:                  5
   Number of wire bits:              5
   Number of public wires:           5
   Number of public wire bits:       5
   Number of memories:               0
   Number of memory bits:            0
   Number of processes:              0
   Number of cells:                  2
     sub_module1                     1
     sub_module2                     1

=== sub_module1 ===

   Number of wires:                  3
   Number of wire bits:              3
   Number of public wires:           3
   Number of public wire bits:       3
   Number of memories:               0
   Number of memory bits:            0
   Number of processes:              0
   Number of cells:                  1
     $_AND_                          1

=== sub_module2 ===

   Number of wires:                  3
   Number of wire bits:              3
   Number of public wires:           3
   Number of public wire bits:       3
   Number of memories:               0
   Number of memory bits:            0
   Number of processes:              0
   Number of cells:                  1
     $_OR_                           1

=== design hierarchy ===

   multiple_modules                  1
     sub_module1                     1
     sub_module2                     1

   Number of wires:                 11
   Number of wire bits:             11
   Number of public wires:          11
   Number of public wire bits:      11
   Number of memories:               0
   Number of memory bits:            0
   Number of processes:              0
   Number of cells:                  2
     $_AND_                          1
     $_OR_                           1
  • Upon running show command: show command
  • This is the hierarchical design
  • Writing the verilog file gives us the following output:
/* Generated by Yosys 0.32+66 (git sha1 b168ff99d, gcc 11.4.0-1ubuntu1~22.04 -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
  • Hierarchies are preserved

Lab 2

  • Writing a flat netlist
  • Using flatten and write_verilog -noattr multiple_modules_flat.v, we get the following:
/* Generated by Yosys 0.32+66 (git sha1 b168ff99d, gcc 11.4.0-1ubuntu1~22.04 -fPIC -Os) */

module multiple_modules(a, b, c, y);
  wire _0_;
  wire _1_;
  wire _2_;
  wire _3_;
  wire _4_;
  wire _5_;
  input a;
  wire a;
  input b;
  wire b;
  input c;
  wire c;
  wire net1;
  wire \u1.a ;
  wire \u1.b ;
  wire \u1.y ;
  wire \u2.a ;
  wire \u2.b ;
  wire \u2.y ;
  output y;
  wire y;
  sky130_fd_sc_hd__and2_0 _6_ (
    .A(_1_),
    .B(_0_),
    .X(_2_)
  );
  sky130_fd_sc_hd__or2_0 _7_ (
    .A(_4_),
    .B(_3_),
    .X(_5_)
  );
  assign _4_ = \u2.b ;
  assign _3_ = \u2.a ;
  assign \u2.y  = _5_;
  assign \u2.a  = net1;
  assign \u2.b  = c;
  assign y = \u2.y ;
  assign _1_ = \u1.b ;
  assign _0_ = \u1.a ;
  assign \u1.y  = _2_;
  assign \u1.a  = a;
  assign \u1.b  = b;
  assign net1 = \u1.y ;
endmodule
  • Running show command show command

  • Executing submodule synthesis show command

  • This concludes lab 2

Lab 3.1

  • Async Reset D-Flip Flop Synthesis and Simulations

  • Simulation: simulation simulation

  • Synthesis: synthesis

Lab 3.2

  • Async Set D-Flip Flop Synthesis and Simulations

  • Simulation: simulation simulation

  • Synthesis: synthesis

Lab 3.3

  • Sync reset D-Flip Flop Synthesis and Simulations

  • Simulation: simulation simulation

  • Synthesis: synthesis

Lab 4.1

  • Running optimizations on mult_2.v
  • Sythesis report: synthesis report
  • show command: sshow
  • Netlist dumped by YoSys
/* Generated by Yosys 0.32+66 (git sha1 b168ff99d, gcc 11.4.0-1ubuntu1~22.04 -fPIC -Os) */

module mul2(a, y);
  input [2:0] a;
  wire [2:0] a;
  output [3:0] y;
  wire [3:0] y;
  assign y = { a, 1'h0 };
endmodule

Lab 4.2

  • Running optimizations on mult_8.v
  • Sythesis report: synthesis report
  • show command: show
  • Netlist dumped by YoSys
/* Generated by Yosys 0.32+66 (git sha1 b168ff99d, gcc 11.4.0-1ubuntu1~22.04 -fPIC -Os) */

module mult8(a, y);
  input [2:0] a;
  wire [2:0] a;
  output [5:0] y;
  wire [5:0] y;
  assign y = { a, a };
endmodule

Day 3 Assignments - RTL

Lab 1

  • Combinational Logic Operations

Lab 1.1

  • opt_check.v
  • Code:
module opt_check (input a , input b , output y);
        assign y = a?b:0;
endmodule
  • Synthesis report: synthesis
  • show command: show

Lab 1.2

  • opt_check2.v
  • Code:
module opt_check2 (input a , input b , output y);
        assign y = a?1:b;
endmodule
  • Synthesis report: synthesis
  • show command: show

Lab 1.3

  • opt_check3.v
  • Code:
module opt_check3 (input a , input b, input c , output y);
        assign y = a?(c?b:0):0;
endmodule
  • Synthesis report: synthesis
  • show command: show

Lab 1.4

  • opt_check4.v
  • Code:
module opt_check4 (input a , input b , input c , output y);
	assign y = a?(b?(a & c ):c):(!c);
endmodule
  • Synthesis report: synthesis
  • show command: show

Lab 1.5

  • multiple_module_opt.v
  • Code:
module sub_module1(input a , input b , output y);
	assign y = a & b;
endmodule

module sub_module2(input a , input b , output y);
	assign y = a^b;
endmodule


module multiple_module_opt(input a , input b , input c , input d , output y);
	wire n1,n2,n3;
	sub_module1 U1 (.a(a) , .b(1'b1) , .y(n1));
	sub_module2 U2 (.a(n1), .b(1'b0) , .y(n2));
	sub_module2 U3 (.a(b), .b(d) , .y(n3));
	assign y = c | (b & n1);
endmodule
  • Synthesis report: synthesis

  • show command: show

  • END OF LAB 1

Lab 2

  • Sequential Logic Optimiztions

Lab 2.1

  • dff_const1.v
  • Code:
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
  • Simulation: simulation simulation

  • Synthesis report: synthesis

  • show command: show

Lab 2.2

  • dff_const2.v
  • Code:
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
  • Simulation: simulation simulation

  • Synthesis report: synthesis

  • show command: show

Lab 2.3

  • dff_const3.v
  • Code:
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
  • Simulation: simulation simulation

  • Synthesis report: synthesis

  • show command: show

Lab 2.4

  • dff_const4.v
  • Code:
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
  • Simulation: simulation simulation

  • Synthesis report: synthesis

  • show command: show

Lab 2.5

  • dff_const5.v
  • Code:
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
  • Simulation: simulation simulation

  • Synthesis report: synthesis

  • show command: show

  • END OF LAB 2

Lab 3

  • Sequential Optimisations for Unused Outputs

Lab 3.1

  • counter_opt.v
  • Code:
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
  • Synthesis report: synthesis
  • show command: show

Lab 3.2

  • counter_opt2.v
  • Code:
module counter_opt2 (input clk , input reset , output q);
reg [2:0] count;
assign q = (count[2:0] == 3'b100);

always @(posedge clk ,posedge reset)
begin
        if(reset)
                count <= 3'b000;
        else
                count <= count + 1;
end

endmodule
  • Synthesis report: synthesis

  • show command: show

  • END OF LAB 3

Day 4 Assignments - RTL

Lab 1

  • GLS and Synthesis-Simulation Mismatch

Lab 1.1

  • 'ternary_operator_mux.v'
module ternary_operator_mux (input i0 , input i1 , input sel , output y);
	assign y = sel?i1:i0;
endmodule
  • Simulation: simulation simulation

  • Synthesis report: synthesis

  • show command: show

  • GLS to Gate-Level Simulation gls simulation gls simulation

Lab 1.2

  • 'bad_mux.v'
module bad_mux (input i0 , input i1 , input sel , output reg y);
always @ (sel)
begin
	if(sel)
		y <= i1;
	else 
		y <= i0;
end
endmodule
  • Simulation: simulation simulation

  • Synthesis report: synthesis

  • show command: show

  • GLS to Gate-Level Simulation gls simulation gls simulation

Lab 2

  • Synth-Sim Mismatch for Blocking Statement
  • 'blocking_caveat.v'
module blocking_caveat (input a , input b , input  c, output reg d); 
reg x;
always @ (*)
begin
	d = x & c;
	x = a | b;
end
endmodule
  • Simulation: simulation simulation

  • Synthesis report: synthesis

  • show command: show

  • GLS to Gate-Level Simulation gls simulation gls simulation

  • This concludes lab 2

About

Assignments and Files from the ASIC course

Resources

Stars

Watchers

Forks