Skip to content

Instantly share code, notes, and snippets.

@ZipCPU
Created January 14, 2017 16:17
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ZipCPU/95e0dd0beb93b127b1ea239c18c3e418 to your computer and use it in GitHub Desktop.
Save ZipCPU/95e0dd0beb93b127b1ea239c18c3e418 to your computer and use it in GitHub Desktop.
FPGA discussion
<student> Yes I am
<ZipCPU> You asked a question on ##verilog some time ago, and then left before I noticed and answered the question.
<ZipCPU> I wanted to make certain you were on line before I commented on any of your issues.
<ZipCPU> Further, because the ##fpga discussion is struggling to handle about 3 topics at once, I thought it might be simpler to leave the discussion channel.
<student> Yea that's right, I left before receiving any answers, I waited a lot but none answered.
<ZipCPU> You were asking some fascinating questions on ##fpga.
<ZipCPU> May I try my hand at answering any of them?
<student> Yea sure, I would be too thankful for that as I'm starting my way in digital design and I have multiple issues that I didn't find answer on edaboard forums, and IRC as well!
<ZipCPU> So ... I started digital design in earnest almost two years ago. In many ways, I'm a newbie. On the other hand, I do have a graduate degree in computer engineering, so ... I might know a thing or two ...
<ZipCPU> At one time, I found a very fascinating article on trying to figure out how fast computers were.
<ZipCPU> It helped to explain the struggle with measuring the computers speed by its clock speed.
<student> That's cool, I only need some detailed technical answers for my questions, even if you didn't have I'm too thankful for your time and trial to answer!
<student> Well, let's start by the weird questions
<student> question*
<ZipCPU> Sure, go ahead.
<student> I just finished my first full Verilog project, simulated and synthesized it, everything worked as I wanted
<ZipCPU> What was the project?
<student> As a beginner, I uploaded my code on edaboard, but got disappointed from the comments!
<ZipCPU> Heheh ... go on.
<student> the project was an implementation for a simplified DES algorithm
<ZipCPU> Did you post as "redsees"?
<student> yea
<student> you saw the thread?
<ZipCPU> Just now when you posted it. I'
<ZipCPU> I've pulled it up, but its a long thread. It'd take me some time to read through it.
<student> Well, let me give you a brief of the comments, they are criticizing the code because I used few tasks, they said on the forum that using tasks is a bad practice because it's like writing SW in Verilog
<ZipCPU> Okay. Go on.
<student> my questions is what's wrong with that? I mean, I used tasks to avoid code repetition that's all, what's "bad" in such code?
<student> in such coding style*
<student> question**
<ZipCPU> Were you around for the computer speed races in the '80s and 90's? It'd help to answer your question.
<student> nope
<ZipCPU> Ok ;) I'll explain a touch then.
<student> yes please, and thanks a ton!
<ZipCPU> Back with the early computers, there began a big speed race. Who can build the fastest computer?
<ZipCPU> Whenever you went to the store to get a computer, people would automatically go and find the fastest computer.
<ZipCPU> How did they know which computer was the fastest? By the clock rate, of course!
<ZipCPU> Computer speed in those days was measured by "Millions of Instructions per Second", sometimes called MIPS.
<ZipCPU> I prefer to remember "MIPS" by "meaningless indicator of processor speed" but ... that's part of the story.
<ZipCPU> On many of the older machines, it would take many clocks to execute an instruction.
<ZipCPU> Then along came newer machines that could execute the same instruction in one clock. In the process, the clocks got slower.
<ZipCPU> Then along came RISC machines with really fast clocks, but instructions that couldn't do as much. How should one know if this was faster/better/cheaper?
<ZipCPU> My point is, you presented some code without a clock.
<ZipCPU> To be useful in HDL, a clock will need to be added.
<ZipCPU> Because you have *so* much functionality taking place within your routine, you will need to add a _slow_ clock.
<ZipCPU> Remember--the speed of the fastest clock you can support is determined by the amount of logic that must take place between clock ticks.
<ZipCPU> All of the wires need to be stable before a clock ticks by some amount of time (setup time), then they need to hold steady for some amount of time (hold time) ... etc.
<ZipCPU> All this is to say that more complex functions between clocks of a necessity slow down your clock rate.
<ZipCPU> That's lesson #1.
<student> Aha, I got the point now of using a clock in a design!
<ZipCPU> Yep!
<ZipCPU> Lesson #2 is ... what about everything else that needs a clock?
<student> exactly, that's the next logical question
<ZipCPU> Suppose you want to add two numbers together, and clock the result. That operation, if it works in parallel with your DES, would then be forced to be a lot slower because of all of the logic you stuffed into your DES calculation.
<student> ye
<student> yea
<ZipCPU> So a computers clock (or FPGA clock, etc) is forced to be as slow as the slowest logic on your board.
<ZipCPU> You want to do things fast, so you want the fastest clock you can get, which means you need to take complicated logic and split it across multiple clock cycles.
<ZipCPU> I'll pause here for comments/questions/thoughts.
<student> it's clear till now
<ZipCPU> "till now"? Uh oh ... what can I clear up then?
<student> let's get back to the first question, what's bad about using tasks, if I rewrote my design and added the usage of a clock signal to synchronize the execution flow of the logics
<student> will using tasks still be a bad practice?
<student> and why
<ZipCPU> Well ... at that point, you don't need tasks anymore.
<ZipCPU> Let's compare tasks and modules.
<ZipCPU> Tasks are (if I remember/understand correctly--I don't really use them myself) sort of like lookup tables, right? They can do complicated logic, but never with a clock. Yes?
<ZipCPU> (Otherwise I'll need to do some googling here ...)
<student> Well, they could be used as a lut but mainly they are used to avoid code repetition, just like procedures and functions in SW
<ZipCPU> Yes, but why tasks to avoid code repetition and not modules?
<student> Because I can't use a module inside another module sequentially
<ZipCPU> "Sequentially"? Now you're talking like a programmer! ;) The only way to do things "sequentially" in Verilog (or other HDL) is with a state machine.
<ZipCPU> Well ... pipelines work too ...
<ZipCPU> If you want to do "A" then "B" ... that takes a bit of thought. Let's assume A depends upon input I, and after doing B and output O is available.
<student> YES!!! you put your hands on the main problem! why talking like a programmer contradicts some concepts in digital design? why the usual programming concepts cannot be used in HW like abstraction and such?
<ZipCPU> Yes.
<ZipCPU> Let's work through it, shall we?
<student> Well, that's a very good/simple example
<ZipCPU> In a computer program, you have a series of steps to accomplish. Hmm .... let's think of a good example here ... how about incrementing a value?
<ZipCPU> Your program will have an instruction to read the value from memory, another instruction to add 1 to the value, and then a third instruction to write the result back.
<ZipCPU> Simple enough?
<student> ye
<ZipCPU> In Verilog, you would typically do the same thing without the memory. Hence, you would have ...
<ZipCPU> always @(posedge i_clk) counter <= counter + 1'b1;
<ZipCPU> If you _had_ to read the memory, and _had_ to do it only when requested, the logic gets *much* more complicated.
<ZipCPU> For example:
<student> isn't counter here considered as a memory?
<student> calling its value, incrementing then updating it back?
<ZipCPU> .... mmm .... good question.
<ZipCPU> Unlike normal memory, a counter doesn't necessarily have an address associated with it.
<student> Isn't any variable a memory address pointing as some location at some memory device?
<student> even if it was a processor register
<student> at some location*
<student> I'm sorry if my questions are too newbie tho
<ZipCPU> You could create a counter, and treat it like memory, though. Example: https://github.com/ZipCPU/zipcpu/blob/master/rtl/peripherals/zipcounter.v
<ZipCPU> (Sorry ... took me a while to get that link ...)
<ZipCPU> "Isn't any variable a memory address pointing as some location at some memory device"? In computer programming, yes. In HDL, that depends.
<student> In HDL, it's the same but with no memory address, like a FF for example right?
<ZipCPU> For a computer to get to some "location" implies the existence of a bus. Sure, you can make a bus within an FPGA, you can make many busses within an FPGA, but youdon't need to.
<ZipCPU> Yes!
<ZipCPU> The next thing the computer would need would be the ability to decode the addresses on the "bus", and to farm any requests out to whatever various devices (pieces of logic) might be on the bus.
<student> yes
<ZipCPU> Example (my current project): https://github.com/ZipCPU/openarty/blob/master/doc/spec.pdf, check out the "Registers" chapter.
<student> let me have a look
<ZipCPU> (It's not coming up for me properly. Tell me if you also have the same problem.)
<ZipCPU> It's on page 19 for me.
<ZipCPU> That page outlines where all of the various peripherals are on the "bus" I created internal to my design.
<student> yea, a bus with each respective address
<ZipCPU> The device has on-board memory, that I have placed at 0x8000.
<ZipCPU> The network has two pieces of memory, one at 0x800 and another at 0xc00.
<ZipCPU> A third piece of memory, used for controlling the network is at address 0x0138.
<ZipCPU> But ... this is probably more advanced than need be for your questions.
<ZipCPU> I just use it to point out, when you create a "bus" for a computer to "read" from, you've got to connect things to that bus.
<ZipCPU> Any number of things can be connected--in many ways, it's up to you.
<student> yes
<ZipCPU> However, "counters" don't need to be connected at all.
<ZipCPU> Hmm ... what's a good example of that ...
<ZipCPU> Ok, here's an example, I've had problems with the bus before where a request might be sent to some broken device, and the device never returns the result.
<student> Well, frankly I'm a bit confused, let me recall a simple example you mentioned in the beginning
<ZipCPU> Imagine your computer trying to read from memory and getting hung ...
<ZipCPU> Okay, I'll pause. What was the simple example you'd like to go back to, the counter?
<student> If we have two block of operations "A" and "B", "A" contained a bunch of operations that must be executed sequentially, "B" waits for "A" to finish executing all its operations, and then executes its own operations. How/Why a clock could be used in here?
<ZipCPU> Ah, yes, good. Let's work through that. May I offer a simplified example "A" for discussion? How about a multiply.
<ZipCPU> That makes for a good discussion of a complex task.
<ZipCPU> "A" takes two inputs, X and Y, and produces an output, Z = X*Y. Simple enough?
<student> yea
<student> you excluded B here?
<ZipCPU> (Excluding B for now--we can come back to it.) We could make it even more complex--suppose you don't have any hardware multipliers, so this must be done completely in logic with lookup tables.
<ZipCPU> In other words, your multiply needs to be done "long-hand" if you will.
<ZipCPU> To do this, you need to create a series of rows, where each row is X(n) (the n'th bit of X) times Y, and upshifted by n. You then want to add these rows together.
<ZipCPU> Lots of logic, right?
<student> yes that's good example, let's not have a multiplier circuit, suppose that "A" is taking two inputs, X and Y, multiplies them using a long couple of sequential logic instructions
<student> yea
<ZipCPU> You might do it with one clock for the *whole* operation. Wow. Lots of logic. One clock.
<student> that's because the operations could be done in parallel right?
<ZipCPU> For the sake of discussion, let's assume this logic takes about 350ns to accomplish. (That's about right ...)
<student> because each operation doesn't depend on the others
<student> am I right?
<ZipCPU> Well ... I'm not sure I understand your question, but ... I think so.
<student> I mean, the whole multiplier circuit operations could be done only in one clock cycle because each operation doesn't depend on the other operations, right?
<ZipCPU> Well, not quite. You could do the whole multiplier circuit in many clocks.
<ZipCPU> For example, suppose you could do a 32-bit add in one clock. You might then multiply two 16 bit numbers together in 16 clocks.
<ZipCPU> At a 10ns clock, that's 160ns to do the multiply, right?
<student> yea
<ZipCPU> Throw in a few more 10's of nanoseconds to deal with a sign bit, etc. so maybe 200ns.
<ZipCPU> However, you can do one 32-bit add in 10ns.
<ZipCPU> So ... would you like your design to run with a 200ns clock (5MHz), or a 10ns clock (100MHz)?
<ZipCPU> How fast would you like to add two 32-bit numbers together, in 10ns or 200ns?
<ZipCPU> If your multiply is so complex that it takes 200ns per clock tick, then you just slowed down any addition operation to that slow as well.
<ZipCPU> Actually, that gives us our perfect example!
<ZipCPU> Suppose you are trying to calculate: V = X * Y + U. (U might even be the V from the last calculation ...)
<ZipCPU> (No ... let's make U independent of V ...)
<ZipCPU> Good example?
<ZipCPU> A is then multiplying X * Y. B is taking the result and adding U to it.
<student> yes, good one
<student> B should now wait until A completes its multiplication
<ZipCPU> If "A" takes 200ns to accomplish, "B" cannot be accomplished for less, since your clock speed must now be determined by your slowest operation.
<student> How can we implement that example using a clock signal
<ZipCPU> The whole thing now takes 400ns.
<student> yes that's logical
<ZipCPU> If, on the otherhand, you implement A with twenty 10ns clocks, then A and B together may be done with 21 clocks, or 210 ns.
<ZipCPU> Which was faster? ;)
<ZipCPU> Okay, but we haven't answered your question, have we?
<ZipCPU> How to do it with 20 clocks, right?
<student> yea exactly
<ZipCPU> Ok. There are two basic approaches in this case: pipelined, and state machine.
<ZipCPU> With the state machine approach, you get something closer to the computer answer.
<ZipCPU> You have an internal "state" that keeps track of where you are in the operation.
<ZipCPU> Based upon the "state", you would do some logic or other.
<student> yea
<ZipCPU> For example, you would have one "state" called the "idle" state.
<ZipCPU> In this state, you wait for a request to do an operation.
<ZipCPU> Once the request comes in, you proceed to the state associated with the first bit.
<ZipCPU> One that first bit state, you would add to your accumulator X(0) * Y. (You'd set the accumulator to zero when you were idle ...)
<student> ah yea
<ZipCPU> On the second bit state, you'd add to your accumulator X(1) * Y * 2. Then on state 3, you'd add X(2) * Y * 4, etc., etc.
<ZipCPU> When you get to the last state, you set a flag on the output that tells the following logic that it has a valid output to work with.
<ZipCPU> Then you switch back to the idle state and wait for another input value.
<student> So now, how "B" is going to know "A" has finished its job and its turn came to execute
<student> ?*
<ZipCPU> "A" has to have an "I'm done" wire coming out of it. It must also have an "I'm busy" wire as well, so you don't ask it to do another multiply while it's still busy with the last operation.
<ZipCPU> I have an example of a "divide" module that uses this exact approach. https://github.com/ZipCPU/zipcpu/blob/master/rtl/core/div.v
<student> "B" will only be concerned about the "I'm done" wire, let's call it "D" signal for example, so if I'm understanding right, "B" procedural always block will have CLK & D is its sensitivity list right?
<ZipCPU> The "i_wr" input tells it to start it's operation. While it is working, the "o_busy" line is high. Once it has a valid answer, "o_valid" becomes true.
<ZipCPU> I only put clocks in the sensitivity list.
<student> then how is "B" going to check for the D signal?
<student> in an if statement inside B's always block?
<ZipCPU> Easy ... on the positive edge of the clock! ;)
<ZipCPU> The always block for "B" would start out: always @(posedge i_clk) if (D) B <= output_of_A;
<ZipCPU> Or, rather, ...
<ZipCPU> always @(posedge i_clk) if (D) V <= output_of_A + U;
<ZipCPU> You'd also want a, always @(posedge i_clk) V_is_valid <= (D);
<student> So that means, if we edited our example to be 4 blocks of operations "A" to "D", each will have its own operations inside an always block, with a "Done" signal to inform the next operation in turn to start execute, and all always blocks will have only clock in their sensitivity lists, am I right?
<ZipCPU> Yes!
<student> I see now the whole picture!
<ZipCPU> I just built something similar recently to create an ethernet output:
<ZipCPU> One module turned th 32-bit memory words into 4-bit inputs.
<ZipCPU> A second module added a preamble.
<student> So instead of tasks, I would use an always block for each set of sequential operations I have right?
<ZipCPU> A third module added the ethernet packet header.
<ZipCPU> A fourth added a CRC, etc.
<ZipCPU> ... nnnn ... <cringe> .... not quite.
<student> Wait, your ethernet project is a great example
<ZipCPU> Always blocks encode what happens on one clock edge.
<ZipCPU> If you want things to happen on multiple clock edges, you must also include some sort of state together into your always block.
<student> In your top-level module, you call an instance of each module you have (the one that turns 32-bit mem into 4 bits, and the other that adds preamble bits, and so on), how do you control their sequential execution? instances work in parallel, so if you created 5 instances for five different modules, they will all start working together
<student> that means you should add a "Done" signal to each instance that's also passed to the next instance to inform it "Wait until I'm done and start execute"
<student> Am I missing something?
<ZipCPU> Yes! Exactly! Now you are starting to learn HDL. To get things to work right, the master task issues an enable line.
<ZipCPU> Each module (in this case) had a a "valid" line on its output, that was then fed into the next module.
<student> that enable lines keeps monitoring the output of each instance, change the "Done" signal state whenever an instance is done in order to start the next state, right?
<student> these enable lines*
<ZipCPU> Yeah, sort of ... in the case of the ethernet, I had to have a new value processed on every clock though.
<ZipCPU> There was no "wait until I'm done" ability.
<ZipCPU> However, every piece of logic required some time to accomplish.
<ZipCPU> Hence, I delayed the "output is valid" line until the output was done, and processed one step of every algorithm on every clock.
<ZipCPU> This would be the "pipeline" approach to the multiply from before that we didn't discuss.
<ZipCPU> In the "pipelined" approach, there is no "busy" flag. There is no "idle and waiting for data" state either.
<ZipCPU> There's one internal variable for ( X(1) * Y, X(n:2), Y, valid), and another
<ZipCPU> internal variable for ( X(2) * Y * 2 + [last accumulator output], X(n:3), Y, valid), and another for ...
<student> yea and so on
<ZipCPU> internal variable ( X(3) * Y * 4 + [the X(2) * Y * 2 +... output from before ...)
<ZipCPU> You get the idea?
<student> so that way no idle/busy
<ZipCPU> You can accept new data on every clock.
<ZipCPU> The trick is, how do you know on the output which output that was supposed to be related to?
<ZipCPU> I mean, suppose you wish to calculate X * Y + U.
<ZipCPU> X * Y won't be available for 20 clocks.
<ZipCPU> What do you do with U in the meantime?
<student> hmmm
<ZipCPU> If you wished to pipeline things, you'd need to place U into memory.
<student> it will stay idle in the first 20 cycles
<ZipCPU> Then, after 20 clocks, you would pull it out of a memory, and add it to the result of X * Y.
<student> yea
<ZipCPU> In the case of the network, the network just shoves data into the pipeline, and looks for valid data at the end. It doesn't need to keep track of anything else along the way.
<ZipCPU> In the case of the divide (state machine approach), the CPU it supports must come to a halt while it waits for the result from the divide.
<student> I see now the big picture, I think I understand now what does it mean to think as a "programmer" rather than an digital circuit designer.
<ZipCPU> ;) ---- I've played both sides of the fence.
<student> When I look at my Simplified DES code, I can see it's a really bad code, YES !!!
<ZipCPU> Can you? Then we've accomplished something!!!!!!
<student> ZipCPU I can't really thank you enough ! really!
<ZipCPU> Well, I accept cash, checks, or credit cards ... ;)
<ZipCPU> No, seriously, you are welcome.
<student> Oh not again lol
<student> Haha thanks x10^9
<ZipCPU> (Yes, I'm laughing here as well, although the bank account isn't doing so well ...)
<student> Believe me, it's the same here haha!
<student> I'm still a student
<student> studying computer and communication engineering
<ZipCPU> What school?
<student> anyway, one final simple request, any book you advice me to read, any general advices concerning verilog/HDL/digital design
<student> Engineering school
<student> was that what you meant?
<ZipCPU> "Engineering school", well, gosh, I figured that much ... no, the University of ... where?
<ZipCPU> The (what) school of technology ...?
<ZipCPU> What city, nation, etc.?
<student> oh LOL
<student> *face palm*
<ZipCPU> <Grin>
<student> anyway, Alexandria, Egypt
<student> that warm country u know
<ZipCPU> Wow, Egypt? Cool!
<ZipCPU> Well, let me ask another question: bachelors degree?
<ZipCPU> </grin>
<student> Yea, still studying to earn it
<ZipCPU> That's cool.
<ZipCPU> I ask because I've found a *really* cool set of videos that discusses how to build a computer and the components of such a computer.
<ZipCPU> It might be a touch more advanced than where you are at though.
<student> I'm interested to bookmark it if u don't mind sending it
<ZipCPU> Have you found fpga4fun.com?
<student> sharing it*
<student> yea
<student> and it's really useful, but I wanted to learn first from books tho
<ZipCPU> Ok, so here's the link (give me a moment to fat finger it in ...)
<ZipCPU> https://www.youtube.com/watch?v=nYVkMKx9Sao&list=PL8EC1756A7B1764F6
<ZipCPU> You might want to double check that I fat fingered it in right ...
<student> lol
<ZipCPU> Did I get it right? You should find "CS6810 -- Lecture 1. Computer Architecture"
<ZipCPU> By ... Rajeev Balsubramonian
<student> yeah, it's the CS6810 course
<student> yea
<ZipCPU> Ok, good.
<ZipCPU> How about the fpga4fun.com site?
<student> that's an advanced course, so back to the question
<student> You now have an idea of my level in Verilog, what do you advice me to do in order to upgrade my skills in digital design, HDL and Verilog coding?
<ZipCPU> Well, let's try this, do you have any hardware that you are working with?
<student> Yea, fpga4fun I had a look at it few months back, also opencores.org is amazing
<student> yea, I've got a mercury fpga from micronova
<student> spartan-based fpga
<ZipCPU> opencores.org is in the process of going bankrupt. Keep your eye on librecores.org.
<ZipCPU> Okay, cool. So here's the next task for you:
<student> was checking it out, seems interesting too
<ZipCPU> Get *every* interface available on that board working for you.
<student> Shall I reimplement each of those interfaces on my own?
<ZipCPU> This would include learning how to read/write the flash, reading and writing from the SRAM, playing music with the ADC, working on the LEDs, etc.
<ZipCPU> Good question.
<ZipCPU> I guess it's up to you.
<ZipCPU> If you choose to use someone else's code, be prepared to debug it ... and hence learn how it works.
<ZipCPU> Your first task with any FPGA board is always blinking the LEDs.
<ZipCPU> Proving that you have working logic.
<ZipCPU> Your second task is communicating between your computer and the board.
<student> yea, blinked those LED's multiple times, but I think I'm going to reimplement the wheel now since I just learned how to do HDL ...
<ZipCPU> This second task is *vital*. Without some form of communication, how will you know what the logic is doing within the board when it isn't working?
<student> aha
<ZipCPU> Yeah, "aha".
<ZipCPU> I've read countless requests for help that basically constitute, "My FPGA design isn't working and I don't know why."
<ZipCPU> You need to be able to know "why". That means you need the ability to "see" what's going on inside your board, at the speed of the boards logic, and learn what's working and what's broken.
<ZipCPU> Are you committed to Verilog?
<student> Not really, I only chose it because it's too similar to C (Programming perspective again)
<student> Do you advice me to go for VHDL?
<ZipCPU> If you are committed to Verilog, I'd then recommend "Verilator" to you. It turns Verilog into C++, allowing you to test your designs and debug any internal wires by "printf" whenever you want.
<ZipCPU> Sorry, I have no advice for you to go VHDL. I only know Verilog. ;)
<student> ah okay
<student> you don't recommend any book?
<ZipCPU> Sorry, I can't.
<ZipCPU> I didn't learn using any books. I learned by building, by trial and error, by Verilator, etc.
<ZipCPU> In order to recommend a book, I'd have to either tell you which book I used, or which series of books I have evaluated.
<ZipCPU> I haven't done any of those things.
<student> I see, that's okay.
<student> May I ask a final Out-of-topic question, How old are you?
<ZipCPU> If you'd like, I'll tell you how I managed to get off the ground in the first place ... ?
<ZipCPU> (I'm 45 years old)
<student> yea please, that would be great
<ZipCPU> For one of the jobs I was working at, the contractor delivered us a board with an initial FPGA configuration in Verilog.
<ZipCPU> The configuration was the "default" configuration that came with his delivery of the board.
<student> Oh, no doubts you are so experienced, I was just about to ask you how can I become such expert like you, I think experience by doing projects, trial/error would be your answer. :)
<ZipCPU> It showed how values could be "read" or "written" from/to the device.
<ZipCPU> It showed how the FPGA connected to a memory "bus" attached to the computer next door. (That computer was an ARM.)
<ZipCPU> My task was to get the FPGA to do a bunch of signal processing.
<ZipCPU> I worked slowly from that bus. First, I would create little tasks that would do one operation, and then I could read their results on the same bus.
<ZipCPU> So for example, start with an address that I could read/write from the bus.
<ZipCPU> Now I know the bus works.
<ZipCPU> Now, make a second address that is equal to the value at the first address ... plus some operation.
<ZipCPU> Then, as things got more and more complex, I did something rather novel.
<ZipCPU> I set everything up to where I could read any internal wires within the FPGA, but prevented the FPGA from clocking until I wrote to a "clock now" register.
<ZipCPU> Heheh ... I built that whole project without ever using a simulator. ;)
<ZipCPU> (Now I use Verilator---it can be a whole lot faster)
<student> How much was your experience in Verilog and HDL back then?
<ZipCPU> That was my first Verilog project. First.
<ZipCPU> I've never done anything in VHDL.
<ZipCPU> Well ... other than examine the VHDL code of students crying for help. ;)
<student> That iimplies this job took some time from you right?
<ZipCPU> It was a paid "job" at the time.
<student> I see
<student> So you made your experience only with trial and error
<ZipCPU> Pretty much.
<ZipCPU> That and ... watching what ISE would and wouldn't synthesize, and what did and didn't meet timing.
<student> That's pretty great, I think I should start as you said, know everything about my board, and try to use all its interfaces/peripherals
<ZipCPU> So ... that's what I started doing when I recently got into things.
<ZipCPU> I bought a Basys-3 board, and then tried to get all of the peripherals to do .... something ... for me. Anything, just to demonstrate I could control it.
<ZipCPU> The reason is more financially motivated than anything else.
<ZipCPU> Hardware costs money. I want to make the most of any of it.
<student> I see, my motivation is a bit different, as I said I'm still studying for my BS. degree, actually I once used FPGA in my school in Digital Circuit Design course, and never used it after than in school, since then I'm in love with digital design and I'm trying to learn every bit of it in my spare time
<ZipCPU> You may be able to tell from my nick name what part of my purpose is.
<ZipCPU> I've been working for some time to build a CPU within an FPGA.
<ZipCPU> I call it the ZipCPU.
<ZipCPU> It's a 32-bit, pipelined, wishbone compatible, von Neumann architecture, etc. CPU.
<ZipCPU> It's designed to be as simple on an architecture as possible.
<ZipCPU> I've gotten it down, in its smallest configuration, to 1200 6-LUTs or so.
<ZipCPU> I'm hoping to promote adoption of this CPU for ... whatever purposes anyone might have.
<ZipCPU> If you are at all interested, please feel free to ask.
<student> I took a look on your ZipCPU github repo
<ZipCPU> The entire CPU (and lots of projects that use it, together with their peripherals) is/are available under the GPL.
<student> yea sure, that's a project to consider looking at when I reach a good level in digital design and HDL coding
<student> Anyway, I'm sorry for wasting some of your time, and I'm really REALLY thankful to you for every bit of that conversation, it really cleared A LOT of things.
<ZipCPU> Glad I could help.
<ZipCPU> It must be pretty late there ...
<student> yea, it's almost 00:30 in here
<ZipCPU> I should let you get some sleep then.
<student> Haha thanks again for your time and effort.
<ZipCPU> My pleasure.
<student> Cya later maybe. :-)
<ZipCPU> Likewise.
* student has quit (Quit: WeeChat 1.6)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment