First timer wants to build a computer - Page 1
Forum section: electronics / beginners

author: Makkowitch
author_rank: Newbie
timestamp: December 26, 2017, 10:53:06 am
content: Hi y'allI have just completed the entire book of nand2tetris, lessons and all. The course is about building a simple computer based on nothing but NAND gates.www.nand2tetris.orgNow I want to build the computer on an FPGA. The CPU consist only of two registers, a program counter and an ALU, so it's really simple. The computer is a von Neumann architecture of the Harward variant e.g. with a ROM for the program and RAM for data. The computer will have two peripherals, a screen and a keyboard, both will be memorymapped into the RAM, so that programs can write directly to the screen and read from the keyboard. The memory and computer will be 16 bit.My question to all of you is how do I start this journey? I imagine that my end goal is to have my game of snake to be playable on the hardware. :-)

author: rstofer
author_rank: Super Contributor
timestamp: December 26, 2017, 03:13:32 pm
content: I built (in software) the nand2tetris CPU as well. I listed some CPU related books in another thread:https://www.eevblog.com/forum/microcontrollers/getting-started-with-fpga-100854/msg1380781/#msg1380781The book in bold has a nice little CPU. They don't give you the HDL code but they do give you the state machine and the datapath (block diagram). It is fairly easy to create and I think I'm running it at 100 MHz. There is also an assembler and a C compiler. These are fairly important and are really the reason I recommend the project.Just Google of 'LC-3' and 'LC-3b' The University of Texas has posted a LOT of information about the LC-3b project (byte addressable version, an upgrade).Now all you need to do is pick an HDL and learn how to create certain constructs. These are building blocks that are used to build up any system. Gates, multiplexers, decoders, priority trees, finite state machines (FSMs) and so on. Then there is the difference between combinatorial logic versus sequential logic. These all have a standard coding scheme and, once learned, are just tools in the toolbox.There are many HDL tutorial sites on the Internet. Pick a language (VHDL, Verilog, System Verilog) and then find a tutorial that matches.https://www.nandland.com/vhdl/tutorials/index.htmlWe started a religious war the other day talking about HDL languages. It happens every time. Kind of like C versus Java versus Python. Or substitute any other 3 languages like Rust, Ruby, Perl. Personally, I like Pascal and Fortran. I also use VHDL and since this is MY post, I'm going to recommend it.All in, the LC-3 (original project) takes about 1400 lines of code. It's a real RISC CPU with privileged and user modes plus a workable interrupt scheme. I took mine as far as writing a piece of code to implement interrupt driven keyboard input and console output.If you want to build a different CPU, that's fine. Just look at the way the LC-3b datapath is laid out. Then look at how they figure out the control signals and fill in the spreadsheet for the various signals. It's the design methodology that's important. Note that the big bus is really a MUX.I chose to play with LC-3 because I was looking for a small core that could be dropped in to support other projects. That and the fact that there is a C compiler. The nand2tetris project has software support so it is another possibility.Short answer: Lay out the datapath (registers, bus(es), memory), figure out the gating signals, come up with a state machine and write the code.

author: Old Printer
author_rank: Frequent Contributor
timestamp: December 26, 2017, 03:34:26 pm
content: Sounds like you are way past it, but have you seen Ben Eater's discreet logic gate computer project on YT? Even if it is repeated info for you he is a great teacher and resource just to see what he does next.https://www.youtube.com/playlist?list=PLowKtXNTBypGqImE405J2565dvjafglHU

author: rstofer
author_rank: Super Contributor
timestamp: December 26, 2017, 08:57:32 pm
content: Back to Nand2Tetris or the HACK computer, you can see the CPU datapath in figure 5.9 and a block diagram of the system in figure 5.10.http://www.cis.gvsu.edu/~kurmasz/Teaching/OldCourses/CS451/CS451_W05/WebPage/Labs/Lab7/TECS_Chapter5.pdfTake registers D, A, Amux and PC as examples. They would be declared as:Code:signal D, A, Amux, PC : std_logic_vector(15 downto 0);There would be a control signal to load each register (and increment the PC) generated in the FSM and declared as:Code:signal LoadD, LoadA, LoadPC, IncrementPC : std_logic;Inside some clocked process, the registers would be loaded like this:Code:process(clk)beginif rising_edge(clk) thenif reset = '1' thenD <= (others => '0');A <= (others => '0');PC <= (others => '0');elseif LoadD thenD <= ALUout;endif;if LoadA thenA <= AMux;end if;if LoadPC thenPC <= A;elsif IncrementPC thenPC <= standard_logic_vector(unsigned(PC)+1);end if;end if;end if;end process;Somewhere in the FSM code these Load signals will be set to '1' in the appropriate states and '0' elsewhere. Make sure you know how to set the default value ('0') at the top of the FSM body so that you don't have to specify their values in every single state. HINT: All signals need to have an assigned value under all conditions and in all states.The Amux might look like:Code:Amux <= ALUout when AmuxSelect = '1' else Instruction;Typically, the PC is a little more complex. Not only does it need to get a value from the A register, it also needs to increment by +1. Usually, there are two control signals and the PC might get it's own component in a separate file. To increment, the synthesizer will create another adder and a constant of +1. All you need to do is write PC <= PC + 1; Then the trouble starts: There is a tendency to declare PC as std_logic_vector (along with everything else) and you can't increment a SLV without using a non-standard library. So, when you implement it, go ahead and declare it as SLV and do this:Code:PC <= std_logic_vector(unsigned(PC)+1);PC is previously declared as an SLV, cast to unsigned, incremented and the result cast back to a SLV and used to update PC.You will get caught out on this issue. Without using a non-standard library, you can't do arithmetic operations on standard logic vectors. But carrying them around as unsigned seems awkward (to me).Anyway, that's what I get out of the figures in the link.

author: rstofer
author_rank: Super Contributor
timestamp: December 26, 2017, 09:50:15 pm
content: Looking at the HDL files created for Project 05, it seems to me that many of them could be converted directly to VHDL components. These components, in turn, could be connected as shown in Computer.hdl.What isn't shown is the clocking of PC and addressM - note the comment at the top of CPU.hdl. You'll have to pay attention to the memory timing. Access doesn't start until after addressM is clocked and the data won't be available until the next clock. I assume you plan to run at 100 MHz...Graphics is another matter. You need to convert the internal version of the image to VGA. When you get that far, there are other places to get that information. In the meantime, just getting text to work will be enough. You will have to add a UART component and, hopefully, your FPGA board implements a USB->Serial connection to your PC.This project takes a lot of RAM/ROM. Essentially 64k x 16 and that takes a sizeable FPGA. It looks like the Digilent Arty will do the job:http://store.digilentinc.com/arty-a7-artix-7-fpga-development-board-for-makers-and-hobbyists/You will eventually need to add VGA output:http://store.digilentinc.com/pmod-vga-video-graphics-array/You will need to install the webpack version of Xilinx Vivado. PC horsepower will matter when it comes time to synthesize your project. Anything much less than an Intel I7 7700 will be pretty grim. Or you just learn patience... I never did!In another thread, I mentioned that I don't especially care for bare boards like the Arty. I like boards with 'gadgets' like 7 segment displays, LEDs, switches and pushbuttons. My favorite board at the moment is the Digilent Nexys 4 DDR. I like it because the gadgets help me see what is happening inside the CPU. I add a single shot to the clock system so I can step through the FSM. I use the 7 segment displays and LEDs to visualize what is going on inside. It is an expensive board and probably not what I would consider a 'first board'. But I do like the gadgets.http://store.digilentinc.com/nexys-4-ddr-artix-7-fpga-trainer-board-recommended-for-ece-curriculum/

author: rstofer
author_rank: Super Contributor
timestamp: December 27, 2017, 12:12:38 am
content: Here's what Computer.hdl might look like when converted to VHDLCode:library IEEE;use IEEE.STD_LOGIC_1164.ALL;entity Computer isPort ( reset : in STD_LOGIC;clk : in STD_LOGIC);end Computer;architecture Behavioral of Computer issignal RAMdata : std_logic_vector(15 downto 0);signal ROMdata : std_logic_vector(15 downto 0);signal toRAM : std_logic_vector(15 downto 0);signal writeRAM : std_logic;signal RAMaddress : std_logic_vector(15 downto 0);signal ROMaddress : std_logic_vector(15 downto 0);beginCPU : entity work.CPU isPort Map (reset => reset,clk => clk,inM => RAMdata,instruction => ROMdata,outM => toRAM,writeM => writeRAM,addressM => RAMaddress,pc => ROMaddress)Memory : entity work.Memory isPort Map (reset => reset,clk => clk,RAMin => toRAM,RAMload => writeRAM,RAMaddress => RAMaddress,RAMout => RAMdata)ROM32K : entity work.ROM32KPort Map (reset => reset,clk => clk,ROMaddress => ROMaddress,ROMout => ROMdata)end Behavioral;This is clearly incomplete because there is no keyboard input, screen output or any other IO. This will come later...I have changed a few signal names to avoid reserved words and, since the lower level entities don't exist, I can't really say that this code is correct. But it might be close. It should give you a feel for how the code changes between .hdl and .vhdlThe address signals are probably too wide but I haven't really looked at the lower level entities. ROMaddress should clearly by [14 downto 0]; RAMaddress is a little more complicated. It should probably be [14 downto 0] but it is also logically blocked into RAM, Keyboard and Screen memory. This is a project for later.

author: Makkowitch
author_rank: Newbie
timestamp: December 27, 2017, 11:38:47 pm
content: @old printer, thanks for the youtube link! It looks very interesting and full of details, that I imagine could come in handy. I'll check it out :-)@rstofer. Wow, just wow, thanks for all the advice! I like vhdl too. I have not coded anything in it yet, only seen a couple of tutorials. It sure has the same flavor as the HDL in nand2tetris, but much more powerfull. What a luxury to have high level constructs like if/else and so on. The HDL from nand2tetris was much more sparse, so I used MUXes for that. I will definetly check out the LC-3 project!I noticed that some FPGA boards come with a build-in memory chip. Could I use that memory instead of modelling the RAM/ROM in the FPGA? I need 16 bit memory and 15 bit addressing. It could be a nice way to keep the project small. At least at first, and then model the RAM in the FPGA later.

author: Makkowitch
author_rank: Newbie
timestamp: December 28, 2017, 12:28:32 pm
content: On second thought, I can just scale down the memory a bit in the beginning, when synthesizing the project, to get a faster iteration cycle.

author: RoGeorge
author_rank: Super Contributor
timestamp: December 28, 2017, 02:00:46 pm
content: Quote from: Makkowitch on December 26, 2017, 10:53:06 amTry this:http://www.fpga4fun.com/

author: rstofer
author_rank: Super Contributor
timestamp: December 28, 2017, 04:43:04 pm
content: Quote from: Makkowitch on December 27, 2017, 11:38:47 pmYou can certainly use off-chip RAM but I would recommend using some static variant rather than DDR. There is a lot of activity around the Xilinx Artix-7 and the 35-T version has enough BlockRAM for this project. The Arty board is an example but there are others. You're right, you can reduce the ROM and RAM address space to make the project fit in much smaller chips.I haven't even looked at the video part of this project. The screen memory is mapped into RAM space so I'm pretty sure there will be enough BlockRAM. The neat thing about BlockRAM is that it can be dual-ported at no apparent cost. So, on one side the CPU sees the screen memory as just more RAM and on the other side, the video component reads the data, does some magic, and clocks out the VGA. In concept, this is simple. I just haven't looked at how exactly to lay the image down on the physical screen. This is truly ugly if you try to do it with external RAM. You usually wind up running the memory at double the speed and multiplexing the access between CPU and video component.