I don't know how CPUs work so I simulated one in code
djhworld.github.io
djhworld.github.io
The first and only time I had to do an all nighter (2 actually) in college was due to that project. Two days before the final presentation, the CPU didn't work. After a few clock cycles the memory would contain garbage. I ended up rebuilding it from scratch debugging every step of the way only to find out the 1-bit mux (a primitive supplied with the software) was wired backwards.
0 corresponded to the B input, and 1 selected the A input.
Once I correct that, the CPU worked like a charm, we nailed the final preso, and I slept for 16 hours.
I slept, came back in the morning, and had the problem fixed in like 15 minutes. I learned so much about CPU design from that class, but I also learned how important sleep is to thinking clearly.
I worked for a while with some older Vietnamese refugees who were largely self-taught electrical engineers. They used to tell me how they'd dream about the circuits in these high-watt lighting ballasts they were fixing. One tale specifically had them trying to find a fix over the course of a week, only to dream up the solution and come in the next morning to repair the gear in minutes.
I've definitely dreamed up solutions to software bugs and architecture problems myself.
I've never really dug deeply into why, but it's fascinating.
Or at least you can feel confident that you’ve picked a good career path.
On several occasion during my IT career I have faced situations where the problem at hand has taken days/weeks to solve.
What is most amazing is that on some occasions the solution literally just pops into my head.
It's almost like there is some background thread of the mind working subconsciously on the problem, only to rise to a conscious level when a solution is found.
I'm not a psychologist but from what I understand, "dual process theories" state that humans have two distinct thought processes. System 1 is fast, instinctive, and unconscious; it answers questions like "2+2=?" System 2 is conscious, deep thought; it answers questions like "if 2x+3=17, x=?". System 1 is the default thought process, but it can be suppressed by system 2. I would love if anyone who knows more knows how this might be connected.
Does Airbnb strip contact details out of messages to prevent hosts and visitors from getting in contact directly?
I once spent more time than I want to admit trying to fix a broken import in python that I knew existed but wouldn't import. The morning after I realised I was trying to import "connnector" and couldn't see the extra "n".
I've done that in my high school Visual Basic class- I woke up around 2 AM, knew exactly where I was going wrong, fixed it, and kept going until I'd finished my program. By the time my dad woke up at six, I had written over six hundred lines of code, had about twelve new features, and I was so exhausted I got sick for two days. I'm still proud of that sprint.
I'm sure each person here is talking about a slightly different assignment, course, and book; but for me (from an EE side of the coin) the person that wrote this book taught our 2 semester course series that starts with basic logic, moves into the circuitry, and then into modeling the entire computer architecture in VHDL on a reasonably inexpensive FPGA (the Altera dev boards are about $100-$200).
The book follows that 2 semester series to a tee, and uses the guy's same in course narrative style (minus smacking the whiteboard @ 8 in the morning and us getting yelled at by the french teacher next door). The writer has won multiple teaching awards from IEEE, and is a real gift to the EE community - as you can tell I have 0 complaints.
Being able to in software define the exact hardware specificaations of older consoles is pretty cool. Where as previously using general purpose RISC or CISC CPUs and have everything emulated as a software application.
https://www.youtube.com/playlist?list=PLqAMlAbd8sIuiuk_yJeqC... MIT 6.004 Computation Structures
https://www.youtube.com/watch?v=HyznrdDSSGM&list=PLowKtXNTBy...
Course is ECE3056: https://ece3056-sy.ece.gatech.edu/
I've been a TA for a course that did something very similar, and whenever a student came to me with a noticeably vague understanding (usually expressed as "it doesn't work, I've spent days on this and I don't know why"), I would observe him/her debugging it for a few minutes and showing it to me, and almost always I'd spot the problem right away; but instead of pointing it out, I would ask the student to print several copies of the circuit onto paper, then tell him/her to annotate all the signals with their expected values for the few cycles leading up to, including, and after the problematic one.
At this point a lot of them would look at me like I was insane, and reply with some variant of "I can't do it" or "we were never taught how to do that" and want to reach for the computer, whereupon I would stop them and show how. Once they figured it out, they would usually reach a point and say "I think this was my problem" --- wanting to go back to the computer again, and again I'd intervene to tell him/her to finish the whole annotation first (because they'd often have more bugs to be discovered.) Once finished, however, I'd let them use the computer again and compare, and then they would always have no problem finding and fixing the original bug, and perhaps several more after that.
I believe this is closely related to another phenomenon I've observed, which I call "debugger tunnel-vision", where a human using a tool and trying to debug a system essentially starts to blindly trust parts of it as being correct, because his/her own understanding of the functioning is itself unclear. My insistence on not using the computer and going back to pencil and paper (and brain) is, albeit probably quite "old-school" to some here, I believe an extremely important technique in being able to understand and debug effectively. It's worked not only for low-level hardware courses, but more high-level ones too --- where I tell students struggling with their code to "mentally execute" each step and compare the resultant expected values with those obtained. One of my favourite sayings is: How can you expect to be able to tell a computer what to do, if you yourself don't know how to do it?
I wish I would have had such a TA in my university. Instead, I got compressed deadlines and a "you figure it out or you fail" mentality in the majority of my classes. There were lectures and a textbook - if you couldn't sort it out and make it click on your own, alongside all of your other courses, you were SOL.
Realy really fun for a semester and a well deserved note at the end of it.
Huge sigh of relief, I might have just passed out then and there if I didn't have to continue.
Really enjoyed your story.
While I wasn't up against any deadlines I did have a few of those so-simple-it's-painful fixes when I was doing this project haha
It was a stupid project. I learned nothing from the project that I had not already learned along the way with simpler toy instructional examples. And yeah, the double all-nighter and having one team member give up 12-hours before the due date was one of the worst experiences in my life.
Let's use an analogy. Suppose you have a class where they teach using Minix. Tasks like "rewrite the time slice algorithm" or "implement part of a filesystem" can be valuable to understanding how an OS works. But if the final project is "reimplement the Linux kernel from scratch" well then you are going to spend a lot of time on the detail work of what you already understand without actually learning much new. It's a poor use of time.
Or in compiler classes. Mess with a module in LLVM is a valid learning experience. Implement a tiny language is super valuable. But "write a C compiler conforming to the C Standard" gets you into a lot of gory details about C, takes an enormous amount of time, and teaches you very little about the theory and practice of compilers and languages.
- Things can be challenging without being educational. (OP explicitly says this)
- ADHD
- High course load / other assignments they might care more about.
Your comment presumes knowledge of their situation that you don’t have. Don’t do that.
Computer Architecture 1
It was required for Computer Engineering majors (my major), but I believe an elective for Electrical Engineering and Computer Science majors.
I wouldn't discourage anyone from learning about hardware from implementing gates or even looking at simple 8-bit CPUs, but if you are interested in learning how modern caches and pipelines work, there is a free Udacity course that goes into excellent detail [0]. You can also find the lecture videos on YouTube.
This is originally an online course at Georgia Tech and the professor does an excellent job teaching these concepts.
[0] https://www.udacity.com/course/high-performance-computer-arc...
[0] http://www.lighterra.com/papers/modernmicroprocessors/
Edit: It'd be great a 2019 refresh (last update is from 2016) talking about Ryzen and the newer Intel designs.
I frequently take for granted that most people don't have this foundational knowledge. The basics come up more than you'd think, especially when provisioning the right hardware for the task.
P.S. For clarification, since those classes are in a series (2110->2200->4290), skipping an earlier one means you are skipping all the following ones too.
P.S. Bill retired a year or two ago :(
You must be familiar with Assembly code, the C or C++ programming language, Unix or Linux, and the basics of pipelining.
Each of us spent the rest of the semester picking an instruction set, designing a system, writing an emulator, and writing the code that would perform the tasks described on the first day.
I went a little overboard and created a C backend for the emulator along with an in-browser JS client that was pretty much a full-blown machine language IDE and debugger.
Needless to say, this feature creep didn't end well. I barely made it work well enough to get an ok grade but I learned that overconfidence can be more dangerous than the lack of.
Here's what I was able to salvage from the front end on short notice: http://blago.dachev.com/~blago/CS-535/stage_2/src/web/ It's using ext.js which was pretty cool at the time.
Haha, this made me smile. I can totally relate to that ambitious line of thinking: given a task to solve, you imagined the logical next steps, to build an environment for solving that general class of tasks.
Great lesson about feature creep, but I also think that kind of vision and ambitious problem-solving can be valuable in the long term, if it works the whole community/ecosystem can benefit.
My original goal for the project was to type a letter on the keyboard and get something rendering on the screen, but I definitely felt the urge to keep implementing new things. Luckily the blog post took a lot of that urge away and focussed it on writing about the project!
That is a very important lesson.
All just because I found some nice architecture models that were only available in QD3D format, and I was convinced it would only take me a few hours to read them... I only got the brilliant idea of just converting them to something simpler like .3DS after I already finished the assignment >_<
I had the same thoughts as you and bought "From Nand to Tetris"[1] a while ago but I did not get as far as you. You've inspired me to pick it back up and finish the book.
Curious if you decided to use "But How Do It Know?" over "Nand to Tetris" for any specific reason or were you just not aware of the latter.
As someone who came to computing through high level software and a little later than many (I wasn't dismantling appliances at age 5 like you hear in a lot of people's origin stories) this was a really empowering ground-up introduction to hardware architecture.
One of the few Coursera courses [1] I actually finished and found rewarding, challenging and fun throughout.
I actually didn't set out on building anything, it all happened organically! I honestly cannot remember why I chose the book, I think I just saw the blurb and figured it was good enough to read.
It was only when I was a couple of chapters in that I figured I could probably whip something up in code :)
Staring at the blank whiteness of an unwritten post, one wonders whether anyone else will notice or care what words will come tumbling out. But through your post, your work is multiplied. It is inspiring.
So, again, thank you.
I got some great feedback from friends and colleagues before publishing it so thanks to them too :)
Speaking of code, another excellent book along these lines is Code: The Hidden Language of Computer Hardware and Software by Charles Petzold.
I can't remember if the book discussed the gate level stuff, maybe that washed over me a bit at the time I'm not sure.
Really?
https://www.microsoftpressstore.com/store/browse/programming
I started working on an emulator [1] a few weeks ago but it interprets Intel x86 assembly rather than ELF files. I found this a great way to get started since parsing text is easier and the instructions you need to get a basic C program (compiled to assembly) running take an hour or two: call, push, pop, add. You can shim _start in without having to implement syscalls.
Conditional jumping and syscalls took another weekend or two and now it can run some basic fibonacci C programs. I also had to build a graphical debugger for it to see what was going on... I will probably move to reading ELF files soon.
I'll be writing up the process in a series on x86/amd64 emulator basics.
[0] https://www.goodreads.com/book/show/2558730.Digital_Design_a...
http://notes.eatonphil.com/emulator-basics-a-stack-and-regis...
This is one reason I'm ambivalent about the skepticism around computer science / engineering programs as a prerequisite for a career in software development. It bums me out to think of people toiling at this work without experiencing that kind of bottom-up knowledge of computing. But I think this is largely a projection of my own personality on others; that would be a bummer for me, but I think many people don't care about any of that and just want to do valuable work for good pay.
Ultimately I hope to implement it on an FPGA with attached keyboard and screen and actually use it to compute stuff: https://github.com/ibeckermayer/Nand2TetrisFPGA
I'm incredibly glad there was that hands-on component to the course, rather than just the theoretical textbook and lectures learning; it was hard as hell, and I actually ended up dropping it the first time and taking it again later, but at the end I actually felt like I kinda knew what was going on. Pointers were never mysterious again, at least.
It seems like a lot of people have gone through similar experiences of building an 8 bit CPU simulator/emulator. Curious why it's not 64 bits. I can guess the answer is "it's hard". I'm just wondering where the difficulty lies. Is it in the standards? The mechanical feasibility of connections? Actual limitations of building a 64 bit emulator on a machine powered by a 64 bit processor?
Apologies if the question seems obvious. I come into this knowing next to nothing and I could probably find the answer with some research of my own. Just wanted to ask the community for thoughts here ️
But it would slow it down massively due to me writing it in a general purpose programming language and passing around booleans everywhere, there's a lot of for loops that copy things in and out of buses and I would have to increase the size of the ALU to accomodate the bigger numbers.
The author themselves points out that a "big pile of gates" is not the best approach here, but I'm kind of surprised that at no point did they attempt to build another representation of the circuit and either execute it in a table-driven way, or write a short script that spits out go for compilation.
Perhaps because the existing implementation had already served its purpose - an educational exercise to understand CPU design, and not an instruction-level emulator or transcompiler.
I'm sorry you didn't think I took the best approach.
The point when I realized I finally understood (on a surface level) everything from the electrical signals to my JavaScript reminds me of when I finished the last video of Khan Academy's series on Euler's formula and "understood" it, if only for a moment.
Take a look to see how simple is working of a CPU, and by how many MAGNITUDES does the code size grow when any modern "programming paradigm" is involved.
Programs that are brought down to the absolute minimum of arithmetic and logical operations in assembler can often run thousand times faster than when written in higher level languages.
I remember I was shown how a classical computer science problem called "Sisyphus dilemma" can be done in a single logic instruction, instead of a kilobyte long program in Java that makes the smallest solution possible when no binary operations are allowed.
Unless you're an expert in ASM / have an unlimited amount of time / work on an extreme edge case I'd say the compiler will beat a human 99.9/100
2. Sure, assembly is faster than Java script but good luck getting any abstraction or type safety in ASM. And also you're code is impossible to debug and takes 15 times longer to work on
Yeah, but you can't scale that to teams of programmers working on complex business logic.
This sounds interesting and I'd like to read about it, but Google isn't helping.
Mistook the name.
Yep, just shift the binary representation of the total number of members by 1 bit
/**
*
* @param n (41) the number of people standing in the circle
* @return the safe position who will survive the execution
* ~Integer.highestOneBit(n*2)
* Multiply n by 2, get the first set bit and take its complement
* ((n<<1) | 1)
* Left Shift n and flipping the last bit
* ~Integer.highestOneBit(n*2) & ((n<<1) | 1)
* Bitwise And to copy bits exists in both operands.
*/
public int getSafePosition(int n) {
return ~Integer.highestOneBit(n*2) & ((n<<1) | 1);
}This reminds me of this amazing computer done in the cellular automaton Wireworld. https://www.quinapalus.com/wi-index.html
link: https://www.youtube.com/playlist?list=PLowKtXNTBypGqImE405J2...
Building an 8-bit breadboard computer!: https://www.youtube.com/playlist?list=PLowKtXNTBypGqImE405J2...
I always find that "learn by doing" works best in these sorts of things :)
Not sure if my thing is remotely close to that, but nice to know I'm standing on the shoulder of giants :)
The Elements of Computing Systems: Building a Modern Computer from First Principles
https://www.amazon.com/Elements-Computing-Systems-Building-P...
Guess introductory courses in universities aren't useless after all.
Uh huh, the FPGA Chip-8 thing sounds awesome! Definitely post about it!
The article describes an 8 bit CPU with 17 instructions.
CHIP-8 is an 8 bit CPU with 31 instructions, but crucially, it has a large amount of documentation[0] and a nice corpus of ROMS available[1] making it a bit easier as you don't have necessarily write your own programs for a CPU you don't fully understand yet.
[0] See http://devernay.free.fr/hacks/chip8/C8TECH10.HTM among many other resources [1] For example this archive of the now defunct chip8 archive site https://github.com/dmatlack/chip8/tree/master/roms
I'd definitely recommend doing something like that (not at the logic gate level though - too slow) but an emulator is a fun project to tackle. I wrote my Gameboy emulator first which is a bit more complicated than chip-8 and at the time the documentation was a lot more varied.
With more and more people getting into coding and languages of higher and higher levels, less of us are turning to the lower levels of computer science. Lots of developers did not study CS at all and the ones who did mostly neglected the computer architecture classes - myself included.
Sometimes I stop and wonder that most of my low level compute knowledge comes as mere luck because I ended up working for the EDA industry for a few years. If I had not, I'd be a computer scientist with close to no understanding of how a computer actually works. We should all know our HDL's.
I bet there are far more low level developers now than 30 years ago, however.
30 years ago every developer at least knew how bits and bytes with logic operations work.
Now, just any minimally proficient C/Cpp devs are genuinely hard to find. I may well say that there are less of them in total now.
C development community shrank a lot over the years.
Things went so bad that now some people suggest running whole web servers on MICROCONTROLLERS to just blink some LEDs!
Why is that such a bad thing? Even microcontrollers are magnitudes more powerful than they were years ago, so why stick with other "simpler" methods when you can go with something more secure, easier to write and understand, and more "standard"?
I'm one of those people running webservers on microcontrollers (you'll hate this, but I program my esp8266 controllers in JavaScript!), and it seems silly to lament that. They are cheap (about $3 a piece to my door), power efficient (battery life is measured in months for the battery powered devices), and all of my code is about a dozen lines of simple code that allows me to integrate with the rest of my system.
Microcontrollers: cheap, reliable hardware. Web: cheap, reliable interface. Web programmers: cheap, numerous.
What's not to love?
You said yourself: minimally proficient C/Cpp devs are genuinely hard to find. HTTP GET with the program. ;)
Seriously, you want your noodle vending machines to run a web server on an MCUs? I can't wait to see how eval escape will look on a vending machine.
Well, at least now you know whom to call when they will break =D
They're all in China and Korea churning out our cheap consumer hardware.
Most IoT devices with embedded web servers are running on relatively modest processors. The main barrier to running an embedded networking stack is RAM and that is abundant enough in cheap micros to make it a non-issue.
There are a bunch of books which explain how to write Lisp compilers. There are a bunch of different strategies.
> Does it create stack frames and do calls when recursing
That's what a typical Lisp might do. It might also change the stack frame and just jump to a function...
It's also relatively easy to check out, since Common Lisp has a built-in disassembler. One can take an implementation, compile a function and see the generated code. Just call the function DISASSEMBLE with a function object...
This is part of a proud and surprisingly long-standing tradition. The first Lisp interpreter was originally written in Lisp by one person, and then hand translated into assembly by another. This came as a surprise to the rest of the lab who had intended to work on an actual implementation in a year or two. You know, some time after they came up with a real syntax for it.
But does it really make you better than other, very unlucky programmers, who doesn't have the "low level computer knowledge"? Does it make you the REAL programmer?
Because it's not. Because that's THE reason we have higher-level programming languages (and also lower-level ones) in the first place. Is computer just a black box to you? That's completely fine.
>computer scientist with close to no understanding of how a computer actually works
Which is how it's supposed to be.
Don't be such a gatekeeper.
I do feel the same. A lot of "computer science" degrees are in fact just basic programming ones, and that often goes to masters, and rare cases PhD level degrees.
It is a common critic from industry that "computer science does not teach how to code," and I see too many universities seemingly taking it these days.
It is ironic how once computing science was once a road to unemployability and coding was all rife, but now companies don't want to hire people without degrees to do menial jobs like webdev.
A lot of the webdev work I've done has been significantly more challenging and technically difficult than most of the C work I've done. That's not to say C is "easier", it's not, but it is different.
I've seen shitty devs in all areas, and I've worked menial jobs both in webdev and at the embedded C level (I had to write C code to display a custom font on a shitty LED display, that was easily the most boring job I've ever done).
http://ai.eecs.umich.edu/people/conway/VLSI/MIT78/MIT78.html
The Great Quux's Lisp Microprocessor is the big one on the left of the second image, and you can see his name "(C) 1978 GUY L STEELE JR" if you zoom in:
"Guy Steele: LISP microprocessor (LISP expression evaluator and associated memory manager; operates directly on LISP expressions stored in memory)."
http://ai.eecs.umich.edu/people/conway/VLSI/InstGuide/MIT78c...
And here is a map of the different parts of the Lisp microprocessor:
Here is the chalk board where they kept track of all the student's projects and where they would go on the chip:
http://ai.eecs.umich.edu/people/conway/VLSI/MIT78/Status%20E...
And the layout of the chip with everyone's project (with the big Lisp microprocessor standing out at the lower left):
"The final sanity check before maskmaking: A wall-sized overall check plot made at Xerox PARC from Arpanet-transmitted design files, showing the student design projects merged into multiproject chip set."
http://ai.eecs.umich.edu/people/conway/VLSI/MIT78/Checkplot%...
This is a photo of one of the wafers they made, with lots of chips:
"One of the wafers just off the HP fab line containing the MIT'78 VLSI design projects: Wafers were then diced into chips, and the chips packaged and wire bonded to specific projects, which were then tested back at M.I.T."
http://ai.eecs.umich.edu/people/conway/VLSI/MIT78/Wafer%20s....
And here the classic paper about it, "Design of a LISP-based microprocessor" by Guy Lewis Steele, Jr. and Gerald Jay Sussman:
Oh, I built a working computer, too. That was fun. But when at the end of that project you've got a processor and some RAM and a display sitting there in front of you, well, you realize that you don't really know what to do with the rig. Now what?
Then I realized that I could do far more damage in software (at scale) than with hardware (just one-off workbench class disasters). And so . . .
Haha, this was pretty much it for me too. I'd imagine going down the hardware route is a lot of fun with a lot of lessons learnt, but an expensive lesson.
I might play around with some hardware stuff next though.
I did suffer a different form of pain with trying to implement all the gates together in a GP programming language - that was probably a bad idea in hindsight!