 So thank you for coming. So this session will be about accelerating silicon design with Jupyter notebooks and open source PDKs. So it's going to be an interactive session. I'm going to explain briefly what it is about. And I'm going to do a live demo. There's going to be a link on the screen. If you want to open that link and follow the demo by yourself, you will be able to do so. So feel free to open your computer and follow if you want to follow along. So first, my name is Joanne Frosin. I go online by Jupyter. I've been at Google for no 10 years. And I'm a developer-relation engineer. So I'm working mostly on a developer-facing product and trying to make the experience better for external developers. And recently, I joined the hardware to Chien and focusing on enabling people to do custom silicon. So the hardware world is new to me. I didn't really know about custom silicon before joining that team. So I approached this with the software engineering mindset. So my team mission at Google is to make custom silicon easier to build for everyone at scale, just like software. So we really want a team at Google and a team outside of Google to be able to think of designing their software and their hardware and their silicon at the same time so that you could build a fully accelerated experience and build exactly the chip that your application needs. The vision is a bit like this. Imagine that if you are a software developer, you have the dash-o flag that you can pass to your compiler to decide what level of optimization you want. Imagine if there was a flag that allowed you to pass like silicon. You could generate an hardware that optimizes your algorithm and generate the hardware description for optimizing your processing. So that's a bit it doesn't exist yet, but that's a little bit of where we want to go, like the vision. And my team, like two years ago, released like a paper at ICAD, ICCAD 2020. That was about the missing pieces of open design elements. And there is also a version of that paper in Japanese on this website, so on developers.google.com slash silicon slash research. And basically it came out with the following assumption. Is that in the current hardware design world, in order to enable this vision of co-designing software and hardware at the same time and having software engineer that can build custom silicon, there are missing pieces. And those four missing pieces are first like an option to have open source PDK. Like currently, when people want to manufacture custom silicon, they need to sign an NDA with a foundry. So it's not like some API that you can look up on the internet like we do in software all the time. Like you literally need to do a contract with a foundry to be able to access a specification. Like most of the tooling that allow people to manufacture silicon or to design custom silicon is proprietary. It's not necessarily a problem that it's proprietary, but it does like handicap people the capability of running this software wherever they want. Like if they want to run it on their laptop, usually they need to use a license from their work, so they won't be able to run it on their personal laptop. If they want to use it as an university on like various computer lab and the university usually it's restricted to like a single computer there. And even more, like if they want to run it on the cloud on thousands of VM, like they won't be able to do that with a workstation workshop, so a workstation license. So like having an open source like silicon to an option allow really people to get started wherever they want. They can get started on their laptop on the cloud, like on the computer or the university. They can get started with those tools freely without constraint. And the other thing that we identify is that there are missing open source IP block and generator. Like often the block that comes with a PDK often come with the tool of the proprietary tool that come with it. And so really if you go out, if you use a different tool or if you want to use a different PDK, there is not a real way to repurpose this IP to different technology. And so like in the software world, it doesn't work like this. We have a lot of libraries that can get ported across a variety of environments. And so we can freely reuse some open source block and be bigger pieces out of that. And so the idea is that if we want software engineer to be able to succeed into designing custom silicon, there needs to be designed block that it can reuse freely. And the last thing is like cheaper and faster manufacturing option. Like when you want to manufacture custom silicon, it takes like a month and multiple months to get the silicon back. And it's often cost like hundreds of thousands of dollars to manufacture like a single chip. And so like it's not accessible to like an obvious or a student. Like they often need like to have like some kind of arrangement with their university to be able to do their first step out. So we want also to democratize that, like make it so that it's easy for anyone to get started and manufacture custom silicon. And so we think that if we have those four pieces, there will be like an open source silicon ecosystem similar to what we have like for software, where like people that don't know anything about design and people that know a lot about design will be able to collaborate and be things together. And so like that's what Google decided to try to fix like to fix like those missing pieces. And the thing that we started working on is open source PDKs. So we worked with a foundry called Skywaller in the US called Skywaller technology. And we managed to convince them to open source their 130 nanometer PDK. So it's a very old technology. It's more that 15, 15 year old, but it's a fully open source on GitHub under Apache two licenses, meaning that anybody is able to look at the PDK, student content, look how the standard cell are implemented and come up and use it to build their own design. So and they don't have to sign any NDA or even to talk to Skywaller in order to do that. They can get started right away like they do with any like open source of their project. There is also a different variant of that PDK, the Sky 130B variant, which is very interesting because it has support for RIRAM. So it's like a kind of advanced or like research, research functionality that's very active in research right now that's available on this older node PDK. More recently, we also partner with a new foundry called Global Foundry and we managed to convince them similarly to open source at 118 nanometer PDK. And so similarly, it's available on GitHub freely for anybody to use under the Apache two licenses. And we also like partner further with Skywaller technology for them to open source their 19 nanometer PDK next year. And so today during this little tutorial, I will show you how to use like the Skywaller APDK to produce like a very simple design. And so the toolchain that we're gonna use is all based on the open source tool and it based on those tools that I want to introduce briefly to you. So first there is like an eye level synthesis tool kit called XLS that's actually developed by Google, by half of my team that the team I'm part of at Google. The idea is that you write like your description into a eye level language. So either a syntax that's close to rust or C++ and then it can generate and pipeline your code for you and generate the hardware description for it. Then we're gonna use like for synthesis, like the thing that map or hardware design to the technology we're gonna use USIS, which is a very well known tool inside the open source hardware community. That's used also a lot for people that do FPGA design. Then for the Placent root tool, so the thing that turn like or technology map design into an actual layout, we're gonna use a project called open road. So it's gonna do the floor planning, the placement and the routine for design. And we're gonna orchestrate that tool with a flow called open lane. And last, when we get like or cheap layout done, we need to create a file to be able to send it to the Foundry for manufacturing. And for that we're gonna use two tool like magic and K-Layout, which are layout tool that are used to perform the last round of check on a layout and make sure we can generate a GDS file that's comply with the Foundry specification. So from this, we are gonna go basically from a .x file, which is like a file that looks like a look like code, like just regular code that any software engineer could write and done to an actual GDS file, which is like the actual silicone implementation of that design that could manufacture on with either SkyWater or the Global Foundry PIK. So in order to install those tool, like before we started on engaging with that community, like all the tools were a little bit all over the place and a lot of those tools have to be built from source. It could be like a really, it could really slow adoption when people have to like perform a lot of common inside your algorithm in order to get started. So in order to make that easier, we created like a set of Konda packages for all those two chain element. So we have package for each of the PDK and also a package for open lane that include like all the dependency of the tool I mentioned there and a package for XLS, the front end that told you to do high level synthesis. So if you use like a Konda packaging system and you type those line in your terminal, you should be able to get a fully functioning two chain to go from a code like a description to actual silicone. And like the other thing that we found out was really interesting for people to be able to share that design with other is the usage of Jupyter Notebook. So Jupyter Notebook is a very well-known like component that a lot of people use inside the ML or data science field. It's basically an environment into which you can type documentation, commands and serialize the output of those commands. And so once you share a notebook with someone else, he's able to see all of that. Like the documentation, the command that you run, the result and you can also like build some pretty visualization around those results. It's a very useful tool to create reproducible research. And we think that it's also a useful tool to be able to produce reproducible hardware design. Basically the vision is that if you share like your notebook with someone else, you should be able to run the same tools that you run and be able to get the same result. So I'm gonna go now and demo briefly that and you're free to open that link if you want on your computer. There is also like a short link there that you can open by yourself. And then I'm gonna leave you maybe like 30 seconds to open that if you want and then I'm gonna go through the demo. So is that okay? Do you understand what I say? Am I speaking good enough? Taps up if it's okay? No? Okay. Okay, so let's go through the demo. So if you click on that link, you should arrive to that page which is like a repository that has a lot of different notebook around like open source silicon. And the one that I want to show you today is like this last one. The one that we used actually for running workshop at Todai and Tokyo Tech in Japan here as of this month. And so when you open that link here, the opening collab, you should arrive on that page. And if you want to follow it on Japanese, in Japanese there is actually a Japanese version of the notebook here that you can follow. And if you open it in Japanese, it should show up like that. And so is that big enough? Maybe I should zoom a little bit. Okay. So when you, so the idea from this notebook is to go from like a code description to actual like silicon. So the first thing that you need to do is to install the tools. So if you click here on install dependency, it should run for maybe two minutes, two or three minutes. And like install all the dependencies that you need to perform that tool. Currently like the actual content of the thing that installs the dependency is hidden. But if you are curious and you want to look at how it's done, you can click on this open show code button and you should be able to see it. And so it installed like a lot of packages from Konda and then like set up them so that they can be used from within collab environments. And this environment collab, the thing that we are showing here is an environment that Google has to run notebook on Google infrastructure. So when you click like this cell, it's actually run on Google data center. It doesn't run on your computer. So you don't like mess up with any of your computer system and you can use freely like Google resources to do your research or to do your experimentation. So the thing that the first part of the flow that we are gonna run is this hardware high level synthesis flow. And so the idea is that we start from a description that's either written in C++ or Rust or a dialect of Rust like DSLX. This is the thing that we are gonna use today. And then we go to an intermediate representation. Then there is some optimization pipeline that are going on. And then like this code gets scheduled depending on the number of pipeline that we ask for. And then we get some virilog which is like an hardware description language that goes into most of the other idea too. The interesting in that, what the thing that makes this hardware synthesis, hardware high level synthesis workflow a little bit unique is that because you write your description into a regular programming language, you can write test for it. And just like you do in software. So you've got a chance to validate like your logic and your design like before actually starting to think about hardware. The other interesting thing is that it does this intermediate representation which allow like other tool to plug on this intermediate representation much like a regular like software compiler to chain and perform optimization on it. One of those tool allow you to do functional simulation using LLVMJIT. Meaning that we can take like the intermediate representation that get generated from your hardware from your hardware high level description and run them at a native speed on your computer. So you don't have to wait to go to system virilog or virilog and to go to the actual like hardware description language to perform some simulation. You can perform like some very quick and native simulation and would put like some 8x664 code for your simulation. And you can also perform like some logical equivalence and some formal testing on the hardware on the intermediate representation as well. So which make it like really interesting because you can like, you can imagine that a lot of different tool could plug on to that ecosystem. The other thing that's a little bit unique is that like usually when you think about design you have to think about how you want to pipeline your design. How you want your computation to be performed along the clock cycle. And that's usually pretty invasive decision inside your design. You need to kind of rewrite the virilog in order to accumulate more or less pipeline stages. Like here with DSLX, what happened is that this become a tool decision. So you write your hardware description, what you're processing in a data flow like language outside of the pipeline constraints and then with the passing parameter to the tool you decide which kind of pipeline you want to ingest. So I'm gonna show you a little bit of an example of what it looks like. So here we have kind of the simplest design possible. We have a little function that's adding two bits. So it takes two arguments, one A and B that are both like one bit wide. So that's like what the UI U1 stands for and it returns like a two bit output because like when we add that two bit that could be like a carry. And so we need like this additional bit to accommodate for that. And we will write like that operation much like we'll write it in software. We say like the output N is equal to A plus B. And when we put this as the last description of this function, which will cause like the, any invocation to the other expression to resolve to that number. And like, but that's like kind of a regular function with two parameters. Now we need to map it to a chip. And like for mapping it to a chip, I declare like another function on top of that. And I decide the number of input and output that my chip will need. And here I say that I will have like eight IOPIN in and eight IOPIN out. So that's much more larger that my one bit, one bit other that I'm doing. So I need to kind of slice this input to feed them inside my function. So here I say I take the first bit of input and send it to the parameter A. And then I take my fourth bit of input and like send it to the parameter B. And that's what I was saying before, like I can run tests for that to verify it actually works. So I could call like the other function and verify that one plus one equal two. And I could also call like the user module function like split my bits according to the conversion. And then I show and verify that I get actually my result bit here. So if I run like this cell, I can see that the unit tests are passing. So it means that my, at least as it is described currently my design is functioning correct. And so now I need to convert that into an actual hardware description. So the first step that we do is that like we convert this to this intermediate representation, this IR I was mentioning before, which will like be, it will look like this language. So it will use like a series of primitive that described like the actual hardware operation I'm trying to perform. So you see that with like this ad here, there is a bunch of bit concatenation and bit slides that are happening. It's a more verbose, but more descriptive, the more explicit description of what I'm trying to do here. And then the last step is to convert that to virilum. So there is another tool inside the tool chain, access to chain to do that. And so I can specify path to my intermediate representation and get a virilum file out of it. So here you see it's a little bit silly because the actual virilum implementation of that is very similar to our inputs, but you can imagine that you could develop like much more complicated design that resulted in much more verbose, virilum description. And so now once we have that virilum, we can get it through the open source silly contusion. So we want to get that virilum to describe like what the actual hardware that we want to implement in a virilumization like just add to number or add to it into actual gate that are laid out on our design. So we are gonna run a flow that's called open lane that's compromise of a lot of different tool that perform all the operations that are necessary to get like this actual GDS file that we can submit to the firmware. So the first thing that we need to pass to open lane is like some configuration. So we need to basically physically map or design to what it puts like on a chip. So the first thing that we need to say is how big we want our chip to be. So here we are seeing that we want our chip to be 50 microns width. And then we need to specify like the target density. How much packed we want the, how much tight we want the gate to be packed together. We want them to be spread all around this 50-micron area. And we want to get them really, really tight. And the other thing that we need to specify is a path to our virilum file and the name of our top level module. We also need to specify the clock. Here we don't have any clock because we have a fully conditional design but if we had a clock we would specify here and we also specify like the period like how many seconds we want this clock to be. The other thing that we need to specify is the pin because our chip is gonna have pin and we need to tell the tool where they should be. So you remember we had like eight input and eight outputs. And so we have this little file that allow you to say I want like the IO input to be on the west side and I want like my outputs to be on the east side. And that's what like those directives stand for. And once we have those information we can try to run the flow. And here I'm gonna write like I wanna run the step of the flow one by one so that we can see the intermediate result and understand how or I'll have a description turn into actual silicon. So the first step that we need to perform is CTSIS. So it will take like RTL description like the virilum that I mentioned before and it will map it to the technology. So it will understand that I need to perform this ad operation and what type of gate I need to perform on that. And it will put like basically a graph of those gates and those connection between them. And as part of the result of that first step we can get like an estimate on how many gates our design is using and we can get also an estimate of the delay how long it takes to perform like this operation. So once I've written like this I can like run the preview here so you can see it run the flow here it's done with the CTSIS and here I can see how the design is actually implemented. So you can see that there is two gates XOR gate and gate and then there is this little thing at the end that like pack six zero on the eight on the six like most significant bits. So this is like the usual way to implement like another function for one bit like the least significant bit will be like the XOR of the two input of the two bit input and the most significant bit will be the end of the two inputs. And you can see here like what's interesting is that this IOHIN here and the out here and the correspond actually to like the variable that we used inside the original code here. So that's like also the nice thing is that like we can map like the connection that are happening between the gate to our original code. And so now like we have like kind of the logical description of our gate are connected together but we still need to turn that into an actual like cheap layer. So the first thing that we do is like we run floor plan. And so it will take this technically map netlist and would put like a die that's corresponding to the size that we requested for. It will lay out the IO for it. So the input and the output that we requested and set up the Polly power delivery network so that our gates could get connected. And the primary metric that we get out of this is like an estimate of the area that your chip is going to be using. So here the floor plan is completed. And if I run the preview you can see here that we have like or basic like chip. You can see here we have like the eight input and the eight output. And we have like the Polly the power delivery network that's like layout in the middle. But you can see that our end gate and our door gate are still on the bottom corner here. And here we have our own gate and here we have our door gate. If we take a look at this, we can take a look at how the door gate is implemented. And the reason that those are still at the bottom is because like we didn't run placement yet. We just like did like the floor planning. So that's what we're going to do next. We're going to do the placement step. So it's going to take like this physical layout that we prepared. Like it's going to take like again, like our technology map net list one dozen to get that we need to lay out. And then it will come up with a cell plus like somewhere inside the design. And for that we'll be able to get an estimate of the actual density of our cell, how packed they are together and also like an estimate of the timing closure. So depending on how far away or get out, this will also affect our timing. So if we run placement, you can originally read the preview here. So here you can see like we have a little bit of more complicated design. If I remove like the two things on top, I can see that like my end gate and my door gate got laid out like in the middle of my design. So like the tool like decided that this will be the good location for those to get to be here and provide like satisfactory timing and satisfy like the two, the density property constraint that I also added. And the next I'm going to do but those gate are still not connected together. So that's why we need to perform the routing step. So the routing step will take like this physical layout with the component that are placed and like draw some little wire like between them and connect them to the input and to the output. And like for that we'd be able to get a much more precise prediction of our timing criteria. So if we met like the original frequency that we asked for but we also be able to know how much connected either design like how close those wire are together. So it takes a little bit more time but if we run the preview here, we see like let me remove like the top layer. So it's a little bit more easy to understand. So like here we can see like or input pin. You see like for bit one or bit zero, it goes inside this buffer and goes into the first XOR gate here. We have like input four. That's also go through a buffer and go also in that XOR gate. Here you can see the connection between XOR gate and my end gate. And I get like those input routed similarly to my end gate that's here. And then I get them routed here on the bottom to my list to my two end bit. So like this bit zero and bit one. And so like here you get like kind of a good idea on how like your original design is mapping to gates that are connected to each other. And the last step that we need to perform is sign off. So we're gonna perform a series of check that actually verify that our design could be manufactured. So it will take like the foundry specification and verify like that the spacing between the gate is correct, the spacing between the wire is correct that we don't have anything outside of the die and verify more complicated like constraint that are specific to the foundry. It perform like a lot of analysis. And at the end, we get like a whole like chip that's ready for manufacturing. And usually like when you integrate, I wanted also to show you that you also get a bunch of metrics that give you like for example, breakdown of the gate that gets used for your device that give you like a count of the wire, an estimate of the actual wire length of how long of a wire you have across all of the design and some metrics around power and timing measurements. And usually when you want to submit that design for manufacturing, you need to include it into like a harness that the foundry provide you. And I will tell you later that Google provide an option to actually manufacture this design for free. The other thing I wanted to show you is that like that's cool for another and that's a nice way to kind of learn those different steps that we can also like do much more complicated thing. And here like I wanted to show you for example that say we designed the same chip that has eight input and eight input that instead of doing just adding two bits we are gonna try to multiply like four bit inputs together to get the eight bit outputs. So like that's will be a mule four function that takes like the first four byte and that like take the second four byte and show them into that function and fully implement like a multiplication. And like I can like I think I can write some tests in advance to verify that this is actually what I want to do. So I say that eight by eight should be equal at 64 and I also verify that it works for the higher level function when I pass like all the input into a single eight bit design. And so if I run that test it will fair because like my function here is returning zero. It's not actually implementing like the multiplication. If I wanted to implement the multiplication algorithm by myself with only the primitive that I have that would be also like difficult. But the nice thing with a nine level synthesis language that often come with a standard library or function that you can use right away. And so if I look at the standard library for XLS and I search for multiplication I see here that there is like actually two multiplication for function like an inside multiplication and a sign multiplication function that I can use right away. So I can go back inside my code and do here call like the STD U-Mule function and pass my two inputs. And here I can see that I pass the test. So like I know that like this function is performing as I expected. So now similarly than before I can convert it to very long. And here you can see it's funny because in very long it also mapped that to a nine level primitive. So it's like implement a multiplier of four bit by four bits. And then it will be up to synthesis to figure out how to actually implement this multiplier using gate. And so that's what I do next. I perform the step up to synthesis and then I can preview the actual. And here you see that it's a lot more complicated than it was for the header. Like if you actually want to implement a multiplication like there is a lot of things that you need to do. There are gonna be a lot of gate here. And that maybe doesn't come as a surprise for if you are already like familiar with hardware and how like CPU are implemented but we run this workshop with a lot of computer science students and they were really surprised by that result. They didn't really expect like multiplication to be so complicated to implement using hardware. And so next like we can write like similarly the open name configuration for a design. So here we have like 50 by 50 and still this 30% density that we want. And we can run the flow. And here you see that the flow is failing because we have a lot more gates than before to put together. So here like we have two solutions. There's someone has an idea of what we should do like no. So like we have two configuration that we can specify either the size over die or either the density. So like those are the two parameters we can play here. We can either have with here that we can either make the chip bigger or we can make it more dense. So because I don't want a bigger chip because it takes more time, I'm gonna put like a bigger density. And so if I put zero seven here, and so I say that the gate are allowed to be a little bit more packed together. Hopefully it should allow me to get a past placement. So here it's gonna be take a little bit more time because there is a bit more to do for the tool to actually wire all those gates. And like you can see here the log is a little bit terse. Like you don't see a lot of information about what's going on. But if you look at the here inside the run directory, you actually have a full directory with all the logs for all the tool for each of the run that you do. So you can really dive down if you need to. And then I could like print the metric. And so here I see that the breakout of gate is a lot more here. If I look at the gate, I have like 10s on gate, like 13s on gate. And I should also see that the wire length almost like multiplied by, almost multiplied by 10. But my chip is not that bigger because like I mentioned to pack more density inside of it. And finally, if we try to preview it, we can see here, the player, you can see here like all the gate that are laid together and all the connection like between them. So that's one example of like a more complicated design. It's not like the most complicated design but it's a good like, give you like a good idea of the range and how the tool can scale. So I'm gonna go back to my presentation. How long? I think I still have five minutes left. So I may not have time to show like the full demo I wanted to show, but I'm gonna show you like this very quickly. So the idea is that now that we have like this notebook that we can run on one design, we can define like some parameter for it. Maybe for example, like the density and the area size that we were able to parameterize and a matrix that we want to score this experiment again. So for example, we could say like we want the chip that yield the last power. And when we have like this kind of notion of input input that we want to correlate, there are services and open source tool called Vizier that allow you to do parameter turning on this. And here I have an example of me running this design on a RIS 5 chip. So a much more complicated design and kind of playing on those two parameter like the die area and the density and trying to yield the design that consume the less power. And so here you can see like 10,000 experiment I performed and you can see like slowly converging toward like this good ratio between area and density to achieve the least power. So the least power design are in blue. You can see it's crying a lot of things all over the place at the beginning and slowly converging toward that line. And I'm sure that people, for people that are deep into the field of hardware engineering or Silicon like they know about those parameters and they know how they correlate together. But for people that are new coming from software, it could be really hard to kind of get the same intuition. And the nice thing is that we can use the cloud and we can use that parameter tuning to actually perform this operation for us and kind of produce the experiment and the rest to kind of find the same results. And because we do that into notebook, we are also able to produce like some nice visualization on what's actually going on. And I have a quick demo of that that I can quickly show which is like basically the parameter tuning thing. So like there is this project I deployed on Google Cloud and I have like the surf design with a notebook that's really looking really similar to the one I was showing before. And here you can see instead of producing like just a few gates, it produced like thousands of them. And then I have like this other notebook that I use for tuning. I specify that I want to tune the target density and the bandwidth and that I want to minimize like power. And then I run a job and I specify that I want to run like 500 job with batch of 20. So every 20 job, I will get some metrics for those 20 parameter. I will send them to the optimization system. It will be returned to me like 20 new parameter to try for. And with that I will be slowly converging toward like a design that kind of meet the metrics that I'm asking for which is minimizing power. And so after I'm done running this experiment, I can actually fetch like all the notebook that were generated by this experiment. So I have a view of all the experiment and all their parameter. I can visualize like each of them and kind of see which parameter got selected. Kind of get like the full log from the design including up to the layout at the end. And when things don't go so well, I can see the exception and kind of troubleshoot what the given run was not successful in here. Like if you can see here, the density and the bandwidth were really small. So it's likely not to fit. So it's likely to be one of those experiments here that didn't yield a successful design. And after what we can aggregate all those metrics that we have inside the notebook and can generate like an aggregate in a table and know which of the design consume the less power. So it's like the experiment 230 which had like those parameter. And we can also generate like a visualization on how they map to the parameter space. So here we can see like all the experiment that got yielded similar to the thing I was showing before. And so that's the idea that you can design like use notebook to design like experiment that goes end to end from like your code description to the active chip. And then you can orchestrate those experiment and do parameter tuning to find the best parameter for your design. So the last thing I wanted to mention is that like so Google is working on making those two better is working on open sourcing those PDK but we also realize that it costs a lot of money to manufacture chip. And if people want to actually fabricate their chip they need to have a way to do so. So we run this open MPW shut up program and the rule are very simple. So you'd have to pay for anything for manufacturing your design. Google is going to pay for the mask and pay for the wafer. The only condition for you to enroll inside program is that your design is open source. So as long as you have an open source design you are eligible for that program. And if you submit a design program you could be one of the 40 projects that are selected. We run one of those shut up like once every two months and the idea is that we try to reproduce design that are reproducible using this open source tool chain. And at the end you get like a board, a little board like this with a few chips for you to test. We run this shuttle like since two years now and we've seen like really increased engagement. We've got like as many as 100 designs submitted to the last one. And like lastly, like if you want to know more about that program and know more about the open source tooling and know more about the notebooks that I mentioned, you can go to this website developer.google.com slash silicon and we also have like this blog post that kind of sum up like the whole program. And there is this open source dash silicon that they have a community on Slack where there is more than 4,000 members that are kind of unrolling on the shuttle and talking exchanging information about how to run the open source tool. So that's it for me. Thank you.