Hello. More talk about cross-compilers, our favorite subject. So it's quite a lot in here. Now, the basic point is that we don't have cross-compilers in the Debian archive itself, and we should fix that. But I think it's actually useful, unless you're all serious experts are ready to go over a little bit about the whole cross building environment, which we've developed over the last couple of years, just so you know what the hell we're talking about and how this is supposed to work. So as ever, the first thing we have to do is explain what build, host, and target mean, because when talking about cross-compilers, it's very important that when you say host, you mean the thing it's going to be run on, not the machine you're building on now. That's build, and so on. And target is the code you are generating for. OK. Yes. Exactly. So a normal compiler has all three of these things the same. Life is very simple.  And you can, of course, cross-build a normal compiler, in which case the build machine is different from the host and target. And we do actually do that when you bootstrap a new architecture. In order to get a compiler for the new architecture, the first thing you have to do is cross-build it. Bigger fonts, OK? Control-shift-plus doesn't work. Great. Bigger font. Is that good? Is that about right? Thank you. So one of the conventions which has existed for a long time, basically, because of auto-conference, is if you want to run something which acts on the target. So there's something different according to what code you're about to generate. You prefix your command with triplet. So triplet to GCC. So ARM Linux going to API GCC generates code for ARM Linux going to API, as opposed to just GCC, which is assumed to actually mean build architecture dash GCC. And in fact, that now works everywhere in Debian and has done for quite a long time. So you can always do whatever you could do. Triplet GCC. If the triplet is the build architecture native one, it still works. So this is nice and orthogonal now. So all you have to do to make everything work is to make sure that when you configured things, or when you use commands, those commands with the prefix are issued at the right time. And the right program gets run. This is the multi-arch syntax for specifying the architecture something is installed on. You mentioned GIR scanner there. Is that somebody actually done that? No, it's made an example of something a little bit further up the stack, which is the next thing you hit. Damn, you got me so hopeful. No. So this is another thing that has architecture-specific behavior. And right now, we can't cross-build anything with GIR scanner in it properly, because we need a cross GIR scanner, and nobody has written one. So I have looked at it, but not written code for it. It looks like the first step is probably to convert all of the stuff in it that has detected type sizes into the really rather alarming autoconf macros for doing this. But if you haven't seen it, autoconf has a thing for detecting the word size and endiness and sizes of arbitrary C types and that sort of thing for the machine you're building for by an incredibly scary piece of M4 that goes off and bisects it by repeated compiler failures, but also it's a marvelous piece of code that you should not cast. So, yeah, so the GIR thing is that's gobjet introspection for everyone who hasn't come across it, and the whole of the GNOME stuff all now uses a lot of that to define its interfaces as well as its documentation. So it's actually at the moment, you can build quite a lot of stuff by just not doing that, and it still works, but that really isn't going to last very long anymore. It's probably broken already. So for cross-building further up the stack than a base system, once you want GTK, you need that, and nobody's done it yet. Sorry, just as a point of information, the package names are the other way around for historical reasons, I guess, so GC-triplet. Yeah, indeed. She's annoying, isn't it? And I think package config is an extra hyphen in it. So it's supposed to be concepts rather than details. I shall go and edit it. Yeah, sorry, it's gobby. Just fix it. So, yeah, she'll understand the multi-arch syntax. Could we use that? So we now have IndiePackage, which is already in stable. The build depends qualifiers, colon any, colon native, and colon specific architecture, which allow you to depend on things. So basically, in general, if you depend on something just without specifying anything in particular, then you want the same architecture as I'm in now. Well, and the multi-arch stuff will magically go, ah, it's a library, which is multi-arch same.  And that all just works. colon any and colon native let you specify the exceptions where you're asking for a something library and building for ARM. But actually, you wanted the native architecture version of that library because it's something to do with a build and not something to do with the code you're going to run on the other machine. And we have the ability to depend on specific packages and other architecture. But in practice, you can't use that because it doesn't work on buildies yet, previous discussion. So we need to experiment with that and find out whether anything really bad happens if you enable that. It should work. Yes, that's right. But the point is that we got it into stable in time so that we can use it, which is good. So you can now just do app get build depth dash a target architecture package. And it will go off and get all the things you need to build on this machine and all the libraries you need to build for the other machine. And this is actually very nice indeed. It just works. The thing you can't do yet is use build profiles from apt without some patches, mostly because we failed to agree the build profile syntax in time for the last release because we had a nice thing with angle brackets that was very simple. But it didn't pass Muster in WNDevelop. We have a new proposal, which was mentioned yesterday. And we expect to actually implement that any second now. But this is very cool. It means you can do a build specifying a build profile, which basically is necessary for bootstrapping to say, just the first time you build libc, you haven't got libse linux yet, or lib audit, both of which are now needed. And you have to have a way of saying, please build without that. Well, if you want to automate this stuff rather than do it all by hand. So I noticed there that in your example, you're showing a build profile equals and stage one comma cross. And I had argued throughout the discussion that we don't actually have a use case for more than one build profile. And that the only build profile we actually cared about was the breaking circular dependencies, which basically only required a stage one. So I wondered if you could. Me and Docker both think it should be split into purpose. So I was going to ask for an example of why you need a cross build profile here and what that was legitimately used for. We'll get to one later. Well, maybe not a cross build profile, but something like a test profile. So we did want to differentiate between build dependencies which are only needed for testing things or for build dependencies which are only needed for cross compiling and things like that. So you're right. You can just do it with one thing. But once you start doing a bit of this, it becomes clear that you go, well, this bootstrap means I need to change this dependency. And if I was crossing, I would need to change this dependency. It's not actually the same thing. They often go together and you could just decree that. But I don't think we lose anything by being able to. We lose some of the simplicity and it introduces confusion. It makes it harder for maintainers to understand what's going on. And I think my brain rat holed five levels deep from that comment from Doko. So I think we should probably postpone that discussion until the end. Yes. The spec allows us to do more than one. But we don't have to. What else have we got? So cross compilers. So what we currently have, so for a long time, mdebian.org has been building a pile of cross compilers for most, if not all, Debian architectures except when some of them are broken, which is quite often. It got to the start back a couple of years ago. They were all broken.  And your cross compilers are knackered. And he fixed it. I think it was the MIPS has three multi-libs. And that was all wrong. And then he fixed all the others too. So the man's a genius. I was very impressed. So that works to an extent, but it suffers a bit from tending to be out of sync with Debian. So right now, if you try it today, last time I looked before I went on holiday, it was out of date. And so it wouldn't install. The common cross compilers are in Ubuntu and have been for a while. So ARM-HF, ARM-EL, and now ARM64, sorry, and PowerPC. Okay. All from AMD64 and from i386? Yes. So later on, we get to discuss the matrix of cross compilers we can actually be bothered to maintain. There's an enormous number of possible combinations and most of them are a bit useless. So the other part of this that makes it work is a magic package called cross build essential, which does the same job as build essential. To just say, if you're cross building, you always need these core things. So a C cross compiler, a C++ cross compiler, cross package config, and a C library for the, or libcdev for the host architecture. How does host target, let's do target architecture. Is there one cross build essential package for every target then? Yes. So you just install cross build essential ARM-HF, installs the right stuff. And better than that, S build already knows that if you asked to cross build something in S build, it should install cross build essential thing.  An S build profile? Oh, no? It doesn't need it. He was asking whether we have an S build profile for that. Right, we don't need it because S build has a step where it installs all the build essential stuff anyway. So it just installs cross build essential, whatever, at that point. Yes, that's right. Well, it's tooled when it's targeting and it knows that build not equal host means it needs cross build essential. You do S build dash dash host arch and... Right, sorry, I was meaning to just say that there's very good iteration with S build here such that S build knows about cross build essential and wraps everything for you and such that... So it already knew about build essential, right? We just told it about cross build essential as well. Yep. Now, of course, the LLVM people want some different packages for cross build essential. So we might have to have, I think, maybe we just want LLVM cross build essential. That would work. And that is actually defined in the sbuild.rc file. So it's not hard-coded. So in fact, for the moment, there isn't cross build essential package in Debian because it hasn't got any cross compiles to depend on, so it's a bit useless. But you can still specify that you want libc, colon, blah and some things if you have got them. That those packages do exist in my Bootstrap repo if you want to have a play. So this is actually all very nice and basically works beautifully, except in a few cases where it doesn't, which we'll get to later. These cross compiles have been built in different ways over time. So Mdebian has used a tool called build cross, which has been an experimental for a long time. Actually, I tried using it recently. It works very well. So that basically just goes through the process of all the steps you need to do to build a cross compiler using dpackage cross, downloading the libc from the other architecture, blah, blah, blah and can do arbitrary combinations of... It'll do a whole set. So you say build from these things to all these things, get on with it. And if you're really lucky, it'll build all of them and not fail halfway through. So we did try building an IA64, an arm to IA64 cross compiler a couple of weeks ago because somebody wanted one and it almost worked. Meanwhile, in Ubuntu, a couple of years ago, Martian did some fine work to produce a cross toolchain. So there's a package called toolchain base architecture, which uses the Linux source, binutil source, GCC source and eglibc source to go through the whole process of build the Linux libc headers, build GCC stage one, build eglibc stage one, build GCC stage two, build eglibc stage two, build GCC stage three, i.e. the one you actually wanted. Oh, and binutils at the beginning of all that. And the GCC default stuff. What's that in there? What's that in the package, I think now? Yeah, so that's nifty. The nice thing about that is that that works on existing buildy infrastructure because it only depends on binary source packages. So all of these things produce a source package. So, ideally, you just use the GCC source and build it in a slightly different way with the profile, for example. But you can't do that at the moment, so that's why it was done like that. Um. Dun, dun, dun, dun. Well, so yeah, you get all those packages out of it. So it uses the d-package cross thing to generate a C library and a libgcc for the host architecture. Target architecture, I don't know. But installed as a binary package for the build architecture. So you're not actually using the one. You're not using the multi-arch location for that library. It's got its own copy, which is okay, except when it goes wrong. You end up with two copies of libc on your system. And just occasionally, things link against the wrong one. That shouldn't happen, but I've seen a few cases of that. So, you can build the cost tool to generate a slightly different way without going through the whole bootstrap process and just building GCC against the libc and libgcc for the host architecture. That now works nicely. That was a GSOC project last year by Tibolt Gurke and Docker who's integrated all that. So there's this magic variable with depths on target packages equals yes. If you set that, you just build GCC against the stuff you already got. But that needs, that's a multi-arch build. So the build of the compiler is now depending on the C library and the GCC from the other architecture. So we can't do that in the archive until we've enabled it. And the question, one of the questions for today is, do we wait and do it that way, or do we just do what Ubuntu is doing now because we could upload it tomorrow? And the main reason we're worried about that is the transition, whether we make lives difficult for ourselves if we're going to move from one to the other. And Docker doesn't like this plan much, but I do. We'd have any of this argument for some time. Sure, whatever. One of the reasons I'd like something sooner rather than later is that I've been running, well, kind of falls over a lot, but I've been running a cross builder, not a cross builder for Ubuntu men for some time. And it's about a third of the packages just built. And I would very much love to see what state all of Debian is in. I can't really do that until we've got cross compilers in the archive. And I'd like to have that in place the sooner the better so that we can start distributing the work of actually fixing packages rather better than we currently do. Yeah, it's true. So the plan was in fact always to upload. We agreed at the MW and Sprint in February two years ago that we'd upload those packages forthwith, but for whatever reason, it never happened. It made a lot more sense then than it did now, but you're right, we should probably just do that. I just worry, what happened? If we do that, and then if we try to transition to cross dependencies, do we have a problem with a lot of replaces and conflicts and things, or does it all just come out in the wash and it's easy? I'm not sure. Are those cross build dependencies or cross runtime dependencies that we're talking about? Your binary packages would be coming from different source packages, probably, potentially, so you'd have a lot of, so when you take over a binary package from one source package to another. Okay. Yeah, that's trivial. Right, okay, good. So the current way to build a cross compiler can be simplified, so I think it's exaggerated to speak about a seven-step bootstrap. So if somebody wants to work on that, please contact me. So yeah, I would like to see some simplification there, but I don't want to spend the time myself at the moment. I mean, it's trivial to take out the binutils parts and put them, so I get to that in a minute of what I think might be a sensible plan. Right, so one design decision for the cross compilers was to have them stand alone, and well, as it's currently done in Ubuntu, we are able to upload the cross compilers to the archive and use them for cross-building. I do not want to rely on foreign architectures to do that, so. Except that if you're multi-arch cross-building, you'd do anyway, because you have to have a matching libGCC everywhere, so you've already version synced to your... But in this case, I already have to have these architecture available, and that's not the case when I'm bootstrapping. No, so I agree, so bootstrapping, you'd have to do something different. Also, there's always the risk that if things ever go slightly out of sync, you end up in the case where you have to reboot strap. That's the other consideration, and so bootstrapping for your cross compiler may not be a one-time operation. You get too far out of sync. I mean, obviously, we have the packaging to do both of these things, right? So at the moment, it's completely trivial. It's setting a variable, which way you build, and yeah, I think it's important that we keep that functionality. It's just a question of what the default build is, whether you do all of it every time, or just, okay, we should probably, we'll carry this conversation on. See how far we get through this, and we'll come back to arguing about that. So yeah, I think Binyutils is nice and standalone and simple. You just have a Binyutils cross-source package that just builds for all the architectures we're supporting. Does that seem sensible? You should probably leave Docker with a microphone. I think he's gonna have to answer all these questions. If we split the Binyutils part out of toolchain base, we just have a thing that builds, just cycles through each architecture we're supporting and builds a Binyutils foo. So, well, the current packaging, so we only built the G-Lipsy parts and the kernel headers out of the base toolchain package. And, okay, Binyutils is already separate. Yes, and GCC is also separate. So what I was doing was to just, well, to limit the bootstrap part into the G-Lipsy packages. Right. So I built this hallway compiler just to build G-Lipsy and then I don't have to care about interdependencies for GCC anymore. Okay, yes, and there's another package config, so cross package config actually consists of nothing but a link. So the actual package config package contains package config cross wrapper, which basically sets a path and then runs package config. So it's a, each cross package config thing is a rather trivial package and they could all be made out of package config for each architecture or you can make one for each of them out of the toolchain base thing, which is what happens at the moment. Doesn't really matter much. I'm not sure if anyone cares. I spent a long time deciding that I couldn't decide which way was better. So if you're arguing that you would have the bit made out of the package config package for each architecture, you mean you would still have to build it as a separate binary package then? Yeah, I think so because, well, yeah, I have to. You could have a package config. You're not cross-installing package config as part of your build system, you're installing the native version of package config, not the cross version. So saying that you would ship the ARM Linux new ABI package config in the ARM-HF version of package config doesn't help you because you've installed the AMD64 version of package config, not the cross one. Yes. I thought you were suggesting that the AMD64 version and indeed every other version of package config would include simulinks for every architecture we've ever heard of and then we just make it multi-arched foreign. It is already multi-arched foreign. Right, but then it would actually work as multi-arched foreign. So yeah. It's sort of a slight lie. If anyone can think of a reason why it's better to do it one way or the other, I... I think it's better to do it the way we've already done it because that way people who want to do their own targets aren't stuck arguing whether their made up architecture is important enough to include in the package config package and so forth. Yeah, I was gonna say pretty much the same thing. It seems a bit of a shame to ship packages which just have simulinks, but it's nice for stuff... Asimlink. Or Asimlink even, yeah. But it does mean that if you have your own package to do this stuff, then you can... You're not linked to the package config... package lifecycle, basically. You can do your own thing on the side and then once it's already... Yeah. Get it all in. You get that independence.  So one of the things that would simplify all this a bit is if we actually had source dependencies which I saw someone mention on the list. Never occurred to me until someone went, we could have source dependencies. So we have to build... There's all that stuff to build binutil source and build GCC source and build Linux source. And Linux source is annoying because it's not quite the same as the actual Linux package whereas the others are the same as the package and have the Debian foo in. I'm kind of conflicted about that. It seems kind of theoretically nice, but given that you always guaranteeably have access to a mirror with source on it as part of the... During a build, why not just use apt-get-source? Someone I found it really annoying is doing the new architecture bootstrap in order to test anything using the build mechanism, you've got to fettle the package so that it rebuilds the source package with the little patch in so that you can do the build as a thing. I'm not saying that the dash source packages are a nice way to do things. I'm saying that you can just use apt-get-source. Yes. In your build. Yes, that's right. It may not... I thought that was kind of... Is that not found on? It may not actually be configured that way right now, but you are guaranteed to have access to a mirror with source on it. You can synthesize one if you need to. Yes. It is. S-build fetches it. There's other stuff that could be nice with beyond just getting the source, if you could say build depends something called on source, you might be able to pull in transitive build depends then. Well, I first... Currently, if you build depend on binutile source or GCC source, they also declare dependencies and stuff that they need. So if you just do the apt-get-source stuff, you don't get that, and so you have to maintain your own set of dependencies. I'd naively assume that you weren't allowed to do apt-get-source in the middle of a build, and that would seem terribly shoddy packaging, but yeah, that would work just fine and actually be slightly easier from my point of view, but yeah, I mean... Okay, so anyway, that's what would be nice or maybe it would be nice. I don't know. Nobody... It's not holding anything up. Yeah. Why not? Backbone. Backbone. So now I have to put myself on the view first. So the reason you're not allowed to do that is because a build is not guaranteed to be online. So if you run apt-get-source, you're assuming there's actually networking or some source repository at least, which is an incorrect assumption. That's what I thought always. So you're guaranteed to have a mirror because your build dependencies are coming from the mirror. You're also guaranteed to be able to fetch the source for the package that you're building so that has to come from somewhere. The builder may not be allowed to access an external network. There's no reason in principle that it would need to access any different network than the one that's pulling its binary build dependencies from. However, I don't think we currently actually have anything in the design which requires that the source is available on the mirror that it's pulling the binaries from because the source package you're building may not be in the archive yet anyway. It may be pulled from somewhere else and it may have some special way of actually getting that in the S build. While that's true, we're not talking about the source of the package you're building. We're talking about something that you might be source-dependent on, which has got to come from the mirror. So I don't see the difference between apt-get-source and a hypothetical future source dependency from that point of view. Okay. Well, I think we'll have to continue this because there's a number of other items to come up. I would like to point out that there are plans to enable network namespaces on Linux build these to shut down any network access. So just because there's a mirror available at the time you're fetching the build dependencies and downloading the package doesn't mean you have any network left when you run the build. We're planning to use this for other things anyway and there are already packages that use this for other things. For instance, Debian installer will be unbuildable if you remove that capability. So I think the project might not like that very much. Okay, right. Well, we'll punt that for now then and come back to that. A Mingyu man over there would like partial architectures for Mingyu architectures so that Stephen, do you want to mention just what's used and what would be useful? Yeah, so this is just in general for partial archers when you're cross-building stuff. If we can have it as a multi-arch partial arch that's recognised by all the various tools then we can ship libraries. This is what Steve was saying in the earlier buff. The nice thing about multi-arch is that you can install libraries that you're never going to use on your host system that match the target and your cross-compilers can use them all. And then that way because of the way AutoconFu works there are a lot of packages in Debian that just do the right thing when you cross-compile them and so then you get for free tons of libraries on your new cross-targets. So the thing that's missing is that Deep Package doesn't actually have a Mingyu architecture defined yet and it probably should and then it's pretty much just works, right? Yeah. It's the same problem as the ARM non-thing from the previous buff is other architectures that we're never going to run but we'd like to build for. So one of the things to consider is how many cross-compilers do we wish to support? Right? So one of the practical problems from doing this for years turns out to be that you've got a lot more things. The more you support the more likely you are to have one of them not build at which point you can't upload your package or whatever, which is why Doco wants nothing to do with this because he just has to worry about the native compilers working and I think it's quite true. We want to keep the standard GCC native build separate from all the cross-compilers because otherwise there's just way too many ways this will go wrong. So at the moment we pretty much build AMD64 and i386 to everything but people are going to want ARM64 to everything soon. Why? ARM64 server boxes to build stuff on and nobody cares about that old i386 nonsense anymore? I mean you're right, this is a slight in the future but not very far. Well... I... Let's talk about how long it takes to bootstrap ARM64 right now and how crazy it would be to actually want to cross-build from ARM64 to anything else. It's possible that in the future ARM64 hardware is actually going to be comparable to something else for a compiler host but that's far enough in the future that that line is clearly high in the sky. It's not today, you know. Next year that will be quite... That remains to be seen. Sorry? Remains to be what? He just compared you to our channel. Okay. So I would like Damian just to start on a very small subset and this small subset should be maybe just AMD64 for the host or maybe AMD64 and i386. Because we know that all stuff works. Right and if somebody wants to extend that later that's not a problem but... We have got some stats from the NDebian downloads to find out which compilers people actually downloaded and you're right. The overwhelming majority are AMD64 to ARM something. So it is true that I do want to like the native tool chain have built from separate sources and the cross-through chains. What I do see in a window for all our supported cross-through chains it's just extra work to upload binators four times upload GCC cross four times and things like that. So maybe it was something about to build all compilers targeting complete Debian architectures in one source package so that maybe may save some time. So you've got a source package that builds all the AMD64 to something like the binutils. So the trade off there is having a separate source so that at least that part versus having a lot of repetition and rebuilding rather pointlessly. If we just use what we already have then they're separate. So one of the things that's quite interesting is something Helmut's been talking about this week which solves the GHC problem to be able to install both i386 and AMD64 native compilers on the same system because they'll both run and we sat there and worked out that that's perfectly doable and actually doesn't conflict with the way the cross compilers are built. In fact it makes it all a bit more orthogonal I actually quite like that idea so we'll get to that later on there's a whole load of stuff so if we get that far so from your point of view you still install GCC 4.7 but actually the packaging behind the scenes changes a bit so one of the things that came out of the Razbian discussion this morning from the Razbian people they said one thing we'd really like it to change was if there was one place to change the compiler defaults because otherwise there's an awful lot of source packages where they have to change the runes but I don't think GCC makes that easy does it? There isn't a place could we do that? My impression was that the Razbian people that want to have a package where they could specify different target defaults for compilers that doesn't match quite what you did in the wiki so well for GCC we do have only defaults packages well that's GCC which GCC gets run but their point is they need to set the defaults build options for V6 instead of on V7 and then rebuild everything and they don't want to have to edit eight source packages well I wondered that will that work? it should if everybody's doing their packages correctly it should be a de-package build flags thing so if the point is you want the compiler's behavior out of the box to use whichever flags you're talking about when it's used outside of a package it's when you build the compiler so they accept rebuilding the compiler set they just don't want to have to edit lots of sources to do that okay so anyway if we think we could do that it will be very helpful to them well I guess in the case of Raspbian in the case of Raspbian do they actually care about what are they configuring in the compiler that's different than the way we're configuring it other than setting the default target the compiler itself would need to be built to not use V7 instructions otherwise you can't run it on Raspbian everyone get that? so yes the compiler has to be built for V6 as well as all the stuff it builds so anyway we should have a look at that it will be nice yeah so there's these various ways of building compilers so there's a bit of a tension between multi-lib and multi-arch stuff there's a lot of things you can do one way or the other you can either put things in multi-lib locations or you can put things in multi-arch locations and use that and the moment the GCC packaging supports both of these and it's quite complicated now on the other hand it's all been done so we might as well leave it there so an x86 people expect to be able to do dashM32 on their AMD64 compiler and get i386 stuff and we can't change that because it's probably in millions of build scripts everywhere I would prefer a world where people didn't expect an RMHF compiler to also do RML stuff and have all the bits installed without them installing an RML cross compiler but again Docker thinks that's useful and I suspect other people do too I have encountered some packages that appear to think that this was something that you could do so the question is do we think we should support that do we think we should just tell people to install both compilers well as long as upstream supports these options and we can use RML and I think RML and we can use M32 and hard codes them in packages I think Debian should support these that gets used on ARM as well certainly used on i386 a lot I agree we can only take that away for Ubuntu to have soft float and hard float modular options because when we did switch over from Army L to Army HF it did make sense to to run these binaries on the very same system and yeah well sometimes we may drop them but okay so I mean I prefer to keep it disabled and wait for people to bitch a lot well it's a bit of complexity we could remove hopefully we will see this for arm 64 again yeah true and we will see them for big Indian and little Indian 64 again yeah you're you're probably right okay thanks well so one of the other things about all this stuff the way all the multi-arch stuff works it's very good for doing distro cross-building but because of the version you can only install the host architecture version of the library the same as the build architecture version and so if you wanted to build a very latest version for your target then that's harder because it'll tell you you can't install the standard system library you need to stick it in a sys route or something so this works beautifully for distro building you get great consistency multi-arch all just works as long as everything is built to the same versions it's less useful to for doing random upstream development and I don't know to what degree people find Debian with multi-arch a bit of a pain in this regard I never do that so I don't care but we may find that doing this everywhere actually makes upstream development using your cross tools more painful rather than less I don't know if anyone's run into trouble trying to use this I guess not your old Debian users and we haven't enabled it yet so ever like yes so there has been some grumbling from upstream we're told by Ben I get we've done it so we'll see how it goes I mean in in principle you can use sys routes and stuff still and that should work something we should check out there's a Debian cross mailing list just about to be created whenever the mailing list masters get around to it I think it's agreed and generally considered useful it's been noticeable it wasn't really one place to discuss all this cross stuff over the last couple years that were where the right people hung out so if you're interested in this when the Debian cross mailing lists appear I guess we'll mail Debian develop and you should sign up my phone I feel obligated to mount a quick defensive multi-arch here I'll be brief so yeah multi-arch doesn't solve all the problems but it does solve the problem of if you are targeting a distribution that you are running it's it lets you do things very effectively and if you're targeting something that's not what you're running you need to use a trute but you previously needed to use a trute or something else anyway so it doesn't make the problem invisible but it also doesn't make it harder than it was but you may need to use a trute and build it for both architectures so it can be slightly harder if you need to install the build architecture version as well because it's something part of the system then you have to have a matching version of the build architecture library and the host architecture library in those tells you can't install it well only if it's something you need to install for the so I mean for the build architecture in the first place yes so yes there's a little bit of it there are a few corner cases where it gets a little bit fiddly but for the most part it's it's not making things harder than it was before for whatever you should be able to get and if you're targeting something that's not not deviant to begin with you should just use this route and you shouldn't be trying to use multi-arch for it indeed so you should get all the system stuff exactly matching by default and you can specifically explicitly say and this extra bit from here so we're about to run out of time other things I should mention there is this problem of specific build dependencies so a number of packages depend on GCC specific version and the problem is that when you cross-build it when it says I build depend on GCC 4.6 when you cross-build it you actually want to depend on GCC 4.6 triplet or triplet GZI around it is and actually you might mean I depend on both the build architecture version a specific version and the host architecture version a specific version so that's something we simply don't support right now so we need a mechanism two things have been suggested we can either there aren't very many packages which do this mostly GCC binutils are the things that get depended on so there's a few dependencies which basically have to be translated to a different package when you're cross-building and we could have some so Colin suggested a scheme I probably got the names all wrong but the idea that there's there's a field in the package that says this package is a translatable package name and you should translate it when cross-building so we just mark the set of packages which have this feature and then something apt-d-package whatever would pick the right one or you could have a substance far so you build depend on something dash substitutable bit the problem is you can't just change it in the dependencies because it depends what you're building for so it's it's special in this regard now I have strong opinions about which of these two we've got a whole minute to a sub spars in build depends is a significant departure from how we use those currently that implies some sort of post some sort of post-processing of of the source package not done at build time and that would be it's not a good fit we should do that way okay Mike I just noticed that the proposal to change them a native compiler to use multi-arch package names would solve the issue with having to specify cross-profile in the substarts case as well so you just say GCC dash version dash hosting new type and everything works in that case as well but you don't know which host type you're depending on until you build it because it depends what you're building for yeah you still need subswars but you know don't and no longer need a profile yeah yeah you still need the subswars you still need the variables but you don't need the profiles in that case okay yeah he's right and that's not gonna listen all right and there's a way without subst wars of if you use ridiculously long dependency strings and use the cross-profile together with every architecture you can build for and right but it would get around that problem in an ugly manner true so well I like and build depends on binutils dev or annoying turns out that actually all the things I found really want libibity dev so we're I'm supposed to split that out of thingy and he hassles me on a regular basis because I haven't done it for months now so we'll fix that and there was this interesting proposal to rearrange the as referenced up further up the thing about being able to install I through it's about basically install any set of architectures side-by-side I have to stop apparently and so I wasn't gonna go into all the details but all the details are listed here and we will put that on a wiki page I think it's quite a good scheme thank you very much I'm sorry there's no time for questions please hassle me afterwards


So, welcome back, we are discussing finite state machine plus data path controller plus data path and we were discussing a particular example of greatest common divisor computation iterative computation and we had discussed the data outline the data path it is corresponding very long description and the controller for that which turned out to be a single which to begin with we designed a purely combinational controller. We found a bit of deficiency in that in the sense that the start signal was having too much priority as long as a start signal was high the system was not at all proceeding to the computations. So, then we outlined if once we if you change the protocol so that we can respond to the start signal as soon as possible then we will have to we will need extra states and the controller will be a more genuine multi state finite state machine instead of a purely combinational controller. So, let us quickly review that and discuss it further. So, the data path for GCD just to consolidate the picture in your mind will repeat quickly draw it bit more neatly this is the X resistor which is driven by output of a multiplexer and at this multiplexer is controlled by an output of a controller with the signal load X in and when this load X in is asserted the input from the external services X in is loaded into the resistor X. This is the clocked resistor otherwise if load X in is 0 then the input to X is going to be loaded with something that would depend on whether swap is asserted or not. If swap is asserted X is to be loaded with Y is swap is de asserted X is to be loaded with something called X minus Y which is the result of arithmetic logic unit which subtracts Y from X. This is the same Y which is going over here coming from somewhere else this is X which is coming from over here that is a picture for how X gets loaded either from X in when load X in is high or if when load X in is not high it will be loaded from either Y or the result of this ALU X minus Y depending on whether we swap or not. So, correspondingly this is Y, Y is a multiplexer here and again that multiplexer is similarly similar to that for X is going to be controlled by a control input in output from the controller which is input to the data path say load Y in and when that load Y in is asserted Y in which is the input ready at the port of this GCD module is going to be loaded into this clocked resistor otherwise like in this case Y is going to be loaded either with depending on swap either with X or with Y. We also require a comparator and a zero checker right other than this. A comparator will need to compare X and Y tell us with indicate to us through this signal whether X is less than Y and a zero checker is going to look at Y whether Y is zero or not and tell us whether Y is equal to zero or not. This Y is coming from over here I guess this is slightly neater diagram for the data path we have shown all the data path components that we require. So, now we had started working I mean on the protocol like where the start signal is quickly responded to and that required a use of a state called state idle in which the system is kind of waiting for the start signal to be asserted and when start is not asserted stay in this state. Once the start signal is asserted then the system in the next clock cycle would move to a state s t loop but before it by the end of the current cycle before it moves to the state load X in load Y in would have been asserted by the controller. So, as to ensure that at the end of this particular clock cycle while moving from state idle to state loop X in and Y in would be loaded into X and Y. So, at the beginning of the clock cycle when the system has moved to state loop X and Y have been loaded with input values. So, now we are ready to compute then we will check. So, this is where this system will reside for a few more clock cycles as long as we have interesting X and Y inputs. In the beginning of every clock cycle this will check whether Y is equal to 0 or not either Y is 0 or Y is not 0. So, if Y is 0 then we know that computation is over the controller asserts the ready signal which is the output of that controller and goes back to the idle state. So, that it is ready for like in taking in the next input X in and Y in to X. If Y is not equal to 0 then we are still have some work to do and that would exactly what to do will depend on whether X is less than Y or whether X is not less than Y. In this case swap signal will be asserted and in next clock cycle we again go to this same state where we will behave the actions of this data path would be again dependent on X Y equal to 0 or X less than Y and so on. So, we will go back in this state we still have some more computation to do. If X is not less than Y then we do not swap and in the next clock cycle we go back to this state. So, this is the state diagram that we have arrived at. To make this unambiguous or like to connect this up correlate this with verilog to understand the verilog's semantics and synthesis process it would be instructive to write the verilog code for this controller. Note that data path has not changed. So, just the controller changing and with the help of that changing the controller we are being able to implement a different protocol of the way we respond to start signal and so on. So, the verilog for generation of this I mean like the state machine. So, first let me describe the state transition logic. State transition is taking place at the triggering edges of the clock that is say positive edge of the clock. So, it is typically is going to be described using a case statement depending on what the current state is we have different cases. The current state is state idle then we stay in the same state as long as start is 0, but if start becomes 1 start is asserted then in the next clock cycle we will be ready to move to state loop. Else we stay this is not required else we stay back in the same state idle that is how we respond while we are in the state idle. So, the transition in the next clock cycle we will move to state loop if start has been found to be asserted like in a stable at the end of this clock cycle and otherwise we stay back in this loop. So, this is corresponding to this particular picture. If start is asserted we are going to move to state loop if start is not asserted we are going to stay back in this state. Now, the logic if the system is in state loop the state transition logic not the logic for generation of the control signal that we will describe in a separate always block. So, here it would depend on whether first will the system will look at the status signal y equal to 0 which is coming from the data path this controller system will look at y equal to 0. If y is equal to 0 then we know that next state we are going to move to is idle state. So, waiting for next triggering next trigger for the system to start else the computation would depend on whether x is less than y or x is not less than y, but the next state is going to be the same. You notice that although in this diagram we have you know if y is not equal to 0 we have this for two further situations with x less than y or x not less than y, but that is for the output control signals control signals which are being generated by this controller, but the next state is going to be independent of whether this or this next state is going to be s t loop. So, as far as next state logic is concerned state transition logic is concerned this is sufficient to say this. In fact, this is also redundant because this is the wedlock semantics will tell us tell the synthesizer that the system the next in the next clock cycle we are staying back in this state. So, this would have been similar to this this else block is also redundant, but just for clarity we are I am putting it here. What else these are the only two states right we have completely captured how the transitions take place, but for completing the case statement we have to have some default and in which we really do not care, but just to be on the safer side we say that if some funny situation is there and anticipated like you know unclear values on the states signal then we move to state idle. So, this this wedlock code fragment captures the state transition logic. Now the logic for generating the control signal is also typically described using always block ok. So, this is the output logic output of. So, the outputs of FSM the control signals to the data path and also a signal ready which is output of this GCD subsystem ok. So, this is combinational logic. So, this will is going to depend purely on what the current state is and within that depending on current state you also look at the current input values to the controller which will be the signals x less than y or signal y equal to 0 and so on ok. So, we have to specify what will be the control signals the control signals are load x in I like in the case for seeing this purely combinational controller which we seen in the last class I use the default values I said a default load x in to 0 load y in to 0 swap to 0 ready towards to 0 and here I am only going to show the non default values. So, if in the state idle then only when start signal is asserted we will be doing something to this like the load x in and load y in signals will be asserted load x in will be 1 load y in will be 1 and we would have moved to that state loop as described in the other always block which is the state transitional description. So, nothing else as far as the output signals are concerned in state idle state loop let us look at the diagram for state loop in state loop the output signals will depend on whether y is equal to 0 then the ready signal will be asserted and if y is not equal to 0 it would depend on whether x is less than y or x is not less than y. So, if y equal to 0 then ready is 1 else if x less than y then swap is 1 else swap is at the default value 0 sorry the default is also required, but default whatever so I do not care really n case. So, I could just have an empty statement here let the default values remain as it is. So, using the blocking assignments and using specifying the defaults early enough and specifying non default values in this block of code I have completely described purely combinational logic for generation of output and this logic depends on the current state as well as the current inputs to the controller which are start y equal to 0 x less than y all the signals are playing a part in deciding the values output values of this controller which are some of them are input to the data path some of them are output to the external world. So, having seen the GCD example quite like you know and variation of that to illustrate the like need for typical need for a multi state finite state machine rather than purely combinational controller I will just for a change will move to a different example of again of FSM plus data path and it is a very simple example where the concept of multiple state will again be evident, but in a different context with a different requirement. So, this is the example of simple binary multiplication where let us ignore this let us assume that the binary numbers are positive non negative or positive numbers and we are going to multiply them using very simple the school grade multiplication system adopted for binary numbers. So, let us say the numbers are this is number 13 in binary this is number 5 the result should be 65 let us say the way this computation is done is as follows the shift the so called shift add approach shift and add algorithm which is very easy to hard wire and that is what we are going to see it as a FSM plus data path is as follows. So, we are going to maintain an accumulator where the multiplication will accumulate that accumulator will be initialized to it will be sufficiently big accumulator capable of storing the product this is x and this is y input x and y have been stored in to registers x and x in and y in have been assumed to be stored in registers x and y at the start of this computation of course, some of this register especially accumulator is going to be changing x will not be changing x is going to be repeatedly added y will be changing because we are going to look at the bits of y 1 by 1. So, assume that y is going to be put in some kind of shift register so that which will be shifting left 1 bit at per cycle at a time. So, the algorithm is as follows it looks at this particular MSB of y this is the let us say let me call this this is MSB of y it happens to be 0 because of that what we are going to do is simply shift since MSB y is 0 just shift. So, what have shift accumulator? So, the accumulator is going to be again shift and load accumulator we also for the next clock cycle we will we will also pop out this particular MSB of y. So, we will say shift y register to left. So, this is these are the actions we will be taking in this clock cycle. So, at the end of the clock cycle y would have been because of this control signal y register would have been shifted left. So, this MSB would have been popped out new MSB most MSB stands for most significant bit we will be looking at this particular bit in the next clock cycle. Accumulator would be loaded with the shifted version of the current accumulator just shift and load accumulator. So, here there is no difference it is going to be 0s all 0s x is going to be as it is in the next clock cycle because of the shift y left we are going to see 1 0 1 and 0. So, note that the 0 is the 0 was this particular 0 trailing 0 is not part of the original input and we are going to keep track of this with the help of a counter. So, I am not missed it out here, but assume that there is a counter which is keeping track of how many iterations we are progressing we are progressed in the next clock cycle when in the in the beginning of the clock cycle we have this situation y shifted accumulator has been loaded with the shifted version of that, but now we have interesting situation the MSB MSB is 1 since MSB of y is 1 is 1 we say shift and add load accumulator with the result of the adder and also pop out y by shifting that register to left. So, now what we get is to the accumulator we like you know accumulator is loaded again with the shifted version plus shift plus add. So, that is 0s plus 1 1 0 1. So, this is going to be the new accumulator x is going to be as it is and in the next clock in the beginning of the next clock cycle we will have this MSB will be 0 again MSB of y will be 0. So, now since MSB is this therefore, accumulator is going to be just loaded with a shifted version of it no addition will take place we will also be shifting y to left and let me also space something that missed out earlier will also be decrementing counter the counter which is going to keep track of how many iterations we have progress. So, in the earlier steps also I should specify that decrement count decrement count.  So, because of this what we are going to get in the accumulator is shifted version of 1 1 0 1 what is remain x is not changing at all, but y is going to be now shifted further and for the last iteration we see that particular the last bit of y as the MSB now remember the y was 0 1 0 1. So, this is when the last iteration now because MSB is high MSB is of y is 1. So, therefore, accumulator is going to be loaded with the shifted version plus x and then at the same time we will instruct the shift register for y to shift to left and to instruct the counter to decrement. Now, what is the result that is going to be at the end of the clock cycle in the accumulator is going to be this shifted by 1 1 bit plus this particular number 1 1 0 1. So, let us calculate that. So, 1 1 0 1 0 0 and this for the 2 0 this is the 8 bit accumulator and 1 1 0 1. So, we get 1 0 0 0 0 0 1 0. So, what we end up here is 0 1 0 0 why would be now all 0s note that counter would have decremented to 0. Now, we know that we have done 4 iterations which are the 4 iterations iteration number 1 iteration number 2 3 and 4 at the end of this 4 iterations we should have we expect to have the result in accumulator about this result is 64 plus 1 this is 65 in decimal. So, it is exactly what we expected it to be 13 multiplied by 5 65 because this is 13 and y was 0 1 0 1 that is 5. So, we have this correct description of the simulation of this particular shifted add based algorithm. So, it is data path is going to be quite simple. So, it is quite instructive to look at this as an other example another example of F s simple as data path. So, what is the data path? So, what do you expect? We definitely require an adder we require a shift register for what? Shift register for y we require a multiplexer I mean most likely in most cases we require there is a role for multiplexers there is a role for ALU. We will see exactly we require a counter for keeping track of the count for updating the count what else to be require in this algorithm? A register several registers one shift register for y and registers for appropriately big register for accumulator and for x. x is in fact constant. So, we might be able to optimize it a little bit. So, let us start like you know placing this components and wiring them up.  This accumulator is going to be taking at times just a shifted version of itself or the result of the ALU addition. So, when it takes the shifted version of itself it is like will regard it as if it is the adder is adding zero to it. So, in the case of shift and add will be passing this accumulators content through a one bit shifter and putting it at this adder and other input to the adder is going to be either x which is stored in this register x a clocked register either x or it could be zero. So, this will depend on whether we say the controller says shift and add. If the controller says only shift that means shift add add is zero then zero will be sent to this adder and then it will have this simply the effect of loading updating the accumulator with it shifted left shifted version. Note that this is not a shift register this is a simple shifter combinational shifter. So, in the inventory of data path very typically we require shifters combinational in general a barrel shifter is very useful component very efficient in general one uses barrel shifter a very important a typical component of useful data paths. Here we have a simple shift combinational shifter which is only shifting by one bit we also require a counter again a synchronous clock system whose output is being used like you know and which is being instructed which is being told which can be instructed to decrement and so on. And will be interested in seeing whether this count has reached zero or not sorry whether this count is zero or not zero checker we will use here count equal to zero. What else do we require this algorithm in the data path shift and add we will come back to it this looks like this is more or less what we require we require a controller now. So, controller for shift add a best multiplier so now again we see that we are very typically going to have one state in which the system will stay for long enough time knows what to do depending on the status signal generated by the by the data path itself the controller will use those status signal generated by data path and like decide on the control signals to be input to drive the data path again. So, looking at a status signal with the controller generates the control signals to the data path and that state I denoted by a typical state to do which is where the majority of the work is going to happen most of the cycle the system would stay in this state and what are the actions the outputs would depend on what the inputs are. So, the most important input to the controller is just we can see there is a control signal shift and add to decide whether to shift and add and anything else it will a lot will depend on whether the count is 0 or not as well as whether the we missed one thing MS the vice the shift register for y and this is the MSB and assume that this is the shift register. So, the MSB of y the most significant by a bit of the shift register is going to be of crucial importance and based on that actions will be decided if MSB of y is non-zero and if MSB of y is 0 these are the two possibilities if MSB of y is non-zero then the we are going to go back in this yeah actually we missed the important the important the count by whether count is equal to 0 or not you has even higher priorities. So, this will not work so quickly like from this state we check whether count is 0 or not if count is has dropped down to 0 we know that this computation is finished let us see what to do whether to go back to this state or not this is important this is when the computation continues if count is not 0 then it would depend on whether MSB is of y is non-zero or whether MSB of y is 0. If MSB of y is non-zero then we know that not only we have to shift, but also add x. So, we generate a certain control signal shift add to the data path we should also be decrementing the count right we should also be loading loading the accumulator with the result of the adder. So, enable accumulator to load itself and one more control signal will be shift y to left. So, all this control signals are asserted so that the multiplexer lets the x go through to the adder. So, that x is added with the shifted version of the accumulator and the result and count is decremented the result of the adder is loaded into the accumulator and y is shifted left. So, all this with the help of this control signals at the end of this current clock cycle appropriate data path operations data will happen and then we go back to this state. On the other hand if MSB of y is 0 then we only we do not shift and we do not add. So, which is like so it does not mean that we do not shift it simply means that we do not add. So, this signal is de asserted because we have decided to use a signal with the name shift add as the input is multiplexer. If shift add is 1 then we let x go through if shift add is 0 then we let 0 be added that means it has the effect of only shifting. So, shift add is de asserted when MSB is 0, but we still have to decrement counter decrement count enable the accumulator for loading and shift the y register register left by 1 bit and we go back to this state. Now, let us come to this particular situation when count was found to be 0. So, should we what are the control signals to be generators control or some output signals to be generated and this state we go to next. So, if like in the single state GCD controller if we are tempted to go back to this state then what would happen is that the computation would have been finished, but nothing would stop from this like shifting of accumulator and all that to happen because this system will keep reacting to might react to like the date what the value of y is MSB y with 0 or not might might in a change the contents of accumulator. So, which is what we do not desire. So, we want a system to freeze the freeze the results in the accumulator. In fact, fortunately that was not a concern in the single cycle because once y become 0 then even if swapping and even if that like subtract operation happens continues to happen x does not get changed because x minus y still happens to be the same as the old x. In this case like you know this accumulator contents might get shifted corrupted and so on. So, that is why we want the system to freeze when count becomes 0. So, we will go to us we will make the controller go to a state called state done and stay there until the next trigger. So, here I am just like just avoiding the role of the idle state and all that there is no I mean you know you can enhance this particular FSM with some more states for appropriate protocol of start triggering the computation of like indicating readiness of the result and so on. But essentially the main part core part of the FSM is this. Here I am just illustrating that I do not want I do not want to use the same state even when count becomes 0 because the count becomes 0 like you know go to the same state yeah I mean it is a simpler more typical approach of having a special state for indicating the end of computation. So, in this state all the signals would be set in such a value to such a value that the system would freeze accumulators would not accumulator would not change by register will not unnecessarily keep shifting and so on. So, quite typically I said we would like to have a state in which we when the control is in that state we know that system is the computation is done. So, when count becomes 0 we move to that state in which we can disable the accumulator from further change like loading it is loading something into itself we can also disable the counter. So, that it will remain at 0. So, that even if we have where to decide to go back here the count would have remained at 0 and so on. Or as a matter of test you might prefer a variation of this instead of this might feel that this could suffice as it is if count is not 0 it will depend on MSB y and a lot of this signals are specified here. If MSB is 0 then just shift do not add decrement counter enable accumulator and so on so forth what else shift y left and similarly here we go to this we go to this. If count were 0 then we might we might take a like you know we might prefer to use a single state machine of course, it will have some inedic faces, but it is not wrong or it like you know it can we can still make it work by like you know generating the control signals as follows we disable the accumulator we disable the counter. Once we disable the counter the count is going to stay at 0 and the system will keep moving in will keep doing this transition and would keep continue to keep the accumulator disabled continue to keep that counter disabled in which case we know that system would not escape into this count will not get modified to something count will not get updated to non-zero and dense based on MSB some accumulator loading or y shifting will happen. So, with the help of this kind of thing we this control signal values will ensure that system will loop harmlessly in this state with everything frozen effectively or if you prefer you might do that this particular way have a special state just a way we had a special state idle to indicate the beginning of computation waiting for some trigger we might we should also we could also have this this is more prefer we are doing it it is clearly if you are trying to be trying to make it purely combinational there should be some protocol problem not really problem, but something not so clean so should be a matter of so, so let us describe the data path in very log. So, this will also consolidate help consolidate understanding of how very log semantics capture the data path as well as the controller. So, the data path data path is synchronous system right. So, what is happening if let us let us make use of single cycle controller if count is not zero rather like. So, the logic for updatering updation of. So, after having seen the data path and is simple finite state machine based controller for shift add based multiplication we will just try to capture this in very log just to consolidate our understanding of how the semantics of very log and how the synthesis as a will map it into the circuit that we had drawn. So, let us first look at the this is the controller and let us look at a data path this is the data path what are the data storage components on the data path is an accumulator there is a register inside a counter which is being updated there are flip flops in the counter which are basically memory synchronous memory elements there is also a register x which is fortunately not getting updated may be if you have a start state idle I mean that is the time x will be loaded from the inputs and there is a shift register for y whose most significant bit is being named MSBY. So, we have to see what kind of actions are taking place on y accumulator and a counter. So, we capture this in very log. So, this is how it would look like always at this is the description of data path in very log always at positive edge of the clock that is a triggering edge of the clock. If the control signal says for enabling accumulator says yes that is they must be we assume that there is a control signal controlling whether the accumulator can be loaded or not we call it enable accumulator. If enable accumulator has been asserted by the controller then we would look at the output of the controller which is the control signal shift add if shift add is asserted is true then accumulator is to be loaded with shifted version of itself plus x. So, that means we have to compute the addition of the shifted version of accumulator and x and load it into accumulator that is this particular thing. If shift if this accumulator is to be loaded in this current clock cycle then it would depend on what the value of shift add is if this shift add is 1 then x is to be added with the shifted version of accumulator and loaded back into accumulator that is this particular statement. If enable accumulator if shift add then accumulator is loaded this way else accumulator is loaded only with the shifted version of itself. So, if shift add is 0 then 0 is routed to the adder nothing happens just the shifted version of the accumulator is routed back into the accumulator. So, it effectively means accumulator has been shifted by a single bit. So, that is the logic for how accumulator is updated. So, that is the logic in this particular block. Now, about the counter of course, this is not complete very log code, but main part of is this. If decrement counter signal is asserted by the controller then the counter will decrement otherwise counter will stay as its own at its own value it is like it will have the effect of disabling the counter. Similarly, the shift register is to be modified if is to be updated if the control signal shift y left is asserted then shift register is shifted left by 1 bit otherwise it stays. So, this shift y left is a signal say sent to this particular shift register shift add signal is generated by the controller and it is controlling this multiplexer enable accumulator signal is generated by the controller is controlling the loading of accumulator and decrement count another output of controller is controlling the counter. So, counter is also in part of the data path and it is being controlled by the FSM. Then this remains to understand how the controller would be generating the control signals which are those are the signals shift add enable accumulator shift y left and decrement count. So, it is the combinational logic for describing the output of controller initially these are the not is initial these are the default values which are going to be changed appropriately in the appropriate conditions. So, if the current state is state loop then if the count is not equal to 0 that means that is the main part of the loop then we will be shifting arranging to shift y will be decrementing the counter at the end of this clock cycle will also be enabling the accumulator for loading at the end of this clock cycle. So, all the signals are to be asserted and, but about shift add it would depend on whether MSB is y MSB y is non-zero if MSB y is 1 then we will be like you know performing addition of x to the shifted version of the accumulator that is controlled by the signal which is the input to the multiplexer else the shift add will be set to 0 which would mean that 0 will be sent to the adder and which will simply have the effect of only shifting the accumulator by 1 bit. In the state done we force this enable accumulator signal to be de asserted which means that accumulator will not be loaded whatever might be happening in the adder at the end of the at the output of the adder or somewhere else. Similarly, counter will not be will be frozen by setting decrement count to 0. So, counter will not be decrementing we hope that counter will also not be incrementing we will have we just assume that we have a specialist counter which only decrements or freezes. So, so on so forth. So, this is an always block describing the combinational logic for output logic of FSM which is combinational which depends on current state and the status inputs from the data path like whether count is 0 or not whether MSB of y is 0 or not right and we know that the signals are being generated whether count is equal to 0 or not is generated by taking the output of the counter and having a 0 checker MSB of y is taken directly from the most significant flip flop of shift register of this. So, this completes our description I mean this can be easily wrapped up in a module and some appropriate declarations of signals you as an exercise you might want to upgrade this controller. You might want to upgrade this controller like in the case of GCD to have an idle state to have a start trigger and to be able to load x new values of x input and y input into x and y. So, this is assuming that at like on reset itself we have something in x register and something in y register that is good enough only for testing, but as a subsystem you would need like you know appropriate input triggers. So, hope like typically you can make use of one state like state idle or state start then this is the main state and this is the ending state and from here again you will go back to that idle state waiting for a start trigger and so on. So, this can be like you know enhanced into more like better protocol for using a multiplier system that they just left us an exercise we have I try to illustrate the main points and I hope that should suffice.


This study found that post-menopausal Tibetan women have a high prevalence of abnormal bone mass, with age, BMI, altitude and CREA levels being significant risk factors for osteoporosis. The study suggests that relevant departments should take targeted measures to promote health education on the prevention of osteoporosis in the general population and increase screening of high-risk groups for osteoporosis to improve bone health. This article was authored by Waicheng Zhong, Yashi Zhou, Peng Wang, and others.