clifford changed the topic of #yosys to: Yosys Open SYnthesis Suite: http://www.clifford.at/yosys/ -- Channel Logs: https://irclog.whitequark.org/yosys
gnufan has quit [Ping timeout: 264 seconds]
kuldeep has quit [Ping timeout: 240 seconds]
kuldeep has joined #yosys
kristianpaul has quit [Quit: Lost terminal]
kristianpaul has joined #yosys
emeb has quit [Quit: Leaving.]
lutsabound has quit [Quit: Connection closed for inactivity]
emeb_mac has joined #yosys
rohitksingh_work has joined #yosys
rohitksingh_work has quit [Ping timeout: 252 seconds]
kuldeep has quit [Ping timeout: 252 seconds]
kuldeep has joined #yosys
rohitksingh_work has joined #yosys
seldridge has joined #yosys
_whitelogger has joined #yosys
seldridge has quit [Ping timeout: 240 seconds]
emeb_mac has quit [Quit: Leaving.]
FL4SHK has quit [Ping timeout: 240 seconds]
FL4SHK has joined #yosys
azonenberg_work has quit [Ping timeout: 272 seconds]
azonenberg_work has joined #yosys
<cr1901_modern> Yay I crashed nextpnr :)! With a 1300-line design.
<cr1901_modern> /me saved the offending design, will experiment later
gnufan has joined #yosys
<cr1901_modern> incidentally, arachne doesn't like this design either... will have to play around
<cr1901_modern> (just takes forever tho, doesn't crash)
[X-Scale] has joined #yosys
X-Scale has quit [Ping timeout: 245 seconds]
[X-Scale] is now known as X-Scale
<cr1901_modern> Maybe it's just me, but is arachne supposed to take significantly longer if you add a PLL to a medium sized design (about 50% of the 8000 Logic Cells on an lp8k used), and upping the clock freq is the only change?
kraiskil has joined #yosys
q3k1 is now known as q3k
promach has quit [Quit: WeeChat 2.3-dev]
sensille has joined #yosys
s_frit has joined #yosys
<ZipCPU> Good morning all!
<ZipCPU> sensille and I have been chatting about interpolation in ##fpga, and I asked him to bring the conversation here to this channel.
rohitksingh_work has quit [Read error: Connection reset by peer]
<ZipCPU> He'd like to build a 3d print-head controller, with interpolation requirements described here: http://3dpfs.sensille.com/index.php?title=Mathematics
<ZipCPU> So far, we've been discussing the basics of interpolation, as I described here: http://zipcpu.com/dsp/2018/01/16/interpolation-is-convolution.html
<ZipCPU> In that article, I start out by arguing that many interpolation developments get the assumptions wrong, and so to start a development on interpolation, I start with the following assumptions:
<ZipCPU> 1. A linear solution is desired. i.e., if you give it two discrete sequences, x0[n] and x1[n], then the interpolated of x0[n]+x1[n] should be the sum of the two interpolated results, x0(t)+x1(t). (Scale applies too)
<ZipCPU> 2. The second big assumption is that the solution needs to be *shift invariant*. What I mean by this is that if the input samples all shift by one (or more) samples in time, the solution should also shift.
<ZipCPU> Splines don't fit these assumptions. They are defined across a bounded window. If you shift the spline development, you'll have samples falling off the end of the window. Worse, solving the spline linear system within an FPGA as part of a real-time controller isn't a reasonable requirement.
<ZipCPU> While linear and quadratic interpolants meet this definition, you can do *much* better in terms of performance.
<ZipCPU> Oh, I was asked about Tchebyshev polynomials as well .... those have the same problems as splines: they are defined on a fixed window of data, and so they are not shift-invariant.
<ZipCPU> Other assumptions: 1) that the incoming signal is sampled (this just makes things easier), 2) the incoming signal is infinite in length. (This basically means that the signal is longer than the processing window we'll apply to it.)
<ZipCPU> 3) All time samples are equidistant. (We'll need to break this in a bit in order to meet the requirements)
<ZipCPU> sensille: Have any of these assumptions ruled out your application yet?
<sensille> just to clarify: you are assuming that the interpolation happens completely within the fpga, right? otherwise i could solve spline equations on the host and just expand it on the fpga
<ZipCPU> Yes.
<ZipCPU> Except ....
<ZipCPU> In order to get the constant |v| that you want, the PC is going to need to be a part of the solution as well
<sensille> please think more of a |v| controlled by a different function, as the head needs to speed up and slow down from time to time, too
<sensille> |v| only holds most of the time
<ZipCPU> Ok, now, let me propose that the solution to the above assumptions is a piecewise polynomial, that interpolates between one x value and the next.
<ZipCPU> (I'm going to ignore y for now, but all of what takes place with x will later apply identically to y--with the exception of |v|)
<sensille> ok
<ZipCPU> Let's now think about what we want: we want a function that is continuous. Hence the interpolation should approach x[n] from the left, and from the right. There should be no discontinuities.
<ZipCPU> That eliminates traditional polynomial fitting.
<ZipCPU> The traditional polynomial fit will take a section of n points, and fit a polynomial to it. When you then switch to the next n points, you have no guarantee of continuity, and the solution often jumps.
zino has quit [Quit: Leaving]
<sensille> (no discontinuities in the first 2 derivatives)
<ZipCPU> sensille: That's where I'm going next ;)
zino has joined #yosys
<ZipCPU> On the blog, I've only presented the math for no discontinuities in the first derivative, but once you understand the approach its easy enough to extend.
<ZipCPU> For example, I've extended this to 5th and 6th order polynomials--the derivation is annoying, but they work quite well.
<ZipCPU> I've also used this approach for satellite propagation--it works quite well there too.
<ZipCPU> So far, we've focused on this article: http://zipcpu.com/dsp/2018/01/16/interpolation-is-convolution.html , one that proves that under the above assumptions, interpolators are nothing more than convolutions.
<ZipCPU> Why this is important is because it allows us to take the Fourier transform of an interpolator. You can then compare frequency responses between interpolators to quantify which one is better (or worse) than any other.
<ZipCPU> Quantification is key to any problem.
<ZipCPU> Ok, let's come back to continuity.
<ZipCPU> Suppose we create a piecewise polynomial that interpolates the sequence 0,0,0,0.....,0,1,0,.....,0,0,... etc. Also known as the Kronecker delta function IIRC.
<ZipCPU> Here's where linearity becomes useful.
<ZipCPU> A polynomial that goes through the delta function can be scaled and shifted so that it goes through point x_k[n] (for arbitrary n)
<ZipCPU> Further, if we add multiple of these polynomials together, one scaled and shifted for every x[n] input value, then you get your final interpolated sequence.
<ZipCPU> My point is, all you need to design is the first polynomial: the one that interpolates the kronecker delta: 0,0,0....0,1,0,,....., etc.
<ZipCPU> If you design that one polynomial so that it is continuous, and continuous in its first, second, ... nth derivatives, then any linear combination of polynomials like this will fit your incoming data.
<ZipCPU> sensille: Making sense so far?
<sensille> wait, i'm still thinking about addition point. i have one polynomial going through one point, and another going through another point, why should the sum of both go though any of the points?
<ZipCPU> Good question, and a fundamental one too!
<ZipCPU> Remember, we've initially assumed that all of our points are equidistant, right?
<sensille> yes
<ZipCPU> (We'll break this later, but it's important for now)
<sensille> ah, wait
<ZipCPU> Yes?
<sensille> i think i got it
<ZipCPU> The full concept?
<ZipCPU> Or ... at least how you can add two piecewise polynomials together, one interpolating through x[n] and another interpolating through x[n+1], and get a polynomial that now interpolates through both?
<sensille> i just assumed it only goes through the delta function where it hits the 1, but it also has to go through all the zeros
<ZipCPU> Yes!
<sensille> and with the equidistance it's clear that they don't overlay on the point to interpolate
<sensille> *points
<ZipCPU> Now, let me ask you to pull up this page: http://zipcpu.com/dsp/2018/03/30/quadratic.html
<ZipCPU> There's a figure, between Fig 5 and Fig 6 on that page, that shows the concept of what I'm talking about.
<sensille> the figure without name
<ZipCPU> It's a piecewise polynomial of five parts, symmetric about zero, that goes through 1 at t=0, and 0 at t=any other integer.
<ZipCPU> Yes, that one.
<ZipCPU> That figure shows a solution to this problem ... built from some assumptions like what we are working with.
<ZipCPU> Sadly, it doesn't capture the continuous in the second derivative property you want, but it does show the concept.
<ZipCPU> To get the second derivative, you'll need to repeat the derivation, and also add one more degree to your polynomials.
<sensille> yes
<ZipCPU> In this example, I set up a series of polynomials with an assumed form.
<ZipCPU> I then also set up a series of equations to get the coefficients for the various polynomials.
<ZipCPU> 1. The piecewise polynomials must go through all the required points: through one when t=0, and through zero when t=any other integer.
<ZipCPU> 2. If you feed the design a constant, x[-2]=x[-1]=x[0]=x[1]=x[2], etc., the resulting polynomial should be the same constant.
<ZipCPU> 3. Same thing but for lines, if x[n]=k*n, then the result of the interpolator should be a simple line.
<ZipCPU> 4. Same thing for quadratics
<ZipCPU> 5. We mentioned continuous. This just becomes an equation in the setup of the interpolator
<ZipCPU> 6. You'll want to set up two more equations: continuous in the first and second derivatives. (My development in http://zipcpu.com/dsp/2018/03/30/quadratic.html doesn't go that far, but it's not that hard to do.)
<ZipCPU> One of the reasons why I stopped where I did was that the coefficients that resulted from the development made for nice, easy to implement on an FPGA, coefficients.
<ZipCPU> Your own development might well have some more complicated coefficients
<ZipCPU> In case you've gotten lost, I do show the FPGA code for the quadratic developed in this fashion at the bottom of http://zipcpu.com/dsp/2018/03/30/quadratic.html
<sensille> from the picture alone i'm currently trying to figure out why you can't do with less pieces for the definition
<ZipCPU> sensille: You can do it with more and less pieces. The quality of the solution you will get, however, will be dependent upon the number of pieces.
<sensille> the less overshoot the better, i guess
<ZipCPU> You also need to be sensitive to whether or not the equations have a solution.
<ZipCPU> If you don't get any solution, you'll need to either extend the number of polynomials, or increase the degree, in order to handle having enough free variables for all of your equations.
<sensille> i see
<ZipCPU> Does this part make enough sense that I can then move on to implementation?
<sensille> ok, so i have all my samples, each one defining a piecewise polynomial. to interpolate i need to add the polynomials for 5 points, right?
<ZipCPU> Yes, you'll need to add all the polynomials together to get one that interpolates between any two points.
<ZipCPU> Hence, you'll have a section of your data of interest, say x[n-k] to x[n+k]. Each point will have a polynomial associated with it by itself, and all of these will need to be summed to get a polynomial going between x[n] and x[n+1].
<ZipCPU> So, here's a comment that's missing: when you increase the degree of your solution, you'll want to alternate between a polynomial defined around x[n] and one defined between x[n] and x[n+1]
<ZipCPU> Hence, for a 3rd degree polynomial, interpolating between x[n] and x[n+1] works "better" (i.e. easier to get a linear equation solution) than one that interpolates between x[n-1/2] and x[n+1/2]
<ZipCPU> For a 4th degree polynomial, you'll want to return to being centered around the points again.
<sensille> i think i'll come to that when i try to figure out the solutions later this day
<ZipCPU> Now, let's move to implementation.
<sensille> ok
<ZipCPU> It turns out that summing these polynomial coefficients together is the same as applying a basic convolution (i.e. digital filter) to the incoming data.
<ZipCPU> Hence, if I filter the incoming data with one filter, I get the linear coefficients. Another filter will give me the quadratic coefficients. A third filter will give cubic coefficients, etc.
<ZipCPU> This is just how you are implementing the summation we've described above: as a series of convolutions.
<ZipCPU> Convolutions are well studied in filtering applications, and so I have several blog posts on how to do that.
<sensille> ok, so i get my coeffcients
<ZipCPU> If you then line up the convolution results, you have your 2nd, 3rd, 4th (or whatever) order polynomial coefficients to interpolate near x[n].
<ZipCPU> After that, you just compute (a0*t+a1)*t+a2)*t+... etc
<sensille> then i need to evaluate the polynomial between the points
<ZipCPU> 't' in my evaluation is a number running between 0 and 1. The consequence of this is that t^n gets *really* small as n increases.
<ZipCPU> Hence, you'll want to watch your bit allocation. Expect that highest coefficient to have only a small contribution.
<ZipCPU> You can therefore adjust the location of its fixed point to get the most precision from it.
<ZipCPU> Same goes for all the other coefficients.
<ZipCPU> Ok, let's go back to your requirements, http://3dpfs.sensille.com/index.php?title=Mathematics, and see how we did.
<ZipCPU> 1) I threw away the original curves in favor of a sampled representation.
<ZipCPU> 2) We haven't gone back to movement speed yet. We still need to hit on that one.
<ZipCPU> 3) Continuous in position, speed, and acceleration, bounded in jerk--yep, got that one
<ZipCPU> 4) Bounded deviation from the curve ... at this point, that's just a matter of bit allocation
<ZipCPU> 5) |v| bound ... still need to come back to that requirement
<ZipCPU> 6) Implemented on an FPGA--I've given a demo solution for that one
<ZipCPU> 7) The step size and clock .... that's going to depend upon how fast your FPGA can implement the multiplies necessary for the convolution. Have you chosen an FPGA?
<ZipCPU> 8) I've done all of the above in cartesian coordinates. I'm going to argue that this is sufficient.
<ZipCPU> I think that's all of your requirements, right?
<sensille> i currently use an artix 7, but that'll be too expensive for others to use. more like a lattice ice40 hx8k
<shapr> yay!
<ZipCPU> Mornin' shapr!
<shapr> GOOD MORNING ZipCPU!
* shapr does cartwheels
<shapr> sensille: I convinced my coworkers to buy these: https://www.crowdsupply.com/qwerty-embedded-design/beaglewire/
<ZipCPU> sensille: This should work just fine on an Artix-7, perhaps even the ecp5 as well. It's going to need those DSP elements.
<sensille> re 8) if it can approximate any curve, i can just transform the points into the target kinematics
<shapr> ooh, I should check the history to see what sensille is doing
<shapr> ZipCPU: My class starts a week from today! I'm both scared and excited!
<ZipCPU> shapr: He's building a 3d printer controller, and wants to know how to drive it.
<shapr> oh cool!
* shapr reads
<shapr> first thought, can't you use PID or something along those lines to get smooth movement from one position to another?
<ZipCPU> sensille: While you might manage to use an iCE40, I'm not sure you'd meet your timing requirements when doing so.
<sensille> ZipCPU: re 4): isn't it more a matter of the point distance, given the fpga precision is "enough"?
<ZipCPU> sensille: How do you mean?
<shapr> ok, I am not qualified to be part of this discussion
<ZipCPU> shapr: Lol!
<ZipCPU> shapr: The blog articles definitely help understanding the discussion--they've got lots of pictures to them.
<shapr> from what I just read, it looks like motor controllers can only handle straight line moves?
<ZipCPU> We're talking about straight lines, curved lines, sinusoidal lines, you name it lines ...
<shapr> oh yeah "current (lacking) solution" sounds like the "etch-a-sketch" approach
<ZipCPU> Yes
<ZipCPU> Exactly
<shapr> aw man, they don't call it snap, crackle, and pop?
<shapr> so much for 80s commercial references
<ZipCPU> lol
<sensille> ZipCPU: we haven't talked about how to choose the sampling points yet. right now i'm only guaranteed to get a smooth curve, but the deviation from the orginal curve is not yet bounded
<sensille> shapr: "current solution" is much better than what other home printers do
<ZipCPU> sensille: The sample rate will bound the deviation from the original curve. Remember how I discussed the Fourier transform of the solution? If you "sample" point near enough, the curve will be a nice fit. The closer, the better.
<shapr> oh, that's good, I know nothing about 3d printers
<ZipCPU> However, I'm guessing that if you control the two derivatives (i.e. insist on continuity), you'll get the low deviation you want.
<ZipCPU> (That follows from the FFT-based analysis.)
<ZipCPU> Are you ready to discuss sampling interval?
<shapr> sensille: since ZipCPU does not advertise, I will say that there is a patreon to support ZipCPU's free advice
* ZipCPU thanks shapr
<shapr> :-)
<shapr> oh, I should up my subscription level, even if all my questions are Haskell related
<sensille> yes, i am
* ZipCPU doesn't know Haskell (yet), and has yet to answer a single Haskell question.
<ZipCPU> sensille: The sample interval at this point is really the elephant in the room.
<ZipCPU> By adjusting the sample interval, you can control |v|.
<ZipCPU> That's how you will go about keeping |v| constant.
<ZipCPU> Hence, if you just assign samples within your design to the points the FPGA will interpolate, you'll get one velocity solution.
<ZipCPU> |v| will be uncontrolled.
<ZipCPU> If you then move your samples closer together anywhere |v| is too fast, or separate them further apart anywhere |v| is too slow, you should get your |v| control back.
<ZipCPU> That work can all be done inside the CPU part of the controller
<ZipCPU> Leaving the FPGA to only interpolate the sample points that result.
<ZipCPU> Further, because you know the equation the FPGA will be evaluating, you can also guarantee (in the same piece of PC software) that the FPGA solution remains within the given bounds.
<ZipCPU> There's another solution I just thought of as well: Inside the PC, you could calculate time samples to pass to the FPGA. Hence, you could sample however, but then send time (a.k.a. speed) as a separate sequence.
<sensille> is this that same as setting the sampling points at equidistant arc lengths?
<ZipCPU> In this latter approach, the FPGA would be passed a series of x[t],y[t] values, together with a separate set of t[n] values.
<ZipCPU> Not quite, but setting sample points at equidistant arc lengths might be a better idea/description of what you wish to do.
<ZipCPU> sensille: So ... I've presented what I have. Does this sound doable at all?
<shapr> ZipCPU: if I sent you a booting/working BeagleWire would you be interested in doing a review on your blog?
<sensille> can i assume that the parametrization of the polynomials in t is nearly the same as in arclength?
kraiskil has quit [Quit: Leaving]
<ZipCPU> I'm not sure.
<ZipCPU> I think there's another bit of work that needs to take place to ensure that.
<sensille> but the same question holds for my proposed solution
rohitksingh has joined #yosys
<ZipCPU> Go on.
<sensille> also, why not calculate the polynomial addition on the host and send only the parameters to the fpga?
<ZipCPU> You could
<ZipCPU> You'd need to check the bandwidth on your comms channel, but that would work.
<ZipCPU> Oh, there's some other benefits I was going to share ...
<ZipCPU> Because you are using a polynomial, it will be very easy to calculate speed and acceleration (and even jerk, etc.)
rohitksingh has quit [Ping timeout: 244 seconds]
<sensille> i'm still at the |v
<sensille> |-point
<sensille> and how to do smooth accelerations
<ZipCPU> You have smooth accelerations, based upon your construction of the piecewise polynomial. That's guaranteed at this point--although you'll need to do a different set of equations to derive the polynomials than the ones I used.
<ZipCPU> So, the difficult part I'm having with the |v| issue. Part of the reason why I'm struggling with this one is that path length is an ugly multi-dimensional integral involving Squar root of (x(t)-x(t+dt))^2 + (y(t)-y(t+dt))^2
<sensille> so when i put my points closer and closer together, i get a smooth acceleration
<ZipCPU> I looked this up a bit ago. You'll find the equation in a 3rd semester calc book.
<ZipCPU> Yes, you get a smooth acceleration.
<ZipCPU> By "smooth" I mean that it is guaranteed to be continuous.
<ZipCPU> There is an issue of whether or not your motor can handle that acceleration.
<ZipCPU> But it will be continuous, and therefore "smooth"
<sensille> yeah, the |v| is what makes my head hurt for a long time now
<sensille> otherwise i could just implement bezier curves in the fpga
<ZipCPU> So, at this point, you have a complete solution for the path. You just now need to go back and adjust the speed of that path.
<ZipCPU> To do that ...
<ZipCPU> Start by evaluating and plotting |v|.
<ZipCPU> I'm guessing that a simple ad-hoc algorithm can help you adjust the |v| points.
<sensille> so many thanks for the walk through. i think i got the main ideas and can take it from there (apart from |v| ...)
<ZipCPU> I've wondered if Remez exchange might help ...
<sensille> can you please share your thought on why you think my solution is too complicated and inferior?
<ZipCPU> But, at least at this point you have a description you can calculate |v| from, and then work with it towards a solution.
<ZipCPU> Ahh ... yes
<ZipCPU> "Too complicated and inferior" is based upon 2 things:
<ZipCPU> 1) I thought I could do better than a 5th order polynomial. So far, I've gotten you down to a 4th order polynomial, that guarantees smooth acceleration and velocity.
<ZipCPU> Why 4th? 'cause I've done the equations before.
<ZipCPU> 2) By converting everything to cartesian coordinates, you've greatly simplified the problem and its implementation.
<ZipCPU> I was hoping I might get you down to a 3rd degree polynomial, but I must apologize ... when I checked my notes against your requirements, I don't think you'll be successful at 3rd degree.
<ZipCPU> Does that make sense?
<sensille> on the other hand my solution (hopefully) already solve the speed problem
<sensille> because it is given at start and end
<ZipCPU> Would you like to share how you managed to solve the speed problem?
<sensille> for the 5th order polynom i have 6 variables. i fill them with x(t), v(t), a(t), x(t+1), v(t+1), a(t+1)
<ZipCPU> Go on
<sensille> giving me a curve that a least is guaranteed to start and end with the given speed
<sensille> but i have no guarantee that it doesn't vary wildly in between
<sensille> i guess that's a question on how i choose the points
<ZipCPU> Yes
<sensille> yes to wildly or yes to the choosing of points?
<sensille> or both?
<ZipCPU> Yes to the choosing of the points
<ZipCPU> Controlling |v| is down to how you go about choosing your points.
<sensille> no, i mean in my solution
<ZipCPU> In both solutions
<sensille> in my solution, v is an input parameter
<ZipCPU> The obvious answer to |v| varying wildly is to "control" it. That is, to create a solution where it remains constant.
<ZipCPU> We discussed using a constant arc length for that purpose. I think that's a wonderful starting point.
<sensille> in both our solutions the interesting question is re paramterization of t vs. arc length
<sensille> if it is nearly equivalent
<ZipCPU> If you just set the arc-length to be a constant, won't that solve the problem?
<sensille> afaik the necessary integral for reparametrization is not generally solvable
<ZipCPU> Solving for arc length shouldn't be all that difficult.
<ZipCPU> If you already have a representation for the curve you need to travel, you just need to calculate arcs along that curve.
<sensille> arc length as sqrt(dx^2+dy^2)
<ZipCPU> While the integral may be difficult, numerical approximations of it need not be.
<ZipCPU> Yes, exactly.
<ZipCPU> How are you at doing integrals numerically?
<sensille> on the host? there are libraries. on the fpga? bad
<sensille> my main question at the moment is if the arc length is linear in t in any of our solutions
<sensille> between two points
<ZipCPU> I'd do the integral on the host.
<ZipCPU> I would recommend making arc length constant between points.
<ZipCPU> Or ... is your question about whether |v| would suddenly change between points, as part of the interpolation?
<ZipCPU> Once you have your point x(t) a function of linear t (as we've described above), calculating dx^2+dy^2 is just annoying, it's not hard.
<sensille> for all t1 <= t <= t2, is interpolate(t) ~= interpolate(arclen(t-t1)/arclen(t2-t1))?
<sensille> that's my question, or nearly
<ZipCPU> I think the answer to that is trivially No, but that you haven't asked the question you want to ask.
<sensille> missing a +t1 in the second argument
<ZipCPU> Let's assume you have two arbitrary functions tracing a path in x,y, (x0(t),y0(t)) and (x1(t),y1(t))
<ZipCPU> Where x1(t)=x0(t0+a1 t) and likewise for y1
<ZipCPU> In other words, both paths trace the same arc, just at different times.
<ZipCPU> The two paths may well have different speeds, but will still trace the same points.
rohitksingh has joined #yosys
<sensille> yes, but is this the case?
<ZipCPU> So, let me rephrase your question.
<ZipCPU> You have a path, x(t),y(t), and you want to know if x(g(t)),y(g(t)) will trace the same path?
<sensille> no
<ZipCPU> Isn't that your question?
<ZipCPU> We are talking about a function g(t) = a linear function of t, right?
<sensille> my question is if x(t) - x(g(t)) < epsilon for all t
<sensille> no, i don't know what g(t) is
<sensille> sorry, have to go soon, will be back in 1-2 hours
<ZipCPU> g(t) is just an arbitrary function where g(0) = 0, and g(T) = T. (i.e., it starts at t=0, and ends at t=T) It also needs to be monotonic.
<sensille> i'll try to rephrase the question later
<ZipCPU> That's what we've been discussing this whole time.
<ZipCPU> Ok
<ZipCPU> I'll be here.
<sensille> but yes, your definition of g(t) fits mine, it is not linear
<ZipCPU> Then your question of whether or not x(t)-x(g(t)) < epsilon is not the question you want to ask.
<ZipCPU> Because x(t) and x(g(t)) will trace the same path, but at different speeds, x(t) may not be the same as x(g(t))--because one path might get to a point before the other, and go on.
<sensille> maybe it is just too obvious for you that i can't get my point through, or you've already answered it long ago ;)
<ZipCPU> Sigh. This could well be the case.
<ZipCPU> Let's re-engage when you get a chance again.
<sensille> at least i know now why the question i asked is not the question i wanted to ask
<mattvenn> familiar feeling
<edmoore> yep
<mattvenn> great discussion btw
<edmoore> the sign of learning tho
<sensille> ok, later :)
<shapr> howdy Ed
<ZipCPU> edmoore, mattvenn: Thanks!
<edmoore> hi shapr
<edmoore> i've just returned from MEFcamp
<edmoore> EMF*
<edmoore> it was fun
<mattvenn> I just watched the talk about the crazy badge
<mattvenn> did you get one?
<ZipCPU> Here's a question for all listening: We kind of hijacked the #yosys channel for this discussion. It's not specifically a #yosys discussion, but rather a theory discussion behind FPGA stuffs. I chose #yosys because it would be recorded. Question for all: Should I do this again, or pick another channel instead?
<mattvenn> this one is good for me
<shapr> oh, buncha people I know were at EMF camp, how was it?
<shapr> ZipCPU: discuss here where it's recorded
<ZipCPU> Thanks, shapr! mattvenn!
<edmoore> yeah i like good chats like that. it's not like this is some madly busy support channel where it'd get in the way
<edmoore> i did get a badge!
<edmoore> shapr: it was really fun, I have some ideas for some struff to make for the next one
<edmoore> i took my icestick and gps stuff to play with but only spent about 3hrs hacking in the end, i was mostly just enjoying other talks and installations and things
<edmoore> and the puzzle/challenge
<shapr> sounds like fun
<mattvenn> has anyone played with picorv32? I'm trying to add extra registers for custom peripheral control and am getting stuck
<ZipCPU> I think daveshah has.
<shapr> so I've heard about crossing clock domains in FPGAs, is there where you have two different external clocks and need to get data back and forth?
<mattvenn> simpler
rohitksingh has quit [Ping timeout: 245 seconds]
<mattvenn> here's the gpio register
<ZipCPU> shapr: Sort of
<mattvenn> and then here's the C firmware that will read and write to that register
<ZipCPU> shapr: The idea is that you have some signal defined on one clock, and you want to read and do things with it on another. You don't need to go in the other direction as well to be a CDC.
* ZipCPU contemplates making a picorv configuration for AutoFPGA
* shapr thinks about that
<shapr> ok, that makes sense
<ZipCPU> shapr: Be aware, pins defined external to the FPGA are usually defined in a clock domain not common to the FPGA
<ZipCPU> Hence, inputs need some form of CDC work before you can do anything with them.
<ZipCPU> For your GMC, the GMC provides the clock, so if you are careful, you shouldn't need any CDC to work with it.
<shapr> well, I've decided to make everything more exciting, now I'm trying to port the existing clash-lang blinky code to ice40
<shapr> from reading the sources, it seems to run fine on Xilinx and Intel, because there's "import Clash.Intel.ClockGen" and one for Xilinx
<shapr> so I'm trying to figure out how to write a module "Clash.ice40.ClockGen"
<shapr> see, now you have your first Haskell question ;-)
<ZipCPU> What FPGA do you have? As in which type of iCE40?
<shapr> this is a beaglewire, let me check
<shapr> hx4k according to PCB screenshots
* shapr checks the actual board
m4ssi has joined #yosys
<ZipCPU> Cool: you have an hx8k. That makes this easier.
<ZipCPU> Next question, what speed is the GMC clock?
<ZipCPU> Is it 50MHz?
<shapr> pretty sure it's 100MHz
<shapr> says "BeagleWire Peripherals: 100Mhz external clock"
<ZipCPU> Oohh, okay, ouch. I've got several loads that would struggle to hit 100MHz. You'd be more comfortable at 50MHz.
<shapr> loads?
<ZipCPU> Designs
<shapr> oh!
<ZipCPU> That's not to say that you couldn't hit 100MHz, just that .... you'd have to work hard to do that from the beginning.
<ZipCPU> So, there's two answers to lowering hte clock speed. The "right" answer, and the "wrong" one. (I use the "wrong" one)
<ZipCPU> The "right" answer is to use one of the PLL's on the board and adjust your clock speed.
<shapr> the answer I've seen before is "feed counter from clock, use higher bits of counter"
<ZipCPU> Be careful how you do that: the PLL's require parameters that aren't trivial to derive. Use the program "icepll" to get them.
<ZipCPU> shapr: That's the wrong answer.
<ZipCPU> Here's why I'm using the wrong answer in my designs tho:
<ZipCPU> The iCE40 PLL is tied to some specific pins. If you use it, you may no longer get the special pin I/O function you want. For exmple, if I used the ice40 PLL's, I wouldn't be able to access the SRAM on my icoboard.
<ZipCPU> A later design adjusted which pins talked to the SRAM, but ... suffice it to say there's a board problem out there with some of the boards.
<ZipCPU> Now, if you only want to drop the speed by a factor of two, always @(posedge i_clk) s_clk <= !s_clk; works. Once you do that, you should then place s_clk into a global buffer and use it for all your 50MHz clocking needs.
<ZipCPU> Be aware that this approach has problems
<ZipCPU> For example, there's no control over the delay between the original 100MHz clock and the 50MHz clock that results from it.
<shapr> why would I want to control the delay?
<ZipCPU> Hence, you'll want to "control" (i.e. CDC solution) any logic moving from the 100MHz clock to the 50MHz clock.
<ZipCPU> shapr: Were you around when I was trying to debug kc5tja's design the other day? ;)
<shapr> I wasn't paying attention
<ZipCPU> He was sending a clock to an output port to control his flash memory.
<shapr> ok
<ZipCPU> A minor, and inconsequential, change to his design adjusted the phase of the outgoing clock, and hence broke his controller.
<shapr> hm
<ZipCPU> We fixed it by forcing the design to use an SB_IO primitive.
<ZipCPU> You just need to know what you're doing and you should be fine.
<shapr> what's that?
<shapr> SB_IO?
<ZipCPU> Yes. That's the name of the hardware I/O primitives on every iCE40 I/O port. It connects your logic to the design.
<shapr> oh, ok
<ZipCPU> If you force the design to use an SB_IO port (yosys doesn't do this automatically), then you guarantee the placement of where the I/O logic will be.
<shapr> there's so much I don't understand
<ZipCPU> But learning is fun!
<shapr> true
<shapr> but now I have a sort-of deadline :-)
<shapr> I also found out that half my 'students' have already had a term in college doing FPGA design
<ZipCPU> Will you be needing the GMC port?
* ZipCPU hopes the answer is "no"
<ZipCPU> ;)
<shapr> that's the GPMC that shuttles data from the beaglebone to the beaglewire cape?
<ZipCPU> Yes.
<shapr> I think I will need it at some point
<shapr> certainly not right away
<shapr> but I'm trying to run ahead of my students
<ZipCPU> That will be your most difficult challenge, IMHO
<ZipCPU> How far have you managed to get?
<shapr> I thought I had the parts figured out, but I had some problems
<ZipCPU> Oh, wait, you are using Haskell?
<shapr> someone suggested I talk to the creator of the BeagleWire, since he was on the same IRC channels
<shapr> not yet!
<shapr> starting out with verilog
* ZipCPU breathes a sigh of relief. He doesn't know how to help folks using Haskell.
<shapr> the Haskell part is for me, there's job potential there
<shapr> the class itself is "learning FPGA dev"
<ssb> shapr, for reference about clock domain crossing: http://www.sunburst-design.com/papers/CummingsSNUG2008Boston_CDC.pdf
<shapr> which for now means verilog and basic stuff
<shapr> ssb: thanks!
<ZipCPU> Google simple clock domain crossing
<shapr> ZipCPU: GPMC use: found out that m_w created beaglewire, asked him for the memory offset
<shapr> he said it's in the device tree file and gave me a link
<shapr> so I wrote some python to attempt to mmap that address into /dev/mem, but consistently got access denied, even as root
<ZipCPU> I'm actually concerned about timing while using the GPMC, and making sure you do the task reliably.
<ZipCPU> Really?
<ZipCPU> Access denied?
<shapr> you said something about the csn and ein pins, but I have no idea what that means
<ZipCPU> Sounds like the memory isn't there. Perhaps you didn't turn it on or some such.
<shapr> so my next steps are:
<ZipCPU> Check the configuration registers for the GPMC I/O's
<shapr> figure out what kind of memory is on the beaglewire, then I can at least figure out which mode the GPMC is using out of its many modes
<shapr> figure out what ein and csn mean (pretty sure csn is chip select, but what does that really mean to me?)
dxld has quit [Quit: Bye]
<ZipCPU> What kind of memory is on beaglewire? Memory mapped I/O! In other words, you get to define/create it.
<shapr> good question
<shapr> wait what?
<shapr> I get to create it?
<ZipCPU> Yes!
<ZipCPU> That's the fun part of any project.
<ZipCPU> The design you just linked already does some of that. It turns the LED's into a memory address. Write that memory, and the LED's change.
<shapr> ok that's my next goal
<ZipCPU> That's not really "memory", but it's an example of how you can "create" it
<shapr> but how the heck do I write the memory?!
<shapr> my goals are data from bbb to fpga, and data from fgpa to bbb
dxld has joined #yosys
<ZipCPU> At BBB's control
<shapr> they should both be able to write to each other's memory somehow, right?
<ZipCPU> No
<ZipCPU> That's too hard.
<shapr> and I know the GPMC is the machine that does that
<shapr> oh?
<ZipCPU> What you want instead is for the BBB to create read/write requests to your "design", not to the memory within it.
* shapr thinks about that
<ZipCPU> For example, you might write to an address within the design, which might then cause a serial port to start transmitting
<ZipCPU> Reading from another address might read the result of a serial port.
<shapr> ok, so ... the GPMC can read/write data to/from the BBB memory, and the sdram on the beaglewire?
<shapr> I somewhat understand that
<shapr> I mean, I get that it's a thing
<ZipCPU> Every bus needs a master. Do you intend to master the GPMC bus from the FPGA, in addition to the BBB?
<shapr> no idea
<ZipCPU> I can't remember if the BBB even allows that. It might, I just can't remember.
<ZipCPU> Let's just stick then with the BBB controls every transfer.
<shapr> fine with me :-)
<shapr> I have no clue, just trying to 1. understand what's possible 2. understand what's easy 3. teach it to others!
<ZipCPU> BBB reads from the bus , FPGA returns the value. Simple enough. It's not really a read from memory though--it's a bus read. What's on the other end might be memory, or it might not be.
<ZipCPU> shapr: The bus tends to be hard. I'd teach the students how to use someone else's bus solution, rather than teaching them how to get the bus right.
<shapr> ohhhh
<shapr> ok this makes more sense now
<ZipCPU> One particularly difficult problem associated with the bus: How do you know you got it right? How can you tell if there's a bug? If you are using the bus to communicate, then debugging it can get really hard.
<ZipCPU> Worse, if you make a mistake, you might lock up the BBB hard.
<shapr> ok, I have an idea
<shapr> I can write verilog to send a test pattern on the bus
<ZipCPU> Careful, that's not the write words
<shapr> and then check that with C code that talks to the GPMC
<shapr> uh oh
<ZipCPU> If the FPGA is the bus slave, then you can't "send a test pattern" to the bus
<ZipCPU> The slave can only respond, it cannot initiate a transfer
<ZipCPU> You can try reading and writing test patterns. That's a good start.
<ZipCPU> As in, the BBB would do the reading and writing, and the FPGA would respond to those requests
<shapr> ok, that makes sense
<shapr> so now I just need to figure out how to talk to the GPMC (bus?) from C code
<shapr> ZipCPU: does the ice40 have internal PLLs?
<ZipCPU> Yes.
<shapr> I got in contact with the clash-lang author
<ZipCPU> I think it's got either 1 or 2.
<ZipCPU> It's not much.
<ZipCPU> Be aware when using them that you might break an I/O. If that happens, your design will fail to build.
<shapr> I'll try to remember that, hopefully it'll come back to me when I need to know it.
<shapr> ZipCPU: so, if I have the memory address, I just write c code like mattvenn linked to write to memory?
<ZipCPU> Meh .... sort of
<ZipCPU> Because you are running from a full Linux distro, you'll need to get the pointer to the address from memmap
<ZipCPU> *mmap
<ZipCPU> It's not a fixed location.
<ZipCPU> It might change from one program accessing BBB to another.
<ZipCPU> It's not that the actual hardware address changes, rather the problem is that the address seen by your program might change.
* shapr grombles
<ZipCPU> Yes. Go on.
<shapr> that implies to me that GPMC data can be in that range of addresses
<shapr> so, I read the arm_blink_leds source
<ZipCPU> It is, it's just that your program will see a different range. The Virtual memory subsystem will get in the way.
<shapr> and that suggested to me that the first four bits of that memory range would map into memory locations that magically set the LED values
<ZipCPU> shapr: Here's a part of a blog article I haven't managed to finish. It shows the basic code involved, minus the constructor: https://imgur.com/8vx39Z2
<ZipCPU> (The constructor is a critical component--let me find that one)
<ZipCPU> Here's the code for the constructor: https://imgur.com/qHEBWv5
<shapr> hm, is there equivalent C for those of us who prefer assembly? :-)
<ZipCPU> ??
<ZipCPU> What, you don't like C++?
<ZipCPU> You should be able to use the address you just gave me, and set LW_REGS_BASE to be that address.
<shapr> well, I have a traumatic experience recently
<shapr> I actually don't mind C++
<ZipCPU> The LW_REGS_SPAN is how big the memory range is
<ZipCPU> This code will access any 32-bit value on your bus--hence the >>2 in the readio() function.
<ZipCPU> Access is really simple, once you have the base address. I called that m_base. You need to get this from the mmap call.
<ZipCPU> Then you can just read/write the GPMC port via m_base[offset] = value; (for writing), or my_variable = m_base[offset]; (for reading)
<ZipCPU> What "offset" you use will be dependent on how you choose to do the address decoding within your FPGA design.
* shapr drinks coffee faster
<sensille> ZipCPU: ok, sorry for the confusion earlier, i think i can rephrase my question now
<ZipCPU> Go on.
<sensille> let's assume all points are evenly spaced in terms arc length
<ZipCPU> Good start. Go on.
<sensille> that means that the average speed between two adjacent points is known, and constant
<ZipCPU> Yes.
<sensille> but it doesn't mean that the speed between to points is constant, right?
<ZipCPU> That would depend somewhat on the arc length separating the two points.
<sensille> the wider the distance, the wider the variations
<ZipCPU> Possibly.
<sensille> (the possible variations)
<ZipCPU> This is all subject to the traditional sampling problem(s).
<sensille> and it also doesn't mean that the speed at the points is known
<ZipCPU> No, the speed at all points *is* known.
<ZipCPU> It's just not necessarily constant, which is what we wish to achieve.
<sensille> sorry, it doesn't mean that the speed at the points is the desired speed
<sensille> is what i wanted to say
<ZipCPU> Ok, let's try this ...
<sensille> but i think we agree on this
<ZipCPU> The issue is associated with the "sample rate", not just the arc length.
<sensille> just to start from there
<ZipCPU> You have two values to adjust here.
<ZipCPU> If you increase the number of samples for the same arc length, assuming the same "sample rate", then the speed will slow down.
<ZipCPU> What's missing here in this discussion is the rate at which the FPGA will move between the points.
<ZipCPU> If that rate is constant, and the arc length is constant, then shouldn't it be at (roughly) a constant speed?
<ZipCPU> Adjusting the rate of the samples, or alternatively the arc length (assuming the sample rate is fixed) would therefore adjust the speed.
<sensille> that's what my gut feeling is, too, but i'm not sure
<sensille> (that was re your roughly constant speed)
<sensille> before changing the sample rate, i just wanted to make sure we have the same understanding on how the speed develops
<sensille> and that seems to be the case
<sensille> ok, now to adjusting sampling rate. i can either manipulate the speed via the sampling rate or by scaling t in the fpga
<ZipCPU> Aren't those the same thing?
<sensille> i think the latter is what you meant earlier when adding a 3rd parameter to each point
<sensille> no, adjusting the sampling rate would mean having more points on the same arc length
<ZipCPU> Not necessarily.
<ZipCPU> It would mean that you go through those same points (for a given arc length) at a new rate--hence a higher |v|.
<sensille> that would be the scaling in the fpga approach
<sensille> wouldn't it be possible to add a 3rd dimension, like x and y, for t?
<sensille> or v?
<ZipCPU> Adding |v| would require the FPGA to do a square root, though, wouldn't it?
<sensille> v in the sense as a scaling function for t, so that we don't calculate x(t) but x(v(t))
<sensille> with, let's say, v(t) a quadratic function
<sensille> so i have independant control of the speed, independant from the sampling of the points
emeb_mac has joined #yosys
<sensille> (and it's independent, not indepentant)
emeb_mac has quit [Client Quit]
<sensille> earlier, you suggest something similar, if i got you right: 15:31 < ZipCPU> In this latter approach, the FPGA would be passed a series of x[t],y[t] values, together with a separate set of t[n] values.
<sensille> and that could be expanded to pass a quadratic function instead of t[n]
<ZipCPU> Yes.
<ZipCPU> Although ... permit me to be biased against this approach for the sole reason that I said you could do this with a 4th order system, and I'd hate to admit a 5th order solution :D
<sensille> glad you said that yourself :)
<ZipCPU> Heheh ... well, 'ya gotst ta be honest about these things ... ;)
<sensille> what we haven't expanded upon is the violation of your assumption of equally spaced samples
<sensille> what would that mean?
<ZipCPU> No, we just did that.
<ZipCPU> The samples are assumed to be at even intervals. We've now chosen intervals evenly spaced in time to send to the motors.
<ZipCPU> How we "broke" this assumption was by adjusting the locations of the points.
<sensille> ok, it doesn't have any consequences on the interpolation algorithm mathematically
<ZipCPU> Correct
<sensille> if i chose the algorithm where i control |v| solely by the distance that would mean i have to chose a resolution where the original curve can be followed closely enough at low speeds
<sensille> so i have to determine a lowest speed i want to use
<ZipCPU> Yes. You will need to choose both the sample rate (in time) on the FPGA, and in space on the host/PC
<sensille> and that sets a lower bound on speed
<ZipCPU> It also sets a bound on your resolution.
<ZipCPU> If you don't sample enough, you won't maintain your approximation bound.
<sensille> so i think i've understood the approach sufficiently, thanks again :)
<ZipCPU> Glad I could help! Feel free to ask again sometime!
<ZipCPU> Now maybe I can get around to blogging about my FFT.
kuldeep has quit [Ping timeout: 272 seconds]
kuldeep has joined #yosys
<awygle> Good morning world
rohitksingh has joined #yosys
<qu1j0t3> awygle: o/
seldridge has joined #yosys
<awygle> how's everyone doing today?
<ZipCPU> o/
<shapr> digging in, learning, frustrated, excited
<awygle> Oh yeah your class starts soon, right?
<shapr> next week
<shapr> yes :-(
<shapr> wait, should have bene :-)
<awygle> N. B. :-)
<shapr> some of the students have ordered VGA pmods, some have ordered stereo in/out pmods
<shapr> I think the first class will be "load led blink"
<shapr> since it comes with the beaglewire
<shapr> then "compile and load the example blink"
<shapr> then we start talking about the parts of the toolchain, what they each do, what happened when we compiled
fsasm has joined #yosys
<awygle> Sounds like a reasonable approach
<shapr> I hope so
<shapr> I fully expect some of the students to rush ahead and do stuff that I don't understand
rohitksingh has quit [Quit: Leaving.]
<shapr> at which point I shall point them here, where I learn stuff
jlf has joined #yosys
maikmerten has joined #yosys
rohitksingh has joined #yosys
rohitksingh has quit [Quit: Leaving.]
m4ssi has quit [Remote host closed the connection]
rohitksingh has joined #yosys
rohitksingh has quit [Quit: Leaving.]
kuldeep has quit [Ping timeout: 272 seconds]
azonenberg_work has quit [Ping timeout: 272 seconds]
kuldeep has joined #yosys
azonenberg_work has joined #yosys
rohitksingh has joined #yosys
rohitksingh has quit [Quit: Leaving.]
kuldeep has quit [Ping timeout: 250 seconds]
kuldeep has joined #yosys
kuldeep has quit [Ping timeout: 240 seconds]
kuldeep has joined #yosys
kmehall has quit [*.net *.split]
elms has quit [*.net *.split]
ovf has quit [*.net *.split]
edmoore has quit [*.net *.split]
mithro has quit [*.net *.split]
pointfree has quit [*.net *.split]
cfelton has quit [*.net *.split]
bubble_buster has quit [*.net *.split]
thoughtpolice has quit [*.net *.split]
eightdot has quit [*.net *.split]
mlen has quit [*.net *.split]
kmehall has joined #yosys
mithro has joined #yosys
mlen has joined #yosys
emeb has joined #yosys
maikmerten has quit [Remote host closed the connection]
azonenberg_work has quit [Ping timeout: 245 seconds]
azonenberg_work has joined #yosys
fsasm has quit [Ping timeout: 252 seconds]
kuldeep has quit [Ping timeout: 244 seconds]
kuldeep has joined #yosys
kuldeep has quit [Ping timeout: 240 seconds]
kuldeep has joined #yosys
emeb has quit [Quit: Leaving.]
jlf has quit [Ping timeout: 240 seconds]
cr1901_modern has quit [Read error: Connection reset by peer]
cr1901_modern has joined #yosys
cr1901_modern has quit [Read error: Connection reset by peer]
cr1901_modern has joined #yosys