RISC-V Mini Game Console

Overview

The Handheld Gaming Console project integrates a RISC-V microcontroller to create a portable gaming system featuring a OLED display and tactile buttons. This console allows users to play classic games like Snake and Pong, with the RISC-V microcontroller managing game logic, user input, and rendering graphics. Additionally, a sound module provides audio feedback to enhance the gaming experience. This project demonstrates the innovative use of RISC-V technology in creating an immersive and interactive gaming solution.

Components Required

  1. VSDSquadron Mini
  2. Oled Display
  3. Push buttons (5)
  4. Capacitors (100nF, 10uF)
  5. Coin Battery ( CR2032)
  6. Resistors (1k, 2k, 3k, 20k, 8k)
  7. Buzzer (MLT-5030)
  8. Hreader pins
  9. BJT ( MMBT3906)
  10. Switch

Circuit Connections

The VSDSquadron Mini RISC-V development boards features a RISC-V SoC with the following capabilities:

  • On-board 24MHz RC oscillator
  • 3 groups of GPIO ports, totaling 15 I/O ports
  • USART, I2C, and SPI
  • UART implemented on USART
  • 2KB SRAM for volatile data storage, 16KB CodeFlash for program memory
  • On-board Programmer.

The circuit connections are as follows:

  • PA2 GPIO Pin is connected to one of the push bottons which controls the turn on/off of a game.
  • PA1 is connected to the buzzer.
  • PC4 is connected to the game controlling push buttons
  • PC2 and PC1 act as SCL(Serial Clock Line) and SDL(Seriel Data Line), these lines are used for I2C communication with OLED Display
  • And there are some VCC and GND connections.
  • Power switch connected to VCC and GND accordingly.

Table for Pin connections

Software

I made one of my most played games of my childhood which is PACMAN.

Code:

#include "driver.h"
#include "spritebank.h"

// ===================================================================================
// Global Variables
// ===================================================================================
uint8_t LEVELSPEED;
uint8_t GobbingEND;
uint8_t LIVE;
uint8_t INGAME;
uint8_t Gobeactive;
uint8_t TimerGobeactive;
uint8_t add;
uint8_t dotsMem[9];
int8_t dotscount;
uint8_t Frame;
enum {PACMAN=0,FANTOME=1,FRUIT=2};

// ===================================================================================
// Function Prototypes
// ===================================================================================
void ResetVar(void);
void StartGame(PERSONAGE *Sprite);
uint8_t CollisionPac2Caracter(PERSONAGE *Sprite);
void RefreshCaracter(PERSONAGE *Sprite);
uint8_t CheckCollisionWithBack(uint8_t SpriteCheck,uint8_t HorVcheck,PERSONAGE *Sprite);
uint8_t RecupeBacktoCompV(uint8_t SpriteCheck,PERSONAGE *Sprite);
uint8_t Trim(uint8_t Y1orY2,uint8_t TrimValue,uint8_t Decalage);
uint8_t RecupeBacktoCompH(uint8_t SpriteCheck,PERSONAGE *Sprite);
void Tiny_Flip(uint8_t render0_picture1,PERSONAGE *Sprite);
uint8_t FruitWrite(uint8_t x,uint8_t y);
uint8_t LiveWrite(uint8_t x,uint8_t y);
uint8_t DotsWrite(uint8_t x,uint8_t y,PERSONAGE *Sprite);
uint8_t checkDotPresent(uint8_t  DotsNumber);
void DotsDestroy(uint8_t DotsNumber);
uint8_t SplitSpriteDecalageY(uint8_t decalage,uint8_t Input,uint8_t UPorDOWN);
uint8_t SpriteWrite(uint8_t x,uint8_t y,PERSONAGE  *Sprite);
uint8_t return_if_sprite_present(uint8_t x,PERSONAGE  *Sprite,uint8_t SpriteNumber);
uint8_t background(uint8_t x,uint8_t y);

// ===================================================================================
// Main Function
// ===================================================================================
int main(void) {
  // Setup
  JOY_init();

  // Loop
  while(1) {
    uint8_t t;
    PERSONAGE Sprite[5];
  NEWGAME:
    ResetVar();
    LIVE=3;
    goto New;
  NEWLEVEL:
    if(LEVELSPEED > 10) {
      LEVELSPEED=LEVELSPEED - 10;
      if((LEVELSPEED==160)||(LEVELSPEED==120)||(LEVELSPEED==80)||(LEVELSPEED==40)||(LEVELSPEED==10)) {    
        if(LIVE < 3) {
          LIVE++; 
          for(t=0; t<=4; t++) {
            JOY_sound(80,100);
            JOY_DLY_ms(300);
          }
        }
      }
    }
  New:
    GobbingEND = (LEVELSPEED / 2);
    for(t=0; t<9; t++) dotsMem[t]=0xff;
  RESTARTLEVEL:
    Gobeactive = 0;
    uint8_t* ptr = (uint8_t*)Sprite;
    for(t=5*10; t; t--) *ptr++ = 0;
    Sprite[0].type=PACMAN;
    Sprite[0].x=64;
    Sprite[0].y=3;
    Sprite[0].Decalagey=5;
    Sprite[0].DirectionV=2;
    Sprite[0].DirectionH=2;
    Sprite[0].DirectionAnim=0;
    Sprite[1].type=FANTOME;
    Sprite[1].x=76;
    Sprite[1].y=4;
    Sprite[1].guber=0;
    Sprite[2].type=FANTOME;
    Sprite[2].x=75;
    Sprite[2].y=5;
    Sprite[2].guber=0;
    Sprite[3].type=FANTOME;
    Sprite[3].x=77;
    Sprite[3].y=4;
    Sprite[3].guber=0;
    Sprite[4].type=FANTOME;
    Sprite[4].x=76;
    Sprite[4].y=5;
    Sprite[4].guber=0;
    while(1) {
      //joystick
      if(JOY_act_pressed()) StartGame(&Sprite[0]);
      if(INGAME) {
        if(JOY_left_pressed()) Sprite[0].DirectionV = 0;
        else if(JOY_right_pressed()) Sprite[0].DirectionV = 1;
        if(JOY_down_pressed()) Sprite[0].DirectionH =1 ;
        else if(JOY_up_pressed()) Sprite[0].DirectionH = 0;
        //fin joystick
        if(TimerGobeactive > 1) TimerGobeactive--;
        else if (TimerGobeactive == 1) {
          TimerGobeactive = 0;
          Gobeactive = 0;
        }
      }
      if(Frame < 24) Frame++;
      else Frame = 0;
      if(CollisionPac2Caracter(&Sprite[0]) == 0) RefreshCaracter(&Sprite[0]);
      else {
        JOY_sound(100, 200); JOY_sound(75, 200); JOY_sound(50, 200); JOY_sound(25, 200);
        JOY_sound(12, 200); JOY_DLY_ms(400);
        if(LIVE > 0) {
          LIVE--;
          goto RESTARTLEVEL;
        }
        else goto NEWGAME;
      }
      if(Frame % 2 == 0) {
        Tiny_Flip(0, &Sprite[0]);
        if(INGAME == 1) {
          for(uint8_t t=0; t<=139; t=t+2) {
            JOY_sound((Music[t]) - 8, ((Music[t + 1]) - 100)); 
          }
          INGAME = 2;
        }
      }
      else {
        for(t=0; t<63; t++) {
          if(checkDotPresent(t)) break;
          else if(t == 62) {
            for(uint8_t r=0; r<60; r++) {
              JOY_sound(2 + r, 10); JOY_sound(255 - r, 20);
            }
            JOY_DLY_ms(1000);
            goto NEWLEVEL;
          }
        }
      }
      if((Gobeactive) && (Frame % 2 == 0)) JOY_sound((255 - TimerGobeactive), 1);
      JOY_SLOWDOWN();
    }
  }
}

// ===================================================================================
// Functions
// ===================================================================================
void ResetVar(void){
LEVELSPEED=200;
GobbingEND=0;
LIVE=3;
Gobeactive=0;
TimerGobeactive=0;
add=0;
INGAME=0;
for(uint8_t t=0;t<9;t++){
dotsMem[t]=0xff;}
dotscount=0;
Frame=0;}

void StartGame(PERSONAGE *Sprite){
if (INGAME==0) {
Sprite[1].x=76;
Sprite[1].y=3;
Sprite[2].x=75;
Sprite[2].y=4;
Sprite[3].x=77;
Sprite[3].y=3;
Sprite[4].x=76;
Sprite[4].y=4;
INGAME=1;}}

uint8_t CollisionPac2Caracter(PERSONAGE *Sprite){
uint8_t ReturnCollision=0;
#define xmax(I) (Sprite[I].x+6)
#define xmin(I) (Sprite[I].x)
#define ymax(I) ((Sprite[I].y*8)+Sprite[I].Decalagey+6)
#define ymin(I) ((Sprite[I].y*8)+Sprite[I].Decalagey)
if ((INGAME)) {    
for (uint8_t t=1;t<=4;t++){
if ((xmax(0)<xmin(t))||(xmin(0)>xmax(t))||(ymax(0)<ymin(t))||(ymin(0)>ymax(t))) {}else{ 
if (Gobeactive) {if (Sprite[t].guber!=1) {JOY_sound(20,100);JOY_sound(2,100);}Sprite[t].guber=1;ReturnCollision=0;}else{ if (Sprite[t].guber==1) {ReturnCollision=0;}else{ReturnCollision=1;}}
}}}return ReturnCollision;}

void RefreshCaracter(PERSONAGE *Sprite){
uint8_t memx,memy,memdecalagey;
for (uint8_t t=0;t<=4;t++){
memx=Sprite[t].x;
memy=Sprite[t].y;
memdecalagey=Sprite[t].Decalagey;
if ((Sprite[t].y>-1)&&(Sprite[t].y<8)) {
if ((Frame%2==0)||(t==0)||(LEVELSPEED<=160)) {
if (Sprite[t].DirectionV==1) {Sprite[t].x++;}
if (Sprite[t].DirectionV==0) {
if (t==0) {
if ((Sprite[0].y==3)&&(Sprite[0].x==86)){}else{Sprite[t].x--;}
}else{Sprite[t].x--;}
}}}
if (CheckCollisionWithBack(t,1,Sprite)) {
if (t!=0) {Sprite[t].DirectionV=JOY_random()%2;}else{ Sprite[t].DirectionV=2;}
Sprite[t].x=memx;
}
if ((Frame%2==0)||(t==0)||(LEVELSPEED<=160)) {
if (Sprite[t].DirectionH==1) {if (Sprite[t].Decalagey<7) {Sprite[t].Decalagey++;}else{Sprite[t].Decalagey=0;Sprite[t].y++;if (Sprite[t].y==9) {Sprite[t].y=-1;}}}
if (Sprite[t].DirectionH==0) {if (Sprite[t].Decalagey>0) {Sprite[t].Decalagey--;}else{Sprite[t].Decalagey=7;Sprite[t].y--;if (Sprite[t].y==-2) {Sprite[t].y=8;}}}
}
if (CheckCollisionWithBack(t,0,Sprite)) {
if (t!=0) {Sprite[t].DirectionH=JOY_random()%2;}else{Sprite[t].DirectionH=2;}
Sprite[t].y=memy;
Sprite[t].Decalagey=memdecalagey;
}
if (t==0) {
if (Frame%2==0) {
if (Sprite[t].DirectionH==1) {Sprite[t].DirectionAnim=0;}
if (Sprite[t].DirectionH==0) {Sprite[t].DirectionAnim=(2*3);} 
if (Sprite[t].DirectionV==1) {Sprite[t].DirectionAnim=(3*3);}
if (Sprite[t].DirectionV==0) {Sprite[t].DirectionAnim=(1*3);}
}}else{
if ((Frame==0)||(Frame==12)) {
Sprite[t].DirectionAnim=0;
if (Sprite[t].DirectionH==1) {Sprite[t].DirectionAnim=0;}
if (Sprite[t].DirectionH==0) {Sprite[t].DirectionAnim=2;}
}}
if (t==0) {
if (Frame%2==0) {
if (Sprite[0].switchanim==0) {
if (Sprite[0].anim<2) {Sprite[0].anim++;}else{Sprite[0].switchanim=1;} 
}else{
if (Sprite[0].anim>0) {Sprite[0].anim--;}else{Sprite[0].switchanim=0;}  
}}}else{
if ((Sprite[t].guber==1)&&(Sprite[t].x>=74)&&(Sprite[t].x<=76)&&(Sprite[t].y>=2)&&(Sprite[t].y<=4)) {Sprite[t].guber=0;}
if  (Frame%2==0) {
if (Sprite[t].anim<1) {Sprite[t].anim++;}else{Sprite[t].anim=0; } 
}}}}

uint8_t CheckCollisionWithBack(uint8_t SpriteCheck,uint8_t HorVcheck,PERSONAGE *Sprite){
uint8_t BacktoComp;
if (HorVcheck==1) {
BacktoComp=RecupeBacktoCompV(SpriteCheck,Sprite); 
}else{
BacktoComp=RecupeBacktoCompH(SpriteCheck,Sprite);}
if ((BacktoComp)!=0) {return 1;}else{return 0;}}

uint8_t RecupeBacktoCompV(uint8_t SpriteCheck,PERSONAGE *Sprite){
uint8_t Y1=0b00000000;
uint8_t Y2=Y1;
#define SpriteWide 6
#define MAXV (Sprite[SpriteCheck].x+SpriteWide)
#define MINV (Sprite[SpriteCheck].x)
if (Sprite[SpriteCheck].DirectionV==1) {
Y1=(back[((Sprite[SpriteCheck].y)*128)+(MAXV)]);
Y2=(back[((Sprite[SpriteCheck].y+1)*128)+(MAXV)]);
}else if (Sprite[SpriteCheck].DirectionV==0) {
Y1=(back[((Sprite[SpriteCheck].y)*128)+(MINV)]);
Y2=(back[((Sprite[SpriteCheck].y+1)*128)+(MINV)]);
}else{Y1=0;Y2=0;}
//decortique
Y1=Trim(0,Y1,Sprite[SpriteCheck].Decalagey);
Y2=Trim(1,Y2,Sprite[SpriteCheck].Decalagey);
if (((Y1)!=0b00000000)||((Y2)!=0b00000000) ) {return 1;}else{return 0;}
}

uint8_t Trim(uint8_t Y1orY2,uint8_t TrimValue,uint8_t Decalage){
uint8_t Comp;
if (Y1orY2==0) {
Comp=0b01111111<<Decalage;
return (TrimValue&Comp);
}else{
Comp=(0b01111111>>(8-Decalage));
return (TrimValue&Comp);
}}

uint8_t ScanHRecupe(uint8_t UporDown,uint8_t Decalage){
if (UporDown==0){
return 0b01111111<<Decalage;}
else{
return 0b01111111>>(8-Decalage);
}}

uint8_t RecupeBacktoCompH(uint8_t SpriteCheck,PERSONAGE *Sprite){
uint8_t TempPGMByte;
if (Sprite[SpriteCheck].DirectionH==0) {
uint8_t RECUPE=(ScanHRecupe(0,Sprite[SpriteCheck].Decalagey));
for(uint8_t t=0;t<=6;t++){
if ((((Sprite[SpriteCheck].y)*128)+(Sprite[SpriteCheck].x+t)>1023)||(((Sprite[SpriteCheck].y)*128)+(Sprite[SpriteCheck].x+t)<0)) {TempPGMByte=0x00;}else{
 TempPGMByte=((back[((Sprite[SpriteCheck].y)*128)+(Sprite[SpriteCheck].x+t)])); 
}
#define CHECKCOLLISION ((RECUPE)&(TempPGMByte))
if  (CHECKCOLLISION!=0) {return 1;}
}}else if (Sprite[SpriteCheck].DirectionH==1) {
uint8_t tadd=0;
if (Sprite[SpriteCheck].Decalagey>2) { tadd=1;}else{tadd=0;}
uint8_t RECUPE=(ScanHRecupe(tadd,Sprite[SpriteCheck].Decalagey));
for(uint8_t t=0;t<=6;t++){
if (((((Sprite[SpriteCheck].y+tadd)*128)+(Sprite[SpriteCheck].x+t))>1023)||((((Sprite[SpriteCheck].y+tadd)*128)+(Sprite[SpriteCheck].x+t))<0)) {TempPGMByte=0x00;}else{
TempPGMByte=(back[((Sprite[SpriteCheck].y+tadd)*128)+(Sprite[SpriteCheck].x+t)]);
}
#define CHECKCOLLISION2 ((RECUPE)&(TempPGMByte))
if  (CHECKCOLLISION2!=0) {return 1;}
}}return 0;}

void Tiny_Flip(uint8_t render0_picture1,PERSONAGE *Sprite){
uint8_t y,x; 
dotscount=-1;
for (y = 0; y < 8; y++){ 
JOY_OLED_data_start(y);
for (x = 0; x < 128; x++){
if (render0_picture1==0) {
if (INGAME) {JOY_OLED_send(background(x,y)|SpriteWrite(x,y,Sprite)|DotsWrite(x,y,Sprite)|LiveWrite(x,y)|FruitWrite(x,y));}else{
JOY_OLED_send(0xff-(background(x,y)|SpriteWrite(x,y,Sprite)));
}}else if (render0_picture1==1){
JOY_OLED_send((back[x+(y*128)]));}}
JOY_OLED_end();
}}

uint8_t FruitWrite(uint8_t x,uint8_t y){
switch(y){
  case 7:if (x<=7) {return (fruits[x]);}break;
  case 6:if ((LEVELSPEED<=190)&&(x<=7)) {return (fruits[x+8]);}break;
  case 5:if ((LEVELSPEED<=180)&&(x<=7)) {return (fruits[x+16]);}break;
  case 4:if ((LEVELSPEED<=170)&&(x<=7)) {return (fruits[x+24]);}break;
}return 0;}

uint8_t LiveWrite(uint8_t x,uint8_t y){
if (y<LIVE) {if (x<=7) {return (caracters[x+(1*8)]);}else{return 0;}
}return 0x00;}

uint8_t DotsWrite(uint8_t x,uint8_t y,PERSONAGE *Sprite){
uint8_t Menreturn=0;
uint8_t mem1=(dots[x+(128*y)]);
if (mem1!=0b00000000) {
dotscount++;
 switch(dotscount){
  case 0:  
  case 1: 
  case 12: 
  case 13: 
  case 50:
  case 51:
  case 62:
  case 63:Menreturn=1;break;
  default:Menreturn=0;break;
}
if (checkDotPresent(dotscount)==0b00000000) {mem1=0x00;}else{
if ((Sprite[0].type==PACMAN)&&((Sprite[0].x<x)&&(Sprite[0].x>x-6))&&(((Sprite[0].y==y)&&(Sprite[0].Decalagey<6))||((Sprite[0].y==y-1)&&(Sprite[0].Decalagey>5)))) {DotsDestroy(dotscount);if (Menreturn==1) {TimerGobeactive=LEVELSPEED;Gobeactive=1;}else{JOY_sound(10,10);JOY_sound(50,10);}}
}}
if (Menreturn==1) {
if (((Frame>=6)&&(Frame<=12))||((Frame>=18)&&(Frame<=24))) {
return 0x00;
}else{return mem1;}
}else{return mem1;}}

uint8_t checkDotPresent(uint8_t  DotsNumber){
uint8_t REST=DotsNumber;
uint8_t DOTBOOLPOSITION=0;
DECREASE:
if (REST>=8) {REST=REST-8;DOTBOOLPOSITION++;goto DECREASE;}
return ((dotsMem[DOTBOOLPOSITION])&(0b10000000>>REST));
}

void DotsDestroy(uint8_t DotsNumber){
uint8_t REST=DotsNumber;
uint8_t DOTBOOLPOSITION=0;
uint8_t SOUSTRAIRE;
DECREASE:
if (REST>=8) {REST=REST-8;DOTBOOLPOSITION=DOTBOOLPOSITION+1;goto DECREASE;}
switch(REST){
  case (0):SOUSTRAIRE=0b01111111;break;
  case (1):SOUSTRAIRE=0b10111111;break;
  case (2):SOUSTRAIRE=0b11011111;break;
  case (3):SOUSTRAIRE=0b11101111;break;
  case (4):SOUSTRAIRE=0b11110111;break;
  case (5):SOUSTRAIRE=0b11111011;break;
  case (6):SOUSTRAIRE=0b11111101;break;
  case (7):SOUSTRAIRE=0b11111110;break;
}
dotsMem[DOTBOOLPOSITION]=dotsMem[DOTBOOLPOSITION]&SOUSTRAIRE;
}

uint8_t SplitSpriteDecalageY(uint8_t decalage,uint8_t Input,uint8_t UPorDOWN){
if (UPorDOWN) {
return Input<<decalage;
}else{
return Input>>(8-decalage); 
}}

uint8_t SpriteWrite(uint8_t x,uint8_t y,PERSONAGE  *Sprite){
uint8_t var1=0;
uint8_t AddBin=0b00000000;
while(1){ 
if (Sprite[var1].y==y) {
AddBin=AddBin|SplitSpriteDecalageY(Sprite[var1].Decalagey,return_if_sprite_present(x,Sprite,var1),1);
}else if (((Sprite[var1].y+1)==y)&&(Sprite[var1].Decalagey!=0)) {
AddBin=AddBin|SplitSpriteDecalageY(Sprite[var1].Decalagey,return_if_sprite_present(x,Sprite,var1),0);
}
var1++;
if (var1==5) {break;}
}return AddBin;}
  
uint8_t return_if_sprite_present(uint8_t x,PERSONAGE  *Sprite,uint8_t SpriteNumber){
uint8_t ADDgobActive;
uint8_t ADDGober;
if  ((x>=Sprite[SpriteNumber].x)&&(x<(Sprite[SpriteNumber].x+8))) { 
if (SpriteNumber!=0) { 
if (Sprite[SpriteNumber].guber==1) {
ADDgobActive=1*(4*8);
ADDGober=Sprite[SpriteNumber].guber*(4*8);
}else{
if ((((Frame>=6)&&(Frame<=12))||((Frame>=18)&&(Frame<=24)))||(TimerGobeactive>GobbingEND)) {ADDgobActive=Gobeactive*(4*8);}else{ADDgobActive=0;}
ADDGober=0;
}}else{
ADDGober=0;
ADDgobActive=0;
}
if ((INGAME==0)&&(SpriteNumber==0)) {  return 0;}     
return (caracters[((x-Sprite[SpriteNumber].x)+(8*(Sprite[SpriteNumber].type*12)))+(Sprite[SpriteNumber].anim*8)+(Sprite[SpriteNumber].DirectionAnim*8)+(ADDgobActive)+(ADDGober)]);
}return 0;}

uint8_t background(uint8_t x,uint8_t y){
return (BackBlitz[((y)*128)+((x))]);
}

Results

My game video link : https://drive.google.com/file/d/1Wr2tZUExrr649TMdLOXeVw5DllF4_PgC/view?usp=drivesdk

https://github.com/tejasopp/VSD_mini_ResearchInternship/blob/main/Game_Console.md

Registration for Ethical RISC-V IoT Workshop

Welcome to Ethical RISC-V IoT Workshop

The “Ethical RISC-V IoT Workshop” at IIIT Bangalore, organized in collaboration with VSD, is a structured, educational competition aimed at exploring real-world challenges in IoT and embedded systems. Participants progress through three stages: building an application, injecting and managing faults, and enhancing application security. The event spans from May 9 to June 15, 2024, culminating in a showcase of top innovations and an award ceremony. This hands-on hackathon emphasizes learning, testing, and securing applications in a collaborative and competitive environment.

Rules :
  1. Only for Indian Student whose college is registered under VTU
  2. Only team of 2 members can Register
  3. Use only VSDSquadron Mini resources for product development
Awards :
  1. Prize money for final 10 Team
  2. 3 Winner team’s Product will be evaluated for Incubation
  3. 7 consolation prizes
  4. Completion Certificate to final round qualifier
  5. Chance to build a Proud Secured RISC-V Platform for India

Date for Registration : 9th May - 22nd May, 2024
Hackathon Inauguration : 23rd May 2024

VSDSquadron (Educational Board)

VSDSquadron, a cutting-edge development board based on the RISC-V architecture that is fully open-source. This board presents an exceptional opportunity for individuals to learn about RISC-V and VLSI chip design utilizing only open-source tools, starting from the RTL and extending all the way to the GDSII. The possibilities for learning and advancement with this technology are limitless.

Furthermore, the RISC-V chips on these boards should be open for VLSI chip design learning, allowing you to explore PNR, standard cells, and layout design. And guess what? vsdsquadron is the perfect solution for all your needs! With its comprehensive documentation and scalable labs, thousands of students can learn and grow together.

VSD HDP (Hardware Design Program) Duration-10 Week

With VSD Hardware Design Program (VSD-HDP),  you have the opportunity to push the boundaries of what exist in open source and establish the new benchmark for tomorrow.

It will leverage your degree in Electrical or Computer Engineering to work with

  • Programmable logic
  • Analog/ digital IP
  • RISC-V
  • Architecture & microprocessors
  • ASICs and SoCs on high-density digital or RF circuit cards
  • Gain hands-on knowledge during design validation and system integration.

Sounds exciting to just get started with expert mentors, doesn’t it? But we are looking for the next generation of learners, inventors, rebels, risk takers, and pioneers.

“Spend your summer working in the future !!”

Outcomes of VSD Online Research IP Design Internship Program

  1. Job opportunities in Semiconductor Industry
  2. Research work can be submitted to VLSI International journals
  3. Participate in Semiconductor International Conference with Internship Research Work
  4. Paper Publications in IEEE Conference and SIG groups
  5. Tape out opportunity and IP Royalty
  6. Interact with world class Semiconductor designer and researchers
  7. Academic professions where more research projects are encouraged.
  8. All the above research and publication work will help colleges and institutes to improve accreditation levels.

Know More Information

VSD – Intelligent Assessment Technology (VSD-IAT)

VSD – Intelligent Assessment Technology (VSD-IAT) is expertly built training platform and is suited for designer requirements. Semiconductor companies understand the value of training automation and Engineer performance enhancement, and do not need to be convinced of the impact of a virtual platform for learning. VSD trainings are quick, relevant, and easy to access from any device at any time zone.

VSD Intern Webinars

VSD Interns made it happen !!

VSD is working towards creating innovative talent pool who are ready to develop design and products for the new tech world. VSD believes in “Learning by doing principle” , and always prepare the student to apply the knowledge learned in the workshops, webinars and courses. We always push our students to work on new designs, test it and work continuously till it becomes the best performing design. Any student who enrolls to VSD community starts working with small design and grows with us and develops a tapeout level design with complete honesty and dedication towards the Work !!

Check out VSD Interns Achievement!

VSDOpen Online Conference

Welcome to the World’s only online conference in Semiconductor Industry VSDOpen Conference. With enormous support and global presence of audience from different segments of industrial lobby and academia made a highly successful event. Evolution is change in the genetic makeup of a population over time, online conference is one kind evaluation everyone adapt soon. 

  • VSDOpen 2022 is an online conference to share open-source research with the community and promote  hardware design mostly done by the student community.
  • VSDOpen 2022 is based on the theme “How to lower the cost to learn, build, and tapeout chips ?”  , which will provide a platform to community to build stronger designs and strengthen the future of Chip design.
  • VSDOpen is envisioned to create a community based revolution in semiconductor hardware technology.
  • The open source attitude is required to bring out the talent and innovation from the community who are in remote part of world and have least access to the technologies.  And now Google support will help to bring the vision to execution by VSD team

VSD Online Course by Kunal Ghosh

VSD offers online course in complete spectrum of vlsi backend flow from RTL design, synthesis and Verification, SoC planning and design, Sign-off analysis, IP Design, CAD/EDA automation and basic UNIX/IT, Introduction to latest technology – RISC-V, Machine intelligence in EDA/CAD, VLSI Interview FAQ’s.

Current Reach – As of 2021, VSD and its partners have released 41 online VLSI courses and was successfully able to teach  ~35900 Unique students around 151 countries in 47 different languages, through its unique info-graphical and technology mediated learning methods.

Enquiry Form