Parallel Tetris

download Parallel Tetris

of 19

Transcript of Parallel Tetris

  • 8/7/2019 Parallel Tetris

    1/19

    Parallel Tetris

    Introduction

    The aim of this project was to create a 2 player version of the popular game Tetris. The

    idea was to have each player playing the game on his own screen using the the PS/2

    Keyboard for input and at the same time his play would influence the play of hisopponent. By that I mean that when a player cleared lines on his game his opponent

    would go up a predefined number of lines (where each line was a random sequence of

    blocks) in his game. To add to this each player would be able to to view the state of his

    opponents game on his own screen enabling him to make informed decisons in his play.For this I used two Altera De2 Boards which were communicating over the serial port.

    The motivation behind this project was that I wanted to do a project which had a visual

    component to it and utilised a variety of the resources offered by the DE2 Board. I also

    wanted to do a project where some element of networking was involved. The design of agame with communication over the serial port accomplished all of these goals and helped

    me learn how to use a variety of components on the Altera Board.

  • 8/7/2019 Parallel Tetris

    2/19

    High Level Design

    I started out this project by researching what projects had already been done on the FPGAon the topic. This was a good starting point as it gave me an idea of what was feasible aI

    did not use the code from any of these projects but it gave me a couple of design ideas formy own project which I would like to thank them for. Some of the things which I took

    away from these projects is that the groups had successfully managed to implement thealgorithms and game in hardware and software giving me the option of chosing which

    direction I wanted to go in with this project. Another design idea I got from these projects

    was the idea of using something known as sprites which is the idea of having each of thetetris pieces predefined and then working of that definition when doing any

    transformations during the game. There are a lot of different components that were

    needed for this project to work. The following sections give an overview of thosecomponents before I get into decribing the actual design and code for the game and how

    the different components are connected together.

    VGA

    As this project is the design of a game, display is one of the most important aspects. Thisrequired a good understanding of the VGA controller so that I could modify it based on

    the needs of the game. For the working of the VGA I used the bookRapid PrototypingOf Digital Systems (SOPC Edition) by James Hamblen , Tyson Hall and Michael

    Furman.I had a good understanding of the VGA controller from the previous labs butthere was one thing that I had to figure out how to do. This was to change the way the

    data was read in from the SRAM so as to get a resolution of 640*480. For this I used

    Professor Land's DE2 Harware examples as reference and a previous year Paint Brush

    Apllication Project done by Ranjani Chandrsekar and Manu Jain. I would like to thankthem for the help. Both of these pages are linked below. The basic working for this is as

    follows. The VGA controller has two 10 bit outputs which are Coord_X and Coord_Y.The SRAM takes in a 18 bit address which can be thought if as 9 bit x coordinate address

    and a 9 bit y coordinate address. The SRAM then returns a a 16 bits value stored at that

    address. This works fine when doing a 320x240 resolution, but the SRAM would run outof space doing the same color mapping on a 640x480 resolution. To get around this you

    have to reduce the color depth to 8 bits/pixel, where 3 bits are for red , 3 bits are for green

    and 2 bits are for blue. This way you essentially double your storage. To do this what you

    have to do is use the top 9 bits of Coord_X and bottom 9 bits of Coord_Y as addressesinto the SRAM. Then you use the LSB of Coord_X to choose between which half of the

    16 bit data from SRAM to use as input into the VGA controller

    .

  • 8/7/2019 Parallel Tetris

    3/19

    PS/2 KEYBOARD

    The next important component that I needed to research and incorporate into the design

    was the PS/2 keyboard. This is a very important component as well as this was what Iwas using for the joystick esentially.I used the bookRapid Prototyping Of Digital

    Systems (SOPC Edition) by James Hamblen , Tyson Hall and Michael Furman againin order to learn about the way the keyboard works. From reading the book I saw how thekeyboard keys were all uniquely identified by their scan codes which are listed as a table

    in the book. I used a verilog module from online which has the vhdl equivalent given in tI

    adapted their module with my project and had it so that I could read the keyboard scan

    codes when I pressed a key and was able to verify that it was working by comparing thecodes to those given in the book mentioned above. I will talk about how I used this in the

    overall design to detect key presses in the game when I discuss the design and code in the

    later sections.

    RS-232 Serial PortAs I was doing a parallel tetris I needed a way to communicate between the two boards. I

    used the serial port on the DE2 Board as it was it was fast enough to handle the amount

    of data transfer that was invovled and I had experience working with serialcommunication.As I was just using the basic features I just used the ground , receive and

    transmit port on the DE2 serial port. I will discuss the code and the setup later but the one

    thing that needed to be done in order for the connection to work was that the receive andtransmit pins needed to be switched when connecting the two boards. Ill mention this

    again when I describe the setup to run the actual project.

  • 8/7/2019 Parallel Tetris

    4/19

    Block Diagram

  • 8/7/2019 Parallel Tetris

    5/19

    The different components are the ones I discussed briefly in the above sections, a NIOS

    processor and the different pieces used to make the all the components work together

    successfully. I will describe the code in detail in the Design section but the thing to seehere is that this figure represents what runs on one of the boards. The other side runs the

    same setup and they are communicating using the serial port as shown in the figure.

    Hardware/Software Tradeoffs

    I had a couple of design decisons to make in terms of what I wanted to do in harware orsoftware. Doing the image rendering and game algorithm completely in hardware would

    offer speed but would be harder to implement and debug as compared to the NIOS. The

    NIOS provided easy compile time and debugging features not available in hardware. Soas speed was the limiting factor I did a couple of tests where I wrote to SRAM and saw

    how quick the changes were seen. As the speed was acceptable for a game to be played I

    decided to do my implementation of the game in software using the NIOS. Now, whendisplaying the opponents grid on the same monitor ,as I was doing no computation on the

    data, even though it would have been easier to do the display using the NIOS it wouldhave slowed the game down. So for displaying the opponents grid I did the logic all in

    hardware.

    Program/Hardware Design

    There are a lot of components in the project. So I will break down the project into the

    essential parts needed and explain the code for them.As most of the game design is donein software the first thing to show is the SOPC builder design and components which

    were also seen in the Block Doagram section above. This will be a good reference to

    explain the code for the different components.

  • 8/7/2019 Parallel Tetris

    6/19

    NIOS

    First I just wanted to give a brief description of the NIOS I used. As this project was notgoing to require significant portion of the boards logic elements I decided to go with the

    NIOS II/f in the SOPC builder which has a lot more features and is faster. This is a 32-bit

  • 8/7/2019 Parallel Tetris

    7/19

    RISC processor with a 4kb instruction cache and a 2 kb data cache. It also has branch

    prediction and some other features. As I was using SDRAM for the program which is 8

    Mb, memory usage would not an issue. I inclued a jtag_uart compnent as it enables printstatements which help in debugging. The following sections explain the design

    Writing to SRAMAs mentioned before the SRAM now has data stored as 8 bits/pixel. To write the SRAM I

    used the function writesram which is given below.This was taken from the Paint BrushApplication which I mentioned earlier and linked.

    This function basically drives the buses for the x coordinate , y coordinate and data to be

    written to the SRAM. The hardware then uses the top nine bits of the outputxcoord from

    the NIOS concatenated with the bottom 9 bits of the outputycoord as the address at whichto write in the SRAM. The data to be written as you would expect is the

    outputsramdatabus from the NIOS. The thing to be careful about is that when you write

    to SRAM you have to delay for some cycles as the SRAM only gets the value if the VGAcontroller is not accessing the SRAM. This is same as making sure that the Hsync and

    Vsync signals from the VGA are not high. There are a number of ways to do this but i

    used the way which was used in the Paint Brush Application project which is to have adelay() function that counts to 150. Another small design trick that I used from the Paint

    Project was that when you loop to write pixel values to a small area of the screen you

    increment the x coordinate by 2 as you are writing 2 pixel values with every write. To

    write 2 pixels in one value, you write one value, shift the variable left by 8 bits and thenOR with the second value. I used this for my initializescreen() function which I adapted

    from the Paintbrush Application project.

    Game DesignNow that I had figured out how to write to the screen using the NIOS to get a 640x480

    resolution I had to design the basic tetris pieces. I started out the design by realising that

    each tetris piece can be broken down into 4 smaller squares. So first I decided how big I

    wanted to make the small square and how big I wanted the playing grid to be. I decidedto make the small square 20 pixels x 20 pixels and the playing grid 20 x 10 which

    essentially means a grid of 200 small squares. The following figure illustrates this point.

  • 8/7/2019 Parallel Tetris

    8/19

    Now that I had decided this, I wrote a createunit() function which takes an x coordinatevalue, y coordinate value and a color as inputs and draws a 20x20 pixel square with the xand y coordinates as the center of the square.

    Next design decison was to decide how to represent a tetris piece. I decided on having a

    struct coordinate which which has an x coordinate and y coordinate field. Then I made a

    tetris_piece which had 4 coordinate structs defining the locations of the 4 small squaresthat make up a tetris piece. It then had a type field which identifies what kind of tetris

    piece it is as there are seven distinct type of tetris pieces. There was a state field to keep

    track of the orientation of the piece which helps with figuring out how to rotate the piece.The final field was a color field as each piece was a different color. Now that I had a

    struct defining a piece I wrote a function draw which took a struct tetris_piece as inputand drew the piece as defined by the coordinates on the screen.

    Tetris Pieces Design

    Now that I had the basic struct for a piece and a function to draw the pieces I decided to

    define a 7x11 array called piecessprites in which each row defines one of the 7 distinct

    tetris piece. The 11 values are the 4 pairs of x-y coordinates that define a piece, the typerepresenting which piece it is, the state which the piece first starts out in and finally the

    color of the piece. These arrays are used to populate the fields of a tetris_piece struct. The

    figure below shows the 7 pieces and what their different possible orientations are. I havealso attached the link for the figure from wikipedia.

  • 8/7/2019 Parallel Tetris

    9/19

  • 8/7/2019 Parallel Tetris

    10/19

    There is an important point to mention. Before I was able to make the the arrays and

    define the coordinates for the pieces I had to pick the regions on the screen where I was

    going to display the players grid, the region where the next piece was displayed, theopponents grid and the region to display the players score. It was important to decide the

    regions as the arrays defined the starting position of the piece when the actual game was

    played. So it was important to know where the new generated piece was supposed to startdropping down from. Before I talk about the functions to change the position of the piece

    there was one function I wanted to explain. As I was doing the drawing of pieces by

    writing to memory, I wanted to minimize the number of writes to memory when theposition of the piece changed. For this I wrote a function drawpiece_tnext which takes in

    the struct tetris_piece representing the piece at time t-1 and the piece at time t. This

    function then compares the coordinates of both the pieces and erases only those squares

    for the piece at time t-1 that dont overlap with the piece at time t + 1. Similarly it drawsonly those squares for the new piece which were not there in the piece at time t -1. This

    helps speed up the process because if for example the piece was a square and you try and

    rotate it, this function doesnt waste time first erasing the old piece and then redrwaing it

    at the same place. It leaves the piece as it is.

    Piece Movement Functions

    Now that I had the functions for drawing the pieces and the definitions of the pieces I had

    to write the movement functions. The basic ones were moveleft , moveright andmovedown which took in the current piece which is a tetris_piece struct and returns a

    modified tetris_piece struct with the appropriate coordinates. For example, the

    movedown function takes the original 4 coordinates which define the piece and add 20 tothe y value of each of the 4 coordinates. The reason you add 20 is because each square in

    the grid is 20x20 pixels. So if you move down one square the y coordinate value

    increases by 20. This similar logic is applied to moveleft and move right as well with thex coordinate values changing in that case. The tricky function was the rotate function aswhat happens depends on the previous state and the type of piece . This is where the

    original tetris piece struct definition was very important as it simplifies this function. For

    this function the input is again the current tetris_piece struct. The function checks whatthe type of the piece is and what the current state is. When I say current state I mean the

    orientation of the piece as were seen in the tetris pieces picture earlier. To get the

    rotations right I drew a grid and saw what the changes in the piece would be when itrotated and then modified the coordinates in the function appropriately. Similary I

    updated the state of the piece every time it is rotated. The number of states depended on

    the number of orientations the piece could have. To give an example of how this would

    work, assume that the piece was a T and I defined this orientation to be state 0. Let thecoordinates defining this piece be (0,0) , (0,1) , (1,1) , (0,2). When this piece is rotated the

    coordinates become (-1,-1),(0,1) ,(0,0) and (1,1) and the state becomes 1.As I remember

    what I define as a particular state using careful coordinate updates I got the correctrotations for the game.

  • 8/7/2019 Parallel Tetris

    11/19

    User Input

    As I mentioned in an earlier section, the user input is through the PS/2 Keyboard. The

    keys used by the game were up,down,left, right and spacebar.Left,right and down movethe piece by one small square in the grid in the appropriate direction. The spacebar key

    makes the block go all the way down till it collides with a piece or the bottom. In thissection I will describe how I read a particular keyboard input and interpreted it. Therewere a couple of things I had to do in hardware and in software to make the keyboard

    work. First I will describe the harware changes. As I had mentioned earlier I used a

    Keyboard module which had been adapted from Digital Sysytems book I had mentioned

    earlier. What this module does is that whenever a key is pressed it generates its ownclocks and shifts in the bits of the scan code which uniquely identify a key. Now this

    scancode is what is eventually read by the NIOS and then interpreted as the appropriate

    key. The problem with this for me was that if some one was pressing the keycontinuously then the bits being shifted in were continuously changing and the NIOS

    would not be able to figure the key out as there would be a lot of bit combinations for the

    same key. To get around this I used the scan ready clock generated by the keyboardmodule which goes high when it is shifting in a new set of bits. This for a particular key

    press went high 4 times. So I kept a count register which counted till it was 4 and then

    incremented a count1 register by 1 and reset count to 0. Now I assigned a register calledkeyscanreg the current scancode value it saw only when count1 changed. I then passed

    this keyscanreg as the input into the NIOS. The reason this helped was because as the

    keyscanreg only changed when a key was pressed its value would not constantly change

    as new boits shifted in. This reduced the number of possible scan code values that couldbe read by the NIOS down to 3.The reason there are still combinations is because if a

    button is presses a couple of times really fast or kep pressed this register does change fast

    as well. In that case the NIOS might sample the value at different points of the bits being

    shifted in giving rise to the different combinations. The software part was tricky toimplement as well. The things I had to get around was that since the scancode register

    kept its value even if a key was not pressed again, I needed a way to interpret the keyonly when it had been pressed again since the last time. To get around this I used an input

    into the NIOS called keycounter. I then kept a currentcount and previouscount variables.

    The keycounter input is the count1 register I had mentioned earlier as that updates only

    when a key is pressed. So in my game when I read a key I assign the currentcount thecount1 value and then compared it to previouscount. If it is greater than previouscount

    then I interpret the key and take action. After that I set previouscount and currentcount

    equal to each other. This is seen in tetris.c file linked later.The next problem I had wasthat I needed a way to be able to record multiple key presses or if a key was being held

    down. To solve this problem I ran a loop that executed 30 times, and in each loopiteration I interpret the key and take the appropriate action. I ran the loop 30 times as thatnumber gave the user time for enough distinct key presses so as to make the game

    realistic as you should ideally be able to move across the entire screen before moving

    down even one block. The problem to doing this is that the scancode that is read in couldnow be more that one value as I was now accounting for a key having been held down or

    it being pressed very fast. To get around this I used print statements in the loop at the

    point where the currentcount is evaluated to be greater than the previouscount signalling

  • 8/7/2019 Parallel Tetris

    12/19

    a key press. Printing the keyscan code as seen by the NIOS at this point enabled me to

    see the different combinations for the keys the NIOS was seeing and I was able to use

    this in the cases for deciphering a key. These were the tricks I used for user input andmaking the response quicker.

    Serial PortI want to describe the how the serial port is used using by the NIOS before describing

    how the game algorithm works. As mentioned earlier I added a RS-232 UART Module tothe NIOS using the SOPC builder. The UART basically raises an interrupt which I

    connected to the IRQ 1 line. So everytime there is data that comes in I had a function

    serialinterrupt that handle the data read. There are two things you do to make this work.First is registering the registering the IRQ 1 line and provding the function to go to for

    handling the interrupt. This is done with the following code.

    alt_irq_register(UART1_IRQ, (void*)&count, serialinterrupt );

    The way you read data is with the following code

    IORD_ALTERA_AVALON_UART_RXDATA(UART1_BASE). Writing to the serial

    port is similar where the code is

    IOWR_ALTERA_AVALON_UART_TXDATA(UART1_BASE, data). The tricky

    part with the write when you do multiple writes is that you have to wait till the UART isready before you can write to the UART again. So I had to read the NIOS forums to

    figure out that you have to wait till the ready to transmit bit in the status register of the

    UART is 1 before wrting again. You can do this by looping and checking the bit andexiting the loop when it was 1. The code for that is given by

    while((IORD_ALTERA_AVALON_UART_STATUS(UART1_BASE) & 0x040) !=

    0x040){ ;}. The AND with 0x040 is because the status register bit 7 is the transmit readybit.

    Playing Grid

    One last thing to describe before getting into the actual game algorithm is to describe

    how the mapping of the pieces is done to the actual grid and state of the game ismaintained. As mentioned earlier the playing grid is 20x10 small squares. As I picked the

    region for the grid I knew the coordinates for the 4 corners of the 20x10 rectangle. What I

    decided to do was to keep a 20x10 array in the actual game program to represent the grid,

    where if the value in the array was 1, that meant that the piece was occupied and if it was0 then it was not. This is how I decided to maintain the state of the game. There was a

    tricky part in terms of the the coordinates though. Now in the actual VGA monitor

    coordinates the X coordinates is the horizontal line, but in the array the x represents thecolums. So I wrote a coor_change function given below.

    struct coordinate coord_change(struct coordinate t9){

  • 8/7/2019 Parallel Tetris

    13/19

    struct coordinate output ;

    output.x = (t9.y - 50)/20;

    output.y = (t9.x - 70)/20;

    return output ;}

    The reason the transformations work like this is because the top left square in the grid isthe [0][0] index in the array. As i started my playing region at x = 60 and y = 40, the

    coordinates for the center of the first square is x = 70 and y = 50. Thats why this gives a

    0,0 output if put into the function. Also notice that if the y coordinate of screencoordinates change the x coordinate of the array changes.This is because as I mentioned

    earlier the y coordinates on the screen now represent the rows in the array. This is the

    basic structure that was used for the grid and will be mentioned in the game algorithm

    and collison detection.

    Game algorithm

    The basic game algorithm steps are listed below

    1.Outer Loop checks if gover veriable is set. If it is game is over. If not then set current

    piece to be the next piece. Set nextpiece to be one of the seven pieces chosen randomlyusing the rand() function.Display the current and the next piece.

    2.Inner loop runs till a collison is detected. Will discuss how collison detection is done in

    next section.Till collison is not detected read the user input using the loop discussed

    earlier. Update the currentblock based on user input and what is an acceptable movebased on the grid occupancy. Once done with reading user input move the block down by

    one small square. If there is a collison then update the state of the grid occupancy by

    setting the value to 1 in the array for the indexes which the coordinates of the currentblock map to. So for example if coordinate is (70,50) set the array value at (0,0) to 1.

    3.Once there is a collison and you exit the inner loop update the grid occupancy state by

    clearing the lines which have been made. I did this by having a temp 20x10 array. I then

    took the current grid state array and copied only those rows into the temp array whichwerent full. I then filled the rest of the rows with 0 values as that represents no blocks. I

    kept track of the number of rows that I didnt copy over as those represented the lines

    made by the player. This variable is what I used to update the current score of the player.

    4.Now that I had an updated state, I had to check if the other player had made a line. I didthis by reading the input into the Nios which was othermadeline.I set this line in the

    serialinterrupt function based on the data I receive from the other player. If the other

    player did make a line (can be only 1,2,3 or 4) I create another grid array calledtempgrid2 where I fill the number of lines the other player made starting bottom up with

  • 8/7/2019 Parallel Tetris

    14/19

    1 or 0 picked using the rand function.Then I fill the rest of the lines with the values from

    the tempgrid1 which had the state of the system once the lines were cleared.

    5. Now that I had the final updated state it was time to write memory and actually updatethe screen. The trick here is that you dont want to update memory locations which keep

    their values after the update. So what I did was I looped through the tempgrid2 array andthe original state before the updates which is represented by tempgrid, and updated

    tempgrid for only those locations that were different from tempgrid. At the same timethat I updated tempgrid, I also updated the SRAM.

    6.Now came the tricky part. I had to send the state of the grid across to the other player.

    So what I did was I created 36 variables where each variable represented 5 bits of the

    current state of the grid. Remember that each value in the grid can only be a 1 or a 0. Inthe loop I basically OR'ed the variable with the bit and then shifted the variable left by

    one. This way the variables held the bit values in the order they would be seen on the

    grid. Once I had these variables I wrote each of these variables into the serial port using

    the functions I had described earlier. As I knew what order I sent them in I knew whatorder I would receive in them. I then sent an 0xff byte which I will explain the

    importance of later. Finally I sent the value of how many lines the player made which isvariable used to update the score.

    7. The final step is checking whether the game was over. To do this I check if any of the

    squares in the second row are filled. If they are then I exit the outer loop and the game is

    over.

    I will discuss how the data is interpreted when received by the serial port and how thescreen is drawn for the opponent in the VGA Controller section.

    Collison Detection

    In this section I will describe how I did collison detection at various stages of the game.The first time when this is needed is when updating the piece on a user input. What I do

    on a user input is that I create a temp tetris_piece struct which gets the updated

    coordinates based on the user input. If the coordinates lie outside the playing grid, or if

    for the 4 coordinates the corresponding entry in the tempgrid array which holds thecurrent state of the grid is one then I dont update the piece otherwise I do. In the case

    when spacebar is pressed the update of the coordinates is not as simple. For each different

    x coordinate in the tetris piece I see what the highest y coordinate can be before there is a

    filled piece in the grid. I then take the minimum of these y coordinates and update thecurrent piece's coordinates relative to that. These were all collison detections for the user

    input updates. Once I am done reading the user input I have to check again for collisons ifthe piece was to move down by one square. First for the different x coordinates that

    define the piece I find the maximum y coordinate. Then for each of the these x,y pair I

    see in the tempgrid array if the square below is filled or not. If any of these are filled then

    there is a collison. If not then I check if the max y coordinate of the piece is at the bottomof the grid. If it is then there is a collison. If neither of these conditions cause a collison

  • 8/7/2019 Parallel Tetris

    15/19

    then I move the piece down by one square.The collison detection is made easier by

    picking a proper way to represent the state of the grid and spreading out the collison

    detection logic.

    VGA Controller

    The VGA controller I started out with was the one I referenced earlier in the report which

    was one of Professor Land's DE2 hardware examples. There are changes I had to make to

    the controller in order to make this project work. I will break down the changes based onthe section of the screen they affected. There are 4 distinct regions on the VGA monitor

    for this project. The players grid, the grid to display the opponents status, the section

    displaying the next piece and the section displaying the score of the player. The playersgrid and the next piece area were both drawn using the inputs from SRAM. This was

    already implemented and I didnt have to change that logic. For the players score display I

    knew what coordinate range corresponded to that area. So I used if statements in theVGA controller to know when the contrller was in the area. To display the score I wrote a

    hexout module in the VGA controller which took in a 4 bit value and gave out a 7 bitoutput which represented which segments should be on similar to a seven segment

    display. I used the iscoreofplayer input into the controller which was an output from theNIOS, and used the hexout module and logic to figure out what segments should be on

    for different digits. I then used if statements and the outputs of the hexout module to draw

    to a particular coordinate range for each segment which I picked.An example of this ifstatement is given below.

    if((((H_Cont - X_START) > 280 ) && ((H_Cont - X_START) < 300)))

    begin

    if(((V_Cont - Y_START) == 150))

    beginCur_Color_R 420 ) && ((V_Cont - Y_START) < 440)) &&

    (((H_Cont - X_START) > 380 ) && ((H_Cont - X_START) < 400)) )

  • 8/7/2019 Parallel Tetris

    16/19

    begin

    Cur_Color_R

  • 8/7/2019 Parallel Tetris

    17/19

    communication worked well. I was also able to successfully display the opponents grid

    using the data received over the serial port successfully. The game can be played as a

    single player and two player game. Though the game was fully functional there weresome glitches which I saw. For the VGA display which was done from the SRAM, there

    are times when pieces leave behind a few pixels when they were updated. These specs

    were cleared when another piece went over them and they did not interfere with the logic.I was not able to figure out why this happened as I made sure in the code that I cleared

    the entire block when it moved. I could only think of the reason being that sometimes the

    value was not successfully written to SRAM by the NIOS. Another glitch was theresponsiveness of the keyboard input. I got the delay between a key press to update down

    to an acceptable level but it still could have been better. There are times when a key press

    does not get acknowledged and requires another press for an update. This is because of

    the way I did my user input where I was reading the scancode from the NIOS. I feel as ifdoing the user input that way leads to cases where an update is missed because the NIOS

    might read a little early or too late. In most cases the update is fine but there are some

    glitches as mentioned above.

    Despite the glitches I believe that the project results met my expectations. I was able toachieve the functionality and goals that I had set when I started the project. Despite that

    there are definitely things that I would do differently if I has the chance to redo the

    project. The first thing I would do would be to have the user input be detected on aninterrupt and using a queue to service the requests. This would give better responsiveness

    and accuracy improving the gaming experience. The second thing I would do would be to

    make the entire VGA display using NIOS outputs and logic in the VGA controller. Thereason I would do this is because it would make the updates a lot quicker and would look

    better.

    This project was a lot of fun to work on and I learned a lot while working on it. Most ofthe C code for the NIOS and the VGA controller logic was written by me. The placeswhere I referenced or used designs I have linked the sources in the report. I will also

    mark the sections in the code that I wrote to make it clearer.

    IMAGES:

    FIG:1

  • 8/7/2019 Parallel Tetris

    18/19

    FIG:2

    FIG:3 e-mail:[email protected]

    FIG:4

  • 8/7/2019 Parallel Tetris

    19/19