I Designed My Own 16-bit CPU

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

There is a discussion on Hacker News, but feel free to comment here as well.

👍︎︎ 1 👤︎︎ u/qznc_bot2 📅︎︎ Jul 29 2022 đź—«︎ replies
Captions
after creating language in my last video i felt that wasn't challenging enough i mean who needs windows and all this modern technology when i could create something much better on my own that's why today i'm designing my 16-bit computer the astro eight they made before 16 bits not all confusing don't complain in the comments [Music] i borrowed this idea from one of my friends doorbell pro before i begin thank you so much my c-sharp video has an incredibly huge number of views and my channel went from under 400 subscribers to over 6 000 so once again thank you and let's get on with the video my computer can be broken down into a few important components the cpu the ram and the video circuitry the ram is for temporary data handling if the computer needs to keep data but perform another task first then it can just store it in ram it has 65 000 memory locations each of which stores a 16-bit word the display is an led screen is attached to dedicated video hardware which handles pixel rendering and the cpu which handles processing data and executing instructions inside the cpu are many things like the registers the multiple counters for keeping track of instructions and the arithmetic logic unit now before rushing to just throw together a bunch of components and transistors and capacitors and chips and stuff like that into one horrible mess let's actually design this thing so i decided to use logisim for the design and simulating the cpu realistically the actual cpu is fairly simple it's basically a lot of different on and off switches which allow different parts of the machine to execute and move memory and data which then produces the desired output let's first go over the instruction set of the computer the computer has 23 different instructions the first three instructions are for reading from a memory address into one of the three general purpose registers a b and c the second two instructions are for loading integer values directly into a and b next we have the read and write instructions for reading and writing to the expansion port on the computer there's a 16-bit port which ties directly into the bus and is available for any device to use next we have the store commands which store the value of either register a or register c into an address in memory then have some arithmetic commands such as add subtract multiply and divide which apply one of those operations onto the a and b registers there are three individual jump commands which are used for different reasons the first one is used to unconditionally jump to whatever address in memory the second one is jump if zero which checks if the previous arithmetic operation equaled zero if that is not the case then it will simply skip this jump command there is also jump if carry which will only jump if the previous operation had a carry for example if you add two numbers and they're large enough to have made it overflow it would only jump if that is true otherwise it would also skip this one here's some more load and store commands which are just used to access higher values that can't fit inside of 11 bit which is all that the instruction register can hold along with the actual instruction bits next two commands are for swapping register values the first one swaps a and b and the second one swaps a and c and the final command is halt this simply stops the clock and doesn't allow the computer to execute any more instructions assembling the instruction set is actually very simple you see each instruction actually corresponds to a binary value and that's just its index so it's the first one then it's number one if it's the second one it's number two and so on and so forth in binary this binary instruction code only takes up 5 bits so we have another 11 bits out of the 16 available to use for anything we want such as a memory address or any other arguments that might be used for the command so all the assembler does is replace all of these values with their binary values and convert all of the arguments into their binary values as well now you may be wondering how exactly do these instructions tell the computer what to do well these instructions don't exactly tell the computer what to do instead they're each comprised of something called micro instructions which is an even more broken down version of what the instruction does for example the first instruction is a in in the first step that a n is executed it will read from the instruction register this just gets the address that we're talking about and trying to read from and then it writes that address into the address register this changes where the ram is pointed to so now instead of pointing to wherever it was before it points to the address that we're talking about after both of those are done in the next step it will read from that memory location and it will write the value into a and the final step which is actually the final step in every single instruction is the micro instruction called ei or end instruction that just signifies to the computer that there's no more steps to be executed so it can end execution there for that instruction and move on to the next one in the program memory in total there are 24 micro instructions which in combination can be used to create all of the normal instructions above now you may wonder how we're able to get all of these micro instruction outputs from a large number of instruction inputs well that is actually done through a lookup table or in this case a rom this rom is pre-written with all of the different combinations of input bits and then the value is fed out into a number of demultiplexers turns on and off the desired micro instructions the memory is laid out like this the first 25 or 16 000 words are dedicated just to the program this is all of the instructions that tell the computer what to do in each program the next 144 words are just for character memory this is where the video circuit will read from in order to know what letter or symbol to display on screen at a given location the next 128 words are for variable memory which is an allocated spot for the compiler where it knows there is free memory and it can put new variables there and they shouldn't get overwritten between the variable memory and memory location 61000 that is general purpose memory that can be used for any reason and finally from memory location 61 000 to 65 000 or 4096 words that is dedicated to the video memory which is where the video circuitry will read from in order to know what color each pixel is something that makes up a surprisingly large portion of this computer is actually the video circuitry this here is logisim's video emulator which allows you to input a number of pixel rgb values and right pixel colors to the screen connected to it is six individual counters which increment on each clock pulse or when different requirements are met these ones over here are for incrementing in the character ram this tells the computer what letter or symbol it should write and this one over here is for pixels which tells the computer what pixel color you should write from the video memory now getting back to the characters there's actually an entire character set that i made for this computer to allow it to easily display symbols and letters this is what it looks like that all fit inside of a six by six grid now most of these actually only take up five by five because i allow a one pixel space on the bottom and the right that's because the computer does not automatically add these spaces so all the letters would look all crammed together some of them though actually do utilize this space because they're meant to be used as more of a symbol or graphics character which wouldn't normally be used accompanied by normal text now let's get on to how i wrote some programs initially i just used the instruction set and wrote programs like that although it became very very complicated and i couldn't figure out some bugs sometimes and i'd spend hours just working on one little program for example look at this program right here as you can see it just draws a rainbow square in accordance with the x and y coordinates well this one took three different revisions and i had to print them out in order to make enough comments and be able to debug it easily here are all the different versions until i finally got it working and this wasn't even a complicated program all it did was write out to the pixel coordinates the x and y values it would be very difficult to make any sort of game with this so i decided that i needed to actually make a compiled language which would compile into this it's called armstrong suggested by badok hopefully you can you know see the reference now we've already been through this once before but let's go over a bit more about what compiling really is and how this language is different from my last one first of all this one will not work on your windows or linux computer this one only works on my computer my processor to be exact the 24 different instructions in the instruction set i was able to narrow down and combine to create this right here you can now easily change register values using the at prefix and a b c or the expansion port because the expansion port is also counted as a register just to make it a bit easier there are also now variables using the dollar sign prefix which the compiler automatically allocates memory for and that way you don't need to use exact memory addresses in order to access data and there is also the label which is using the hashtag prefix this place where you can easily jump to in your code and that way you don't need to use specific line numbers which are dynamic and change there's the define command for defining a memory address there's the change command for changing any value equal to another value there is the add subtract multiply and divide commands which do those operations on two input values and then put it into the output value then there's the go to command which goes to a specific line number or label there's also the go to if statement which only goes to the line number or label if the comparison between its a and b values is true and finally there is the if statement which is just like the go to if statement but instead of jumping if it's true it just continues inside of the if statement if it is true so in c plus i built a compiler which would compile it all into the instructions and it looks like this when we compile it now if you remember the rainbow square demo that i showed you in logisim then you'd know that it is not very fast in fact it is much lower than one frame per second and that isn't actually the fault of the program the program is perfectly fine as it is it's actually because logisim needs to simulate all of the different logic relationships and logic gates and that actually takes a lot of processing to do so in order to actually run something at full speed i decided that i need to make an emulator so i also used c plus and sdl2 for the graphics and built a working emulator that could correctly process all the instruction set and correctly respond as if it was the actual hardware running the code so it runs it identically to logisim although it runs it at thousands times faster so to test out the different circuitry and parts of the system i made a few different programs which would allow me to debug and make things better or change them as i saw fit so here are a few of the examples that i made and you see this one the ball bouncing well that one well what do you think i'm gonna use it for i decided i was gonna make pong the ball has four different variables about it it has the x and y position as well as the x and y velocity it moves diagonally until it hits a wall if the wall is on the left side of the screen or the right side of the screen then it will swap its x velocity so it looks like it bounces off of it and same with the top and bottom of the screen it swaps its y velocity so to make this work for pong i need to turn off the left and right walls so the ball now goes through them and respawns in the center of the screen now this is not all that pawing is of course so i also made the left and right paddles those paddles are actually characters this one to be exact in the character sheet that's because it would take more processing time to actually write all those pixels to the screen using bitmap mode although as you can see all the characters are confined to this grid on the screen so it does look a little bit blocky when you move up and down so then what i did was some very simple rectangular collision which just checks if the ball is inside of either of the characters now the paddles actually need some movement and luckily that's where the expansion port comes in you see the expansion port can be used for many many different things and in this program i decided i want to use it for a keyboard so i made a mock keyboard circuit emulator which converts the ascii character keys on a normal usb keyboard into my special character mode which uses different indexing and so inside of the pong program i can just check if the expansion port which in this case of course is the keyboard is equal to the w and s keys for up and down for the left paddle or the up and down arrows for up and down for the right paddle and then i can just offset the character in memory accordingly unfortunately since this code is run hundreds of times per second that means that the instant that i press one of the movement keys it actually moves the paddle all the way to that side of the screen and there's no wait time so instead i hacked a little way inside of the code which allowed it to only register a key press once i've released the key or longer time has passed meaning i can't hold down the key although it'll move a lot slower than at max speed i also had to do something similar with the ball while i was still making the ball demo because the ball would move very fast across the screen using program didn't have much computing to do and so the ball therefore bounced very quickly across the screen let's learn it to only change his position every couple hundred cycles after i had all that done i made the net in the middle of the screen very simply it was just a loop that drew gray pixels on the screen every 128 pixels from the last one now the final thing of course is keeping track of the score luckily i obviously made numbers in my character set which means it's very simple to just display a simple score number from 0 through 9 using the player's score which increments every time the ball goes past the opposing player's side upon reaching 10 they win and the game is reset back to the beginning and they can continue playing once again this project is open source on github so you can go ahead and go to the link in the description where you can try it out use it for anything that you want or contribute to it join me in probably a few years for the actual build of this with electronics and components thank you for watching this if you enjoyed please feel free to hit the like button if you didn't like it you can hit the dislike button subscribe if you want to see more and i'll see you in the next video [Music] you
Info
Channel: AstroSam
Views: 956,913
Rating: undefined out of 5
Keywords: programming, coding, astrosam, samastro, sam-astro, cpu, homebrew, logisim, computer, design, circuit
Id: Zt0JfmV7CyI
Channel Id: undefined
Length: 15min 46sec (946 seconds)
Published: Fri Jul 22 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.