 So who here has absolutely no idea what I'm gonna talk about and has never heard of the E1 software defined interface before You know, it exists. Okay It doesn't actually yet, but That's that's the whole point right So there was a previous talk At Osmo con in 2018 where I presented kind of the state of things and here I'm gonna try to focus on what I've been working on and Which is the Like the implementation that that uses an ice 40 FPGA as a basis for the implementation of this so because I just did the Ice 40 before I'm gonna just start with the hardware. So that's the first prototype I'm not really sure if I should actually didn't before but that was based on an abduino board which is a UP 5k development board which has horrible horrible layout and is pretty much non-functional until You beef up the ground connection so that there isn't ground Bounds around and then you add decoupling capacitors and some kind of stuff. That's just to get it working and Then that's the mess of wires with my different attempts at doing an E1 Phi I made a new board Which is this one And it's meant to plug into the ice breaker that I Mentioned before so it has a dual PMOD connector And this in this includes this that's the clock part So it's a 30.72 megahertz clock Because that's pretty much the only clock if you divide it by 15 you get 2.0 48 41 and I don't remember the exact ratio, but you can actually multiply it with the ice 40 PLL Into 48 megahertz for USB and so you have a both clock from a one crystal That's the USB interface. It's really just direct connection to the FPGA pins. You just have like the series resistor for I'm not sure why but impedance matching. I'm gonna say That's the E1 Phi that uses only FPGA Ios That's the way it works so I'm still using Obviously a transformer. I tried doing without the transformer But using only capacitive coupling couldn't make it work like I can make either ticks or Eric's work But when you have both you have too much common more in common mode noise leaking from one to the other and that doesn't work So, okay, I actually have to use a transformer Technically only need a transformer on one of the two side either Eric's or takes it doesn't make sense because they don't sell half a transformer Yeah, right So the transmit side is very simple, it's basically two resistors and you just send a person one or the other So you're gonna have zero The three volts divided by the impedance or whatever and see if you use a one Right, yeah, so the the physical layer link of On E1 is you get positive pulse or negative pulse when it's a one and you have no pulse when it's zero That's the kind of levels that you would find of the line So you get a positive voltage a negative voltage or nothing And then you have a bunch of encoding to transform your bits into those pulse So that you don't get too many runs of zeros because you would lose low synchronization. And so there is bit stuffing. No, sorry No, it's not bit stuffing. It's something else or whatever there you young It's called HDB 3 encoding And so you get positive negative pulses and that's what that's basically what you need to detect either a positive pulse a negative pulse or no pulse That's kind of a trinary encoding and so here if you Toggle that IO and not this IO you get a positive pulse if you do the opposite you get a negative Negative pulse and if you don't do anything well, you don't get many pulse And so yeah takes is very easy Detecting on the Eric side is much more complicated This takes more components That's just the termination resistor like the nominal impedance of the line is one on 120 ohm. So you put a 120 ohm resistor there to terminate the line and then you need to detect Pulse is that go up or pulses that go down now this circuit is made to be entirely symmetrical That's actually pretty important because if you load one side more than the other you get asymmetries and stuff like that And so this is this has been designed to be as symmetrical as possible to get the Best possible Signal integrity and detection. I tried an asymmetric one It works more or less, but this provides better result with I think It takes like a two more capacitors and two more resistors, which is it really doesn't matter So the general idea is that you again use the FPGA differential IO as comparators and You pre-biased them to be off which means so all the P bias here are slightly lowered and negative bias So basically I'm biasing this at zero point 33 Times the Vcc so like 1.1 volts I bias this sorry this is biased sorry at a 1.1 volt this is biased at 2.2 volts, which means that by default all the comparators are off and then when a pulse Arrives in one direction or the other it will push Both IO in one direction or the other so if you look you know if you have a positive pulse it will turn The comparator more off for one of them and actually turn it off turn it on for the other I mean, yeah, if you if you look at the connection it makes sense I am not sure how to explain it, but basically yeah when you get a pulse you you just Change that bias point enough so that in in one of the case it turns it on and on the other what it Plays it in the wrong direction, which means it's already off. So just more off I say but whatever Or I mean, it's it's off with more margin. Okay, right All the bias voltage in this test board they're programmable So I use a again presents the modulation was just less filtering to generate them But really if what I found You can generate them with just a resistor divider and that's that's gonna be fine That's what I'm gonna do and the final hardware version Yeah, I mean it's I wanted to test to run a like long-term Bit error rate measurements with different bias level to see exactly how much That influenced the bit error rate basically Because if if your bias is too great, then your pulse, of course, they don't Your pulse is not good enough to overcome the bias But if it's too small It will actually detect purse that aren't there. So, yeah So that's for the Hardware interface to the FPGA. So now what exactly is in that FPGA? well Obviously, I put the it's a you want to USB. So There's a E1 core and there's a USB core in there but coding everything in very log in a like in hardware Description language would be inflexible and not so software defined as a real good say And so the general architecture is that inside the FPGA I I created a custom system of on chip which has a risk 5 soft core That's you know executing a software like you would find on the at me or whatever And it just has a dedicated peripherals to accomplish this goal. And so those peripheral would be The USB core itself Which I presented before and the E1 Peripheral That does all the physical interfacing as well as all the E1 framing and D framing and it can Receive and transmits E1 multi-frames So if wait, I should have put a diagram of an E1 Give me a second Okay, so that's an E. That's what an E1 frame looks like up more or less. There's actually a bug about whatever You won't notice it If anybody can point me the bug in there Anyway, that's what an E1 frame looks like so you have a 32 time slots each of those queries is one bit, right? So if 32 time slots and then you have 16 frames when that's divided into first sub multi-frame and a second sub multi-frames And the sub multi-frames are relevant for the CSE computation basically and so the E1 core in the in that system on chip will take care of finding the alignment of that frame structure into the bit stream and You just tell him Okay, the next multi-frame you receive you write it at this particular address in memory and it will do this and you have a classic you know FIFO of buffer descriptors both for transmit and for receive for transmit instead of finding the frame alignment well, it will actually generate it and Correctly generate all the fixed bits here to provide the remote and with the With the alignment Okay So that's what the E1 coders and it stores all the data into a giant 64k buffer I mean giant in relation to E1. It's it's actually a pretty long buffer you don't have to use all of it of course and to lower the computational load on the on the soft core there is actually a DMA core that can copy data between the E1 buffer and USB transmit and receive buffers, so when you receive a multi-frame you can just Issues a couple of DMA command that copy them in the next USB frame to be transmitted The other peripheral that you find you can control the lead you you can talk to the flash which is useful to implement DFU for instance so that you can actually from USB update both the FPGA bit stream and the Software image that runs on it one interesting feature of the ISO that I forgot to mention is that it has a so-called warm boot and so You can boot by default a safe image and then the fabric itself can tell the configuration logic to go and fetch a new bit stream from the different address in the configuration flash so you can have the same bootloader and then user image that you would find in a in a classic microcontroller and have a safe update path You have a PDM which is again, presidency mediation that controls the bias voltage and Will help for clock tuning because one of the goal of course of this is to provide a stable E1 clock to the Base station because most of them will lock the internal O6 so to the incoming Betrayed of the E1 So yeah, something it's missing currently at the moment is a GPS DO. I didn't have any When I made the board but it's Really simple logic to add to the FPGA and debug you out and then you have The main RAM and the boot RAM that's actually necessary because the So as I said, it has a lot of memory in a single port RAM in one megabits The downside of this is you can't initialize it Which mean it comes and configured once the FPGA is booted That large area of RAM contains random data. It's not even zeroed out or anything Which of course your soft core still needs to boot from something Thankfully the small memory blocks those can be initialized from the bit stream. And so what I'm doing is I'm using two of those Block rams as the boot ROM mapped at the you know address zero and they contain by default a small assembly bootloader that will use the SPI peripheral to go and load the actual application program into the Large memory and then jump to it and then that small memory zone is then used as the stack space for the C run time Yeah, I think that's pretty much it for the other side of things I The software running on this is currently very Basic in the sense that I've got an E1 Test software that implements a loop back So, you know every buffer it receives it just feeds it to the transmit core and I tested that This actually works just fine Which kind of validates the receive and transmit path I Also have Working USB stack and by that I mean something that responds sufficiently good to the control transfer to be enumerated I tested isochronous transfers as well At least the receive Part I didn't test the transmit part, but there's no reason That wouldn't work, but I don't have an actual firmware that Implements what's actually needed to do that. That's something I Was hoping to be done by now, but I had some issues last week that needed debugging and Unlust a bit of time on there, so but I'll be working on that next I Did some work also on the host side of things because you need something to well talk to that dongle and and basically bridge USB to Osmo BSP and C yeah, Osmo BSC and Osmo MGW I think is going to need to talk to that and so both can't talk to the To the USB device So general idea is to have a demon a demon that we call Osmo 1d that's gonna Allow client application to open and close time slots and stuff like that And that's the That's the client API for for that demons is that you You can query different things so you have a interface level or line level and the time slots level and you can query information about them mostly well for interface you can mostly query how many lines it has and Line, I think the only thing you get as a status currently is if it's up or down and then time slots you have different mode HDLC or row mode and When you open all those communication go over unique sockets and so when you call a TS open it actually Enables the time slot and actually start transmitting whatever you send it you Because it's over of unique sockets when you send the packet to open it what you get back is an actual file descriptor Which you can just write your packets to And yeah Yes, I Since it was possible I figured that oh, yeah, so the question was if I was doing a file descriptor passing and and yes The message you get back as the status and if the if the status is okay You actually get a file descriptor through the unique sockets And that file descriptor uses Sockseck packet Yeah, I screwed it with socket pair possibly The protocol is made to be very small and easy it's a few fixed size a structure which you know map one-to-one to the the query and was just in a Provision for a version number if at some point we want to to extend it or all things like that, but Yeah, at the moment it's I mostly implemented the server and client logic and how they talk to each other but there is not actually the Communication to the USB side because what the USB side isn't implemented yet so anyone that wants anyone that wants to help with that or to actually use that API to Go into Libos more abyss to add support for for it in there and in Whatever Osmo MGW uses it does it use also Libos more at the moment It's not supported at all. So you the support for you one needs to be introduced at all for Right, yeah, and That's pretty much what I have so if anybody has any questions so First of all, I think it's amazing how much effort you put into it. It's really it's a very very How can I say I enjoy very much observing it? I would love to do something with it But time is of course always a constraint So the the risk 5 this Pico risk 5 existed in using unmodified so because I think at some point you I did I did cut my own microcontroller also for the ice 40 I didn't mention it because I didn't have time to draw a Diagram for the Internet of it. And so I cut it actually my own 16 bit microcontroller With its own instruction set and compiler assembler and C compiler But because I was under the assumption that the risk 5 would be too big but Through some configuration. I I could reduce the size of the the PyCore V 32 risk 5 and Also managed to clock it fast enough Originally, I wanted to clock all the logic at 48 megahertz Which is just not possible for the PyCore V 32 At the moments, I actually don't meet timing for this But given the huge timing margin I have that I show in the overclocking thing is it was just fine even 20% faster than I I need I needed to I might so here I draw this zone is what's clocked at 48 megahertz, which is only the USB core. I Might actually implement Cross clock So it is that this block crosses clock domain for the wishbone internal bus between 30.72 and 48 I might actually run The sock itself at 24 megahertz to meet timing in the future if if need be but at the moment it works just fine, and I'm kind of hoping the open source tools will evolve enough to Meet timing is that and how much Capacity do you use in the fpga so at the moment? I'm using around 70% of the logic inside the fpga The majority of which is actually taken by the PyCore V 32 the PyCore V 32 basically takes about 1500 Logic elements, and I'm at 3000. So it's like a half the design is that Ideally in the final board, I'd like to put two E1 interfaces Because I have the Ios for it, and I think it would enable some interesting use to have two interfaces like Active sniffer or actively be able to inject the data into one time slot and not the other that kind of stuff that you can Do if you have two interfaces possibly Yeah, thank you