Veera[m] | Just for knowing in XER, CA is one bit only but here it is set as e.ca = 0b11 (0x3) why? | 01:17 |
---|---|---|
lkcl | CA and CA32 are in the same XER sub-register | 07:51 |
kylel | veera, it basically shifts one of them to the left and adds them together resulting in 3 | 11:42 |
lkcl | as in: bit 0 is CA, and bit 1 is CA32. | 14:00 |
lkcl | Power ISA requires, in 64-bit mode, for those to be the same. i think. something like that. | 14:00 |
lkcl | whatever the reason, you'll see both of them set. | 14:00 |
lkcl | ghostmansd[m], i've an idea. we've a nominal amount of BTC (donated). how about we send you some of that, as a "deposit"? | 14:07 |
lkcl | if you really need to use it, you convert it. | 14:09 |
* lkcl waves at octavius | 19:14 | |
lkcl | moornin. you saw the research i've been doing into nmigen pins/resources? | 19:14 |
lkcl | Chips4Makers[m], i tracked down an appropriate location to put JTAG Boundary scan [when using nmigen] | 19:15 |
lkcl | https://bugs.libre-soc.org/show_bug.cgi?id=50#c6 | 19:15 |
octavius | Hi luke, yeah I have. Atm is a little overwhelming to me. Does the JTAG Boundary scan effectively look like a giant shift register (where each SoC pin is a bit)? | 19:16 |
lkcl | it's actually very simple: create a new Platform "MixIn" which overrides set_input, set_output, and set_input_output, to do exactly what you'd naturally expect to be done | 19:16 |
lkcl | yes | 19:16 |
octavius | What is set_input/output/io? | 19:17 |
lkcl | but it's not _one_ bit | 19:17 |
lkcl | it's 2 bits | 19:17 |
lkcl | one bit as the actual pin | 19:17 |
lkcl | one bit to be able to set whether it's connected "through" | 19:17 |
octavius | ok | 19:17 |
lkcl | or whether it's connected to the JTAG for "Scan purposes" | 19:17 |
lkcl | caveat again: | 19:17 |
lkcl | on bi-directional pins, it's _three_ wires | 19:18 |
lkcl | wire 1: the input wire | 19:18 |
lkcl | wire 2: the output wire | 19:18 |
octavius | oh, you're talking about gpio | 19:18 |
lkcl | wire 3: the pad direction (oe), whether it's an input or output | 19:18 |
lkcl | yes, that's what Boundary Scan is | 19:18 |
lkcl | Boundary Scan is "full complete and total redirection" of the entire GPIO | 19:18 |
lkcl | every single one | 19:19 |
lkcl | into a Shift Register - if requested | 19:19 |
lkcl | and not into a Shift Register (direct connection of peripheral to actual IOpad) - if not requested | 19:19 |
lkcl | this controlled - again via the same Shift Register - for absolutely every single pin, on a per-pin basis | 19:19 |
lkcl | where each pin can be | 19:20 |
lkcl | InType | 19:20 |
lkcl | OutType | 19:20 |
lkcl | InOutType | 19:20 |
lkcl | TristateInOutType | 19:20 |
lkcl | get_input, get_output and get_input_output, sorry | 19:21 |
lkcl | https://git.libre-soc.org/?p=nmigen.git;a=blob;f=nmigen/build/plat.py;h=c1d8fc693c0c180d56f319433889b10125ee573e;hb=e88d283ed30448ed5fe3ba264e3e56b48f2a4982#l203 | 19:21 |
lkcl | further up, you can see the enumeration of all pins: | 19:21 |
lkcl | https://git.libre-soc.org/?p=nmigen.git;a=blob;f=nmigen/build/plat.py;h=c1d8fc693c0c180d56f319433889b10125ee573e;hb=e88d283ed30448ed5fe3ba264e3e56b48f2a4982#l146 | 19:21 |
lkcl | and the Xilinx Platform overrides get_input, get_output, and get_input_output | 19:21 |
lkcl | connecting them to the requested FPGA IOpad resource | 19:22 |
lkcl | we don't want that | 19:22 |
lkcl | we want, for every single "requested" pin, that they be wired *FIRST* to JTAG Boundary Scan | 19:22 |
lkcl | and *THEN* to be returned. | 19:23 |
lkcl | having found the right code-point, it's actually dead easy | 19:23 |
octavius | Apologies if I'm slow at this, the explanation is difficult to visualise in my head. I read a quick article on JTAG (needed a fresher), and made a simple diagram for the single GPIO block. Uploaded it here: https://ibb.co/bg9vYtY Can you confirm if this is correct? | 19:47 |
octavius | To fully control GPIO from the JTAG chain, all three signals must be muxed | 19:48 |
octavius | In our case though, not every pin is going to be GPIO (such as RGMII or ULPI), so we probably don't need a 3-6 mux for every SoC pin? | 19:49 |
octavius | So you want me to create a new Platform class which adds a mux to the in, out, oe signals of the pin object in get_input, get_output, get_tristate, get_input_output? If so, that does seem straightforward. I'd just need to know the names of the JTAG signals to connect to | 20:13 |
lkcl | yeah! that looks pretty damn good actually | 20:14 |
lkcl | that's worth dropping on the wiki | 20:14 |
lkcl | yes, all 3 must be muxed... | 20:16 |
lkcl | ah ok i am using the word "GPIO" in a general context, sorry | 20:16 |
lkcl | in the context of "JTAG", GPIO could be "a pin named GPIO0" or "a pin named RGMII_TX0" | 20:17 |
lkcl | sorry about that | 20:17 |
lkcl | so, yes, every single one of the pins - RG0_TX0, ULPI0_DATA0, GPIO5, I2C_SDA, everything - absolutely all of them must be routed through JTAG Boundary Scan muxes. | 20:18 |
lkcl | otherwise, how would you: | 20:18 |
lkcl | a) test the IO pads without the function potentially being faulty | 20:18 |
lkcl | b) test the function without the IOpad potentially being faulty | 20:18 |
lkcl | So you want me to create a new Platform class which adds a mux to the in, out, oe signals of the pin object in get_input, get_output, get_tristate, get_input_output? | 20:18 |
lkcl | no, not add a mux: connect to a pre-existing JTAG object's pin-resource | 20:19 |
lkcl | this will need to be done in small steps | 20:19 |
lkcl | line 64 of class JTAG | 20:20 |
lkcl | https://git.libre-soc.org/?p=soc.git;a=blob;f=src/soc/debug/jtag.py;h=4b4f17a97d672c3f22b668008a1c058ac2500da6;hb=HEAD#l74 | 20:20 |
lkcl | here is where i have created something which calls the "add_io" function of C4M JTAG | 20:20 |
lkcl | that creates a suite of IO Records whiiiich... | 20:21 |
lkcl | ... line 197: | 20:22 |
lkcl | https://git.libre-soc.org/?p=c4m-jtag.git;a=blob;f=c4m/nmigen/jtag/tap.py;h=1f3d424cbd7451c0434e0c71168f5aa0935af860;hb=c2bf4810f9f91ced7fcda777b92b86ab353da288#l197 | 20:22 |
lkcl | get created *on-demand* of the right type (In, Out, InOut, TristateInOut) | 20:22 |
lkcl | line 544 is the implementation of add_io | 20:22 |
lkcl | https://git.libre-soc.org/?p=c4m-jtag.git;a=blob;f=c4m/nmigen/jtag/tap.py;h=1f3d424cbd7451c0434e0c71168f5aa0935af860;hb=c2bf4810f9f91ced7fcda777b92b86ab353da288#l544 | 20:22 |
lkcl | so, whilst that gets created in that function, and it doesn't really look as if anything is done with it, actually, if you look in elaborate_ios, actually it is | 20:23 |
lkcl | the IOConn Records get connected up to the Shift Register (so that you don't have to). | 20:23 |
lkcl | therefore.... | 20:24 |
lkcl | back iiiin.... | 20:24 |
lkcl | https://git.libre-soc.org/?p=soc.git;a=blob;f=src/soc/debug/jtag.py;h=4b4f17a97d672c3f22b668008a1c058ac2500da6;hb=HEAD#l74 | 20:24 |
lkcl | when a "pinset" dictionary was created, those *automatically* get connected to the Shift Register (and the Mux) | 20:24 |
lkcl | so that *you* do not have to connect up a Mux | 20:25 |
lkcl | all you have to do is: | 20:25 |
lkcl | m.d.comb += self.ios[0].i.eq(somethingsomethingfromaperipheral) | 20:25 |
lkcl | m.d.comb += actualoutputtocorona.eq(self.ios[0].pad_side.i) | 20:26 |
lkcl | it's probably easiest / best to do this as a 3-stage process | 20:27 |
lkcl | 1) create a dummy ASICPlatform class - hardcoded Resources. | 20:27 |
lkcl | 2) convert ASICPlatform to non-hard-coded Resources | 20:27 |
lkcl | 3) add JTAG Boundary Scan | 20:28 |
lkcl | where (3) involves creating a *duplicate* set of Resources. | 20:28 |
lkcl | where - exactly as in the image you created, the one set of Resources is on the left (actual IO pads) | 20:28 |
lkcl | and the other set of Resources - with identical names and identical functions - is on the right | 20:29 |
lkcl | 1 sec | 20:29 |
lkcl | https://libre-soc.org/shakti/m_class/JTAG/jtag-block.jpg | 20:31 |
lkcl | if you write that as a really, *really* simple program, starting at phase (1) with something that matches | 20:32 |
lkcl | dummy_pinset() | 20:33 |
lkcl | line 26 | 20:33 |
lkcl | https://git.libre-soc.org/?p=soc.git;a=blob;f=src/soc/debug/jtag.py;h=4b4f17a97d672c3f22b668008a1c058ac2500da6;hb=HEAD#l26 | 20:33 |
lkcl | it should be pretty straightforward | 20:33 |
lkcl | hey, for uart, you could even use this: | 20:35 |
lkcl | https://github.com/nmigen/nmigen-boards/blob/bd7fdd379d8b28f8b542f251a11ca28297e8fd6f/nmigen_boards/resources/interface.py#L10 | 20:35 |
lkcl | I2CResource further down as well.... | 20:37 |
octavius | Sorry, I'm distracted atm, I'll come back in half hour and read again. I think I understand the problem, but it's a lot (and seems redundant, at least until I understand it) | 20:53 |
lkcl | ack | 22:00 |
lkcl | for when you're back: it isn't redundant, because without JTAG Boundary Scan, you end up with the situation in every single one of the google skywater 130nm OpenMPW tape-outs | 22:01 |
lkcl | the "Management" core failed | 22:01 |
lkcl | and because there was no JTAG boundary scan, absolutely nobody could properly identify if their ASIC peripheral functions were faulty | 22:02 |
lkcl | or whether the IO pads were faulty | 22:02 |
lkcl | because the "Management" Core could not flip the GPIO muxer | 22:03 |
lkcl | no JTAG boundary scan, no way to test IO pads independently of peripherals | 22:03 |
lkcl | you're probably referring to "the JTAG Resource() list" has to be identical to "the IOPad Corona Resource() list" | 22:04 |
lkcl | that absolutely *has* to be an identical list | 22:04 |
lkcl | if if isn't an identical list, how the hell can you connect the thing on the left to the thing on the right? | 22:05 |
lkcl | https://libre-soc.org/shakti/m_class/JTAG/jtag-block.jpg | 22:05 |
lkcl | i just realised, the diagram's slightly inaccurate. let me redraw it | 22:06 |
octavius | Just re-read your comments. So the topology is: | 22:10 |
octavius | Resource Manager (SoC periphs) <-> JTAG <-> Resource Manager (ASIC corona) | 22:10 |
octavius | I'll need to create an ASIC Platform class that attaches to JTAG (within the get_* methods) by: | 22:11 |
octavius | jtag_in = self.jtag.get_core_side(pi, port, attrs, invert) | 22:11 |
octavius | jtag_out = self.jtag.get_core_side(pi, port, attrs, invert) | 22:11 |
octavius | Does there need to be a new directory "ngi_router" in "libresoc-litex" repo? There would then be a ngi_router.py file with the new class | 22:15 |
lkcl | yes... but not in stage (1) or (2) | 22:20 |
lkcl | that'll be stage (3) | 22:20 |
lkcl | oh hell no. | 22:20 |
lkcl | litex is *out* | 22:20 |
lkcl | this will be entirely without litex. except, potentially, having looked at how lambdasoc works, that explicitly imports litedram and liteeth. | 22:21 |
lkcl | but it imports them as stand-alone instances. and, what is very nice, does so in a way that illustrate how that can be done... from nmigen | 22:21 |
lkcl | ok i have the redrawn image... just cropping it | 22:22 |
lkcl | https://libre-soc.org/shakti/m_class/JTAG/jtag-block.jpg | 22:23 |
lkcl | so that should illustrate it correctly. | 22:24 |
lkcl | in "bypass" mode - note that one of the SR bits sets "bypass / no-bypass".... | 22:24 |
lkcl | the IOpad is connected *directly* to the peripheral. | 22:24 |
lkcl | JTAG is bypassed entirely | 22:24 |
lkcl | which is why it's called: bypass | 22:24 |
lkcl | this is "normal" operation. | 22:25 |
lkcl | when that "control" bit is set, two things happen - not one: | 22:25 |
lkcl | 1) the IOpad is connected (muxed) to "pad" SR TDI/TDO bits | 22:25 |
lkcl | 2) the *PERIPHERAL* is **LIKEWISE** connected (muxed) to "core" SR TDI/TDO bits | 22:25 |
lkcl | BOTH THESE THINGS ABSOLUTELY MUST HAPPEN | 22:26 |
lkcl | it is useless just to connect the IOpads to the SR without connecting the core to the SR | 22:26 |
lkcl | it is useless also to connect the core to the SR without also connecting the IOpads to the SR. | 22:26 |
lkcl | because | 22:26 |
octavius | Ok, I think I understand the hardware itself | 22:26 |
lkcl | how else would you test both, independently? | 22:26 |
octavius | The diagram explains it quite well | 22:27 |
lkcl | but, you do not even need to know that c4m-jtag is doing that on your behalf | 22:27 |
lkcl | but, it also explains, clearly, why there must be *two* identical resources | 22:27 |
lkcl | one named pads | 22:27 |
lkcl | one named core | 22:27 |
lkcl | by resource, i mean - very specifically - nmigen PlatformManager.resources lists | 22:28 |
lkcl | which contain entries of type nmigen Resource() | 22:28 |
lkcl | for stage (1) and (2), strictly speaking, you don't even need to create an ASICPlatform class | 22:28 |
lkcl | you should literally just be able to use a nmigen.build.plat PlatformTemplate() instance | 22:29 |
lkcl | maybe not even that - just nmigen.build.plat Platform() instance | 22:30 |
octavius | And then override PlatformTemplate's get_* methods? | 22:30 |
lkcl | does Platform() have a build() function? | 22:30 |
lkcl | no, not even that, initially | 22:30 |
lkcl | that would be stage (3) | 22:30 |
lkcl | nope build() is part of Platform() not PlatformTemplate() | 22:30 |
lkcl | so you can create an instance Platform() | 22:31 |
lkcl | then call p.build(thetoplevelobject) | 22:31 |
lkcl | for stage (1) and (2) - which do not involve JTAG - the existing get_input() get_output() and get_input_output() should work perfectly | 22:32 |
lkcl | https://git.libre-soc.org/?p=nmigen.git;a=blob;f=nmigen/build/plat.py;h=c1d8fc693c0c180d56f319433889b10125ee573e;hb=e88d283ed30448ed5fe3ba264e3e56b48f2a4982#l203 | 22:32 |
lkcl | only at *phase 3* - when actually doing the redirection (get_core_side, jtag_in/out) would the ASICPlatform need to be created, *then* the duplicate Resource() is needed. | 22:33 |
octavius | I need to go, otherwise I won't get enough sleep. I'll be on tomorrow morning around 8am onwards to continue. If you're busy I'll continue with figuring out the svg. | 22:33 |
lkcl | ok :) | 22:34 |
octavius | Sorry, this is a lot | 22:34 |
lkcl | ah goo idea | 22:34 |
lkcl | yes, sorry :) | 22:34 |
lkcl | night | 22:34 |
octavius | Hopefully with a fresh mind I'll get it | 22:34 |
octavius | You two, gn | 22:34 |
lkcl | took me 5 months to work it all out... | 22:34 |
Generated by irclog2html.py 2.17.1 by Marius Gedminas - find it at https://mg.pov.lt/irclog2html/!