Hacker News new | past | comments | ask | show | jobs | submit login
Designing a CPU in VHDL, Part 6: Program Counter, Instruction Fetch, Branching (domipheus.com)
75 points by skywalker_ on July 23, 2015 | hide | past | favorite | 21 comments



Would anyone familiar with the various qualities of FPGA boards care to weigh in on how to pick a good development board for this project? I personally know nothing about FPGA specs.

Additionally, the first blog post in this series can be found at http://labs.domipheus.com/blog/designing-a-cpu-in-vhdl-part-...


The Terasic DE0-nano (http://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=E...) is a great board for soft CPU's. It's cheap, has a decent size FPGA and external SDRAM. The Altera tools are free and run under Windows/OSX/Linux.

I've used this board for my own soft CPU (http://jamieiles.github.io/oldland-cpu/) and it's a rewarding project!


Happy to provide some quick feedback on your coding style:

Please don't use initial blocks to initialize values, use an always block with reset. That will also solve the issue of having multiple drivers per signal (bad). Also, don't load memories from the RTL, do that from the test bench (using hierarchical references).

  initial begin
	$readmemh({`OLDLAND_ROM_PATH, "decode.hex"}, microcode, 0, 127);
	rd_sel = 4'b0;
	update_rd = 1'b0;
	alu_opc = 5'b0;
	branch_condition = 4'b0;
	alu_op1_ra = 1'b0;
	alu_op1_rb = 1'b0;
	alu_op2_rb = 1'b0;
	mem_load = 1'b0;
	mem_store = 1'b0;
	mem_width = 2'b0;
	pc_plus_4_out = 32'b0;
	instr_class = 2'b0;
	is_call = 1'b0;
	update_flags = 1'b0;
	update_carry = 1'b0;
        cr_sel = 3'b0;
        write_cr = 1'b0;
        spsr = 1'b0;
        is_swi = 1'b0;
	is_rfe = 1'b0;
	i_valid = 1'b0;
	cache_instr = 1'b0;
	exception_start_out = 1'b0;
end

If someone knows of a community like HN that can write great Verilog, let me know.


The closest thing I can think of as far as communities would be the http://www.edaboard.com/ folks (although that's a lot of students) or opencores.org (which is more just general projects).

There are a lot more "news" esk hardware design places as well but I'm assuming you're looking closer to stack overflow/github of HDL rather than the slashdot/reddit of HDL?

If you want HDL best practices any of the resources you can get your hands on from http://www.sutherland-hdl.com/papers.html <-- those folks are excellent

and I would highly recommend this book: http://www.amazon.com/SystemVerilog-Verification-Learning-Te...


Thanks for the feedback. With regards to initial blocks, the advantage of using them on an FPGA design is that it's just the initialization value of the registers in the bitstream so doesn't have any real cost, but doing it with a reset would take logic, no? Does that really qualify as multiple drivers?

For the memory loading, I don't know how you'd infer a ROM another way - aren't hierarchical references only supported in simulation/test benches?


Doesn't your design need to handle reset anyway? If so, then the initial block is redundant. If your design doesn't have a reset, that's highly unusual.

If your target wasn't an FPGA (but an ASIC), the initial block would be completely ignored, so who knows in what state your design would start. FPGAs are nice, they let you specify initial values. Real chips don't. Just put all initial values in your reset clause, in the same always block you assign those registers. Let the FPGA compiler optimize the logic if it can, or infer a mux if it must.


The DE0-Nano has a successor, the DE0-Nano-SoC which also has a dual-core Cortex A9 on chip (similar to the Xilinx Zynq chip):

https://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=...


Digilent has a bunch of FPGA boards:

http://www.digilentinc.com/Products/Catalog.cfm?NavPath=2,40...

The DE0-Nano-SoC, which has an FPGA and a dual-core Cortex A9 might be a good option if you wanted to get started with Altera parts:

https://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=...

The analogous Xilinx board is probably the Zedboard:

http://zedboard.org/

Finally, you might consider the Lattice Semiconductor iCE40. There are two dev boards (small and large, both very cheap):

http://latticesemi.com/iCEstick

http://www.latticesemi.com/en/Products/DevelopmentBoardsAndK...

They are especially attractive since they have the only fully open source toolchain:

https://github.com/cseed/arachne-pnr

Have fun!


Not a great codebase, if you are trying to learn the industry's best practices. For instance, I recommend naming your RTL signals based on which pipeline stage they belong to. Assuming this thing even has a pipeline.


Hey - author here. I'm not wanting to learn industry practices, it's a hobby project. May look into things like that later, though. The other article parts have the disclaimer that says I have no idea what I'm doing ;) Cheers for the feedback :)


Uh oh. I didn't realize you were actually on HN. Apologies if my other spiel seems too harsh.

Perhaps the better sounding term would be "engineering practices" rather than "industry practices". If it's a hobby, you still want to get a good result out of your effort. That principle in industry still applies to the hobbyist IMO.

The signal names issue that alain94040 mentioned was just an example of one problem with the code.

Assuming the desired result is to get running on an fpga, I think you need to take a step back for a second and look at the target environment you want to run on and plan out how it will all work.


Hah, don't worry - I didn't think it was harsh. I've had no training/edu in HDL whatsoever, so this was a deep dive - I expected to be told I'm doing wrong!

The end result is on FPGA, yes. Still a long way before that works. And I'll make sure any massive screwups are documented in next parts, those are the best parts (and, probably most valuable) to write about :)


So, where is a great codebase for somebody who wants to learn?


Tools vendors each have coding guidelines that their stuff likes. At the RTL level, industry guys like myself just follow them like puppies due to fear of something in the tool chain breaking.

Then we complain to them when it misbehaves anyway. A quick google will you find some guides.

https://www.doulos.com/knowhow/vhdl_designers_guide/rtl_codi...

On top of that we had company specific style guides. Having jumped from company to company, each one is different here and there.

To be honest, I think we tended to avoid looking at other people's code when we could! Its like having to wipe someone else's butt. It all looks terrible. Everyone can pick on someone else's stuff.

Having said all that, the basic principles of engineering apply:

- Nice separation between the design and the test bench.

- modularity within the design itself.

- A convention of signal naming that will assist the verification process. Eventually they get thrown a waveform when something has gone wrong. They need to look at signal names that aren't some random alphabet jumble.

- Parameterize variables so they can be reconfigured easily.

etc.


industry guys like myself just follow them like puppies due to fear of something in the tool chain breaking

There's also value to a consistently styled codebase.


I keep pointing people to the page I started a while back: Verilog for Software programmers (https://en.wikibooks.org/wiki/Programmable_Logic/Verilog_for...)

Maybe it's time for me to add another one: good Verilog RTL coding style, or basic RTL rules for Verilog... Based on the kinds of mistakes I see online, it would be easy to cover initial blocks, multiple assignments, etc.

EDIT: just started https://en.wikibooks.org/wiki/Programmable_Logic/Verilog_RTL... . For now, just contains placeholders for the items I want to cover, but feel free to add to the list, that's the whole point of a wiki.


Not a great codebase. That's putting it lightly.

It does have a pipeline BTW.

Industry is so different I don't know where to start complaining.

Xilinx tools are not used for simulation usually because they suck and we generally pay those other tool vendors for their stuff so we might as well use them.

Given that newbies don't want to pay, maybe Xilinx is the best. I don't know much about the free stuff.

Looking at previous posts, there is so much behavioral code everywhere. We don't write a lot behavioral stuff in VHDL usually. There are higher level languages for behavioral code. Once again, you probably have to pay for those tools so maybe you have no good choices other that behavioral VHDL.

IF generic you are stuck with the Xilinx behavioral VHDL, I still would NOT write the behavioral stuff to be a cycle accurate representation of the design. You are just as likely to make a mistake in the behavioral as the RTL. Then when you test the behavioral model against the RTL you will spend half your time debugging the behavioral side. Thinking ahead really helps.

The whole approach is wonky from the start. If it were me I would think about the project as a whole and plan ahead. The design is complex in terms of verification. We always assume that every design is complex to verify! If not you wouldn't need HW in the first place.

There will be lots of tests. How does the test bench run a big suite of tests and report failures? You do not want to look at waveforms unless your test finds a failure. This blog jumps straight to waves!

I would start from the whole design first. Figure out the interfaces. Then try to express those interfaces in terms of transactions.

In fact, maybe don't even start writing VHDL as an expression of the design. Most times in industry we design via documents first. Docs express how the HW will work at a high level and how it will be verified. It breaks the design down into modules. It explains the interfaces between modules. These interfaces become possible points for the verification to look at. The test bench compares the simulated result with a golden reference when it sees a transaction event at the interface and reports a mismatch.

The point is create project infrastructure first via planning. Have a big picture view of how it's all going to be thoroughly tested automatically each time new code is committed. In industry on top of directed tests, we use constrained randomized tests. We have to determine whether we have covered everything. So we need functional coverage. All this is designed first BEFORE we play around with flops.

We can tolerate a lot of craptastic VHDL/Verilog code in industry because at the higher levels it looks neat and tidy and it is all tested vigorously.

Basically don't follow any stuff from academia because I would bet those guys have never delivered a commercial product. Educational material from tools guys is almost as bad for similar reasons. No one can hold your hand so you have to use your brain.

I probably vented too much here. It's just tough to see engineering done badly.


Software guys should be at least passingly familiar with the idea of rigorously spec-driven design- that's what gluggymug is talking about.

You know how in software you always say, "We don't have time for that"? Well, it's a lot harder to get away with skipping it in HDL.


This is some great stuff, thanks for all the feedback - seriously. My VHDL experience is probably about 2/3 online tutorials, and they were all behavioural. The main aim of the articles are for me to learn.

The point about documentation is valid. However, as I've has no training at all in this, I'd be writing a document that basically has no value. After this project has come to it's conclusion, I'll probably go try again using processes/methods learned.

Thanks again for the feedback :)


Learning by doing is cool.

You don't have to do it the conventional way.

It's just that from my perspective, I can only focus on the future problems. I am too traumatized from the HW experience! I almost rewrote a couple of my points again just now.:)

You are documenting via your blog in a sense. It has value. It is a high level representation of your plans for the project.


Is there any repository of knowledge for learning these best practices?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: