Skip to content

VSDSquadraonMini_Research_intern_repo {I made the pinout diagram for the squadron mini :) } (for documenting/accounting the progression of the internship)

License

Notifications You must be signed in to change notification settings

ARX-0/VSDSquadraonMini_Research_intern

Repository files navigation

VSDSquadraonMini_Research_intern

Repository for documenting and accounting the progression of the internship.

HIGHLIGHTS

Updated Pinout Diagram for VSD SQUADRON Mini thats my contribution towards opensource

Below is the updated pinout diagram for the VSD SQUADRON Mini, which is essential for our ongoing projects. This updated version was created by referring to the original documentation and the repository to it is linked below.

VSD SQUADRON Mini Pinout diagram Pinout Work Final Pinout Image

Link to the documentation and the official repo

TASK - I

(Executed in VMware Ubuntu 18.04 environment)

Objective

To execute a simple C program (prog.c), compile it, and verify the number of instructions using the RISC-V compiler. Refer to the screenshot below:

Annotated Image

The above program adds all the numbers from 1 to n and produces the output.

Steps to Convert the C Program to Assembly Code

  1. Compile the Program:

    riscv64-unknown-elf-gcc -O1 -mabi=lp64 -march=rv64i -o prog.o prog.c
    ls -ltr prog.o
    riscv64-unknown-elf-objdump -d prog.o

    Or use:

    riscv64-unknown-elf-objdump -d prog.o | less
  2. Explanation:

    • -march=rv64i: Specifies the target architecture (RV64I - RISC-V 64-bit integer base ISA).
    • -o prog.o: Specifies the output file name (prog.o).
    • prog.c: The input C source file.
  3. Output:

    The output file prog.o is created and displayed as shown below:

    Annotated Image

  4. Inspecting the Assembly Code:

    Search for the main function using /main and n consecutively to navigate through the output:

    Annotated Image

    • Observe that the main function ends at 100b0 and starts at the instruction 10184.
    • Subtract the start address from the end address: 100b0 - 10184 = 2C in hexadecimal.
    • Convert 2C to decimal and divide by 4 to get the number of instructions: 2C (hex) = 44 (dec) / 4 = 11 instructions.
  5. Optimized Compilation:

    Repeat the above process with the -Ofast optimization flag:

    riscv64-unknown-elf-gcc -Ofast -mabi=lp64 -march=rv64i -o prog.o prog.c
    riscv64-unknown-elf-objdump -d prog.o | less

    The output is as follows:

    Annotated Image

    Annotated Image

    The result shows 11 instructions in the main function.


By following these steps, you can verify the number of instructions in the compiled RISC-V assembly code.

TASK-II

MAIN AIM OF THIS TASK IS TO UNDERSTAND THE VARIOUS RISC-V INSTRUCTIONS AND WHERE IT IS BEING USED.

The documentation used is the official RISC-V spec sheet and the Green card (the card with all instructions).

The documentation used is referred here.

My previous encounters with these processors are documented HERE; it's a single cycle processor with a limited instruction set.

Sure! Here are the stages as bullet points:

  • IF: Instruction Fetch
  • ID: Instruction Decode
  • EX: Execute
  • MEM: Memory Access
  • WB: Register Write Back

IF (Instruction Fetch)

The PC or the program counter increments the value of the address-pointer (address) by four for every clock cycle, from the existing (current) instruction to the next instruction, thereby effectively fetching information. This gives us how the IF (Instruction Fetch) takes place. The below is the representation of RV32i 31 general-purpose registers x1–x31, which hold integer values. Register x0 is hardcoded to the constant 0. Here the x registers are 32 bits wide.

the register orientation

ID (Instruction Decode)

In the (Instruction Decode) ID, it decodes the current instruction given by the current address via the PC (program counter). They are categorised into the following R, I, S, B, U, J (types of instruction sets) following the RV32I base integer instruction set.

THE CATEGORIES THAT THE INSTRUCTION SETS ARE CATEGORISED INTO ARE REPRESENTED BELOW

I type jump insrt JALR

after DECODING into these perticular instruction sets the 32 bit instruction is then executed

EX (Execute)

R Type Instruction

I type jump insrt JALR

Here in the R type instruction. All operations read the [19:15] rs1 and [24:20] rs2 registers (the source registers) as source operands and write the result into register [11:7] rd (the target register) . The [31:25] funct7 and [14:12] funct3 fields select the type of operation finally the opcode for R-type instruction is [6:0].

ADD and SUB perform addition and subtraction respectively.

SLT and SLTU perform signed and unsigned compares respectively.

{That is rd becomes (1) if rs1 < rs2 ,otherwise it is made zero (0)}. {In the operation of SLTU the registers rd,x0,rs2 sets rd to (1) one if and only if rs2 is not equal to zero. Otherwise rd is set to zero (0).}

AND, OR, and XOR perform bitwise logical operations. SLL, SRL, and SRA perform logical left, logical right, and arithmetic right shifts on the value in register rs1 by the shift amount held in the lower 5 bits of register rs2.

examples:-

  1. ADD r6, r2, r1

    • Opcode: 0110011
    • Funct3: 000
    • Funct7: 0000000
    • rd: 00110 // represent as 5'b6
    • rs1: 00001 // represent as 5'b1
    • rs2: 00010 // represent as 5'b2
    • Instruction Code: 0000000 00010 00001 000 00110 0110011
  2. SUB r7, r1, r2

    • Opcode: 0110011
    • Funct3: 000
    • Funct7: 0100000
    • rd: 00111
    • rs1: 00001
    • rs2: 00010
    • Instruction Code: 0100000 00010 00001 000 00111 0110011
  3. AND r8, r1, r3

    • Opcode: 0110011
    • Funct3: 111
    • Funct7: 0000000
    • rd: 01000
    • rs1: 00001
    • rs2: 00011
    • Instruction Code: 0000000 00011 00001 111 01000 0110011
  4. OR r9, r2, r5

    • Opcode: 0110011
    • Funct3: 110
    • Funct7: 0000000
    • rd: 01001
    • rs1: 00010
    • rs2: 00101
    • Instruction Code: 0000000 00101 00010 110 01001 0110011
  5. XOR r10, r1, r4

    • Opcode: 0110011
    • Funct3: 100
    • Funct7: 0000000
    • rd: 01010
    • rs1: 00001
    • rs2: 00100
    • Instruction Code: 0000000 00100 00001 100 01010 0110011
  6. SLT r11, r2, r4

    • Opcode: 0110011
    • Funct3: 010
    • Funct7: 0000000
    • rd: 01011
    • rs1: 00010
    • rs2: 00100
    • Instruction Code: 0000000 00100 00010 010 01011 0110011
  7. SRL r16, r14, r2

    • Opcode: 0110011
    • Funct3: 101
    • Funct7: 0000000
    • rd: 10000
    • rs1: 01110
    • rs2: 00010
    • Instruction Code: `0000000 00010 01110 101 10000 0110011
  8. SLL r15, r1, r2

    • Opcode: 0110011
    • Funct3: 001
    • Funct7: 0000000
    • rd: 01111
    • rs1: 00001
    • rs2: 00010
    • Instruction Code: 0000000 00010 00001 001 01111 0110011

I Type Instruction

I type jump insrt JALR

Here in the I type instruction we have [31:20] as the 11'b immidiate exteder value (with a sign extend) ,[19:15] the source register adress ,[14:12] function3 (which denotes the type of the function used say ADDI/SLTI/XORI etc) ,[11:7] has the adress of the source register ,[6:0] has the opcode of the immmidiate instruction set.

ADDI(increment/decrement function) adds the sign-extended 12-bit immediate to register rs1. Arithmetic overflow is ignored and the result is simply the lower *width of an x register* bits of the result.

SLTI (set less than immediate) places the value 1 in register rd {if register rs1 is less than the signextended immediate when both are treated as signed numbers}, else 0 is written to rd.

SLTIU is similar but compares the values as unsigned numbers Its function is rd, rs1 sets rd to 1 if rs1 equals zero, otherwise sets rd to 0

ANDI, ORI, XORI are logical operations that perform bitwise AND, OR, and XOR on register rs1 and the sign-extended 12-bit immediate and place the result in rd. Note an example, XORI rd, rs1, -1 performs a bitwise logical inversion of register rs1

rd = rs & imm ,rd = rs | imm ,rd = rs ^ imm are some examples respectively.

examples:-

  1. ADDI r12, r4, 5

    • Opcode: 0010011
    • Funct3: 000
    • rd: 01100
    • rs1: 00100
    • imm: 000000000101
    • Instruction Code: 0000000 000101 00100 000 01100 0010011
  2. LW r13, r1, 2

    • Opcode: 0000011
    • Funct3: 010
    • rd: 01101
    • rs1: 00001
    • imm: 000000000010
    • Instruction Code: 0000000 000010 00001 010 01101 0000011

S Type Instruction

I type jump insrt JALR

The S or shift type instruction is a type of I type instruction but with the immidiate extender value bits split into two imm[11:5] as [31:25] and the imm[4:0] as the [24:20] instead of the conventional [31:20] being the immidiate extender.

  1. SW r3, r1, 2
    • Opcode: 0100011
    • Funct3: 010
    • rs1: 00001
    • rs2: 00011
    • imm: 000000000010 (split as 5-bit imm[11:5] and 7-bit imm[4:0])
    • Instruction Code: 0000000 00011 00001 010 00010 0100011

The operand to be shiftedis in rs1, and the shift amount is encoded in the lower 5 bits of the I-immediate field. The right shift type is encoded in a high bit of the I-immediate.

SLLI is a logical left shift (zeros are shifted into the lower bits).

SRLI is a logical right shift (zeros are shifted into the upper bits).

SRAI is an arithmetic right shift (the original sign bit is copied into the vacated upper bits).

B Type Instruction

I type jump insrt JALR

The 12-bit B-immediate encodes signed offsets in multiples of 2, and is added to the current pc (current adress) to give the target address.

Branch instructions compare two registers. BEQ and BNE take the branch if registers [19:15] rs1 and [24:20] rs2 are equal or unequal respectively.

BLT and BLTU take the branch if rs1 is less than rs2, using signed and unsigned comparison respectively.

BGE and BGEU take the branch if rs1 is greater than or equal to rs2, using signed and unsigned comparison respectively.

Note, BGT, BGTU, BLE, and BLEU can be synthesized by reversing the operands to BLT, BLTU, BGE, and BGEU, respectively.

example:-

  1. BNE r0, r1, 20

    • Opcode: 1100011
    • Funct3: 001
    • rs1: 00000
    • rs2: 00001
    • imm: 00000000010100 (split as imm[12], imm[10:5], imm[4:1], imm[11])
    • Instruction Code: 0000000 00101 00000 001 00001 1100011
  2. BEQ r0, r0, 15

    • Opcode: 1100011
    • Funct3: 000
    • rs1: 00000
    • rs2: 00000
    • imm: 00000000001111 (split as imm[12], imm[10:5], imm[4:1], imm[11])
    • Instruction Code: 0000000 01111 00000 000 00000 1100011

J Type Instruction

J Type Instruction

In the J type instruction is of two types unconditional jumps and conditional branches.

JAL or the jump and link instruction uses the J-type format, where the J-immediate encodes a signed offset in multiples of 2 bytes. The offset is sign-extended and added to the pc to form the jump target address. Jumps can therefore target a ±1 MiB range. JAL stores the address of the instruction following the jump (pc+4){the increment in pc} into register rd.We use the x1 as the return address register and x5 as an alternate link register.

I type jump insrt JALR

JALR or the jump and link register (is an indirect jump instruction but here we use I type encoding instead of the J type encoding)

The target address is obtained by adding the 12-bit signed I-immediate to the register [19:15] rs1, then setting the least-significant bit of the result to zero. The [14:12] function3 is set to all zeros .The address of the instruction following the jump (pc+4) is written to register [11:7] rd. (Optional case :-Register x0 can be used as the destination if the result is not required.) the pop and push that comes along with it are out of the scope of this repo refer the resources pg 17 of the riscv-spec-v2.2.pdf attached above in the same repo :)

U Type Instruction

I type jump insrt JALR

The U type instruction has [31:12]immidiate extender ,[11:7]destination register (rd) , [6:0] opcode for the U type instruction LUI or the AUIPC .

LUI (load upper immediate) is used to build 32-bit constants,LUI places the U-immediate value in the top 20 bits of the destination register rd, filling in the lowest 12 bits with zeros.

AUIPC (add upper immediate to pc) is used to build pc-relative addresses. AUIPC forms a 32-bit offset from the 20-bit U-immediate, filling in the lowest 12 bits with zeros, adds this offset to the pc, then places the result in register rd.

MEM (Memory Access)

Load Word Instruction & Store worrd instruction

I type jump insrt JALR

It basically dose read data or writes data to memory. Consisting of the above instructions LW and SW load word and store word respectively, load and store instructions transfer a value between the registers and memory. (register ---> memory)

(LOAD is encoded in I type format) where as (the STORE is encoded in S type instruction format) ,

Load is encoded in the I-type format. The effective byte address is obtained by adding register rs1 to the sign-extended 12-bit offset. Loads copy a value from memory to register rd. Stores copy the value in register rs2 to memoryor simply (rs2,rd = rs1 + 12'b offset imm ).

  1. LW r13, r1, 2
    • Opcode: 0000011
    • Funct3: 010
    • rd: 01101
    • rs1: 00001
    • imm: 000000000010
    • Instruction Code: 0000000 000010 00001 010 01101 0000011

STORE (SW) instruction reads the lower 4 bytes of your source register rs1 and stores them into memory at the address given in the destination operand

WB: Register Write Back

The Register Write Back (WB) stage is the final step in the execution of an instruction in the RISC-V pipeline. During this stage, the result of the instruction's execution is written back to the register file, making the result available for future instructions. The WB stage is essential for ensuring that the computations performed by the processor are correctly stored and accessible.

Once the data is selected, it is written to the specified destination register (rd). The register file is updated to reflect the new value. The control signals ensure that the correct register is updated with the correct data.

Example: ADD rd, rs1, rs2 In the WB stage, the result from the ALU is written back to the destination register rd.

Example: LW rd, offset(rs1) In the WB stage, the data read from memory is written to the destination register rd.

TASK III

Installation of required softwares GTKwave,iverilog.

To install iverilog

  git clone https://github.com/steveicarus/iverilog.git
  cd iverilog
  sh autoconf.sh //To configure the iverilog in your local repository run the following command. 

Autoconf in root…// shown succesfull else try the following command and repeat the above steps

sudo apt-get install autoconf

Then configure the files

  ./configure

Finally install GTKwave and iverilog

     //sudo apt-get install package_name in ubuntu

   sudo dnf install flex 
   sudo dnf install gcc
   sudo dnf install bison
   sudo dnf install g++
   sudo su
   make install
   sudo dnf install iverilog
   sudo dnf install gtkwave 

then we are set to go

use to clone the RISC-V core repository

 git clone https://github.com/vinayrayapati/iiitb_rv32i
 cd iiitb_rv32i

now in the codes of the RISC-V repo we get to see the memory (the instructions in the memory)

it is as given in the below HTML TABLE

Instruction Hexadecimal Binary
add r6, r1, r2 32'h02208300 0000_0010_0010_0000_1000_0011_0000_0000
sub r7, r1, r2 32'h02209380 0000_0010_0010_0000_1001_0011_1000_0000
and r8, r1, r3 32'h0230a400 0000_0010_0011_0000_1010_0100_0000_0000
or r9, r2, r5 32'h02513480 0000_0010_0101_0001_0011_0100_1000_0000
xor r10, r1, r4 32'h0240c500 0000_0010_0100_0000_1100_0101_0000_0000
slt r11, r2, r4 32'h02415580 0000_0010_0100_0001_0101_0101_1000_0000
addi r12, r4, 5 32'h00520600 0000_0000_0101_0010_0000_0110_0000_0000
sw r3, r1, 2 32'h00209181 0000_0000_0010_0000_1001_0001_1000_0001
lw r13, r1, 2 32'h00208681 0000_0000_0010_0000_1000_0110_1000_0001
beq r0, r0, 15 32'h00f00002 0000_1111_0000_0000_0000_0000_0000_0010
add r14, r2, r2 32'h00210700 0000_0000_0010_0001_0000_0111_0000_0000
bne r0, r1, 20 32'h01409002 0001_0100_0000_1001_0000_0000_0000_0010
THE OVERALL waveform for the above table is given below

for the waveform marked in purple 0->ADD,1->SUB,2->AND,3->OR,4->XOR,5->SLT,0->ADDI,1->LW,0->SW,0->BEQ

The BEQ is given here as it dint fit there;

REG[0] <= 32'h00000000;
REG[1] <= 32'd1;
REG[2] <= 32'd2;
REG[3] <= 32'd3;
REG[4] <= 32'd4;
REG[5] <= 32'd5;
REG[6] <= 32'd6;

Let's compute the ALU outputs for each instruction based on these initial values.

  1. add r6, r1, r2 (32'h02208300):

    r6 = r1 + r2 = 1 + 2 = 3
    ALU_OUT = 3
    
  2. sub r7, r1, r2 (32'h02209380):

    r7 = r1 - r2 = 1 - 2 = -1 (in 32-bit signed integer, this is 0xFFFFFFFF)
    ALU_OUT = 0xFFFFFFFF
    
  3. and r8, r1, r3 (32'h0230a400):

    r8 = r1 & r3 = 1 & 3 = 1
    ALU_OUT = 1
    
  4. or r9, r2, r5 (32'h02513480):

    r9 = r2 | r5 = 2 | 5 = 7
    ALU_OUT = 7
    
  5. xor r10, r1, r4 (32'h0240c500):

    r10 = r1 ^ r4 = 1 ^ 4 = 5
    ALU_OUT = 5
    
  6. slt r11, r2, r4 (32'h02415580):

    r11 = (r2 < r4) ? 1 : 0 = (2 < 4) ? 1 : 0 = 1
    ALU_OUT = 1
    
  7. addi r12, r4, 5 (32'h00520600):

    r12 = r4 + 5 = 4 + 5 = 9
    ALU_OUT = 9
    
  8. sw r3, r1, 2 (32'h00209181):

    ALU_OUT = r1 + 2 = 1 + 2 = 3
    (This instruction does not write to a register, it stores the value of r3 at address ALU_OUT)
    
  9. lw r13, r1, 2 (32'h00208681):

    ALU_OUT = r1 + 2 = 1 + 2 = 3
    (This instruction loads the value from address ALU_OUT into r13, assuming the value at DM[3] is 0)
    
  10. beq r0, r0, 15 (32'h00f00002):

    ALU_OUT = NPC + 15 = Current PC + 15 (Branch taken because r0 == r0)
    
  11. add r14, r2, r2 (32'h00210700):

    r14 = r2 + r2 = 2 + 2 = 4
    ALU_OUT = 4
    
  12. bne r0, r1, 20 (32'h01409002):

    ALU_OUT = NPC + 20 = Current PC + 20 (Branch taken because r0 != r1)
    

Summary Table

Instruction ALU Output
add r6, r1, r2 3
sub r7, r1, r2 0xFFFFFFFF
and r8, r1, r3 1
or r9, r2, r5 7
xor r10, r1, r4 5
slt r11, r2, r4 1
addi r12, r4, 5 9
sw r3, r1, 2 3
lw r13, r1, 2 3
beq r0, r0, 15 Current PC + 15
add r14, r2, r2 4
bne r0, r1, 20 Current PC + 20

TASK IV

Why Do We Do All This?

We delve into the intricacies of VLSI (Very-Large-Scale Integration) design flow and processor workings to understand the fundamental aspects of how processors are constructed and operate. Additionally, exploring the relationship between VLSI and embedded systems helps us realize that these two fields complement each other seamlessly, with VLSI providing the hardware framework and embedded systems bringing them to life with software functionality.

Updated Pinout Diagram for VSD SQUADRON Mini

Below is the updated pinout diagram for the VSD SQUADRON Mini, which is essential for our ongoing projects. This updated version was created by referring to the original image and the repository linked below.

VSD SQUADRON Mini Pinout diagram Pinout Work Final Pinout Image

You can find the pinout diagrams at this link.

Simplifying CH32V Development Using Arduino Studio and implementation of Memory Game using Arduino Studio

Serial Number Item Quantity
1 LEDs 4
2 Jumper wires 1 set
3 4-pin push buttons 4
4 VSD Squadron Mini 1

vsd pinout for ckt

refer codes.ino for the codes

While my initial plan was to use an HC-05 Bluetooth module to send analog values to my phone, due to resource constraints and time limitations, I pivoted to creating a memory game using the VSD SQUADRON Mini board. The memory game is a small, fun project that showcases the board's capabilities.

Connecting VSD SQUADRON Mini to Arduino Studio

Here's a guide to connect your VSD SQUADRON Mini to Arduino Studio and upload your code. This process leverages the Arduino peripherals for the CH32V00x board, which the VSD SQUADRON Mini is based on.

Step-by-Step Guide

  1. Open the Repository Visit the Arduino core CH32 repository.

  2. Copy the URL Copy the following URL for the board manager:

    https://github.com/openwch/board_manager_files/raw/main/package_ch32v_index.json
    
  3. Open Arduino Preferences Open the Arduino IDE, go to "Preferences," and paste the copied URL into the "Additional Boards Manager URLs" field.

    Preferences

  4. Boards Manager In the Boards Manager, search for "CH32V" and click install.

    Boards Manager

  5. Documentation and Examples Refer to the documentation for detailed instructions on manipulating the peripherals. You can find it here.

    The repository also contains various examples to get you started. Check out the example code:

    Example Code

the working clip

Watch the working Video

Video 1

Watch the video

Video 2

Watch the video

About

VSDSquadraonMini_Research_intern_repo {I made the pinout diagram for the squadron mini :) } (for documenting/accounting the progression of the internship)

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages