lkcl | cesar, sorted https://git.libre-soc.org/?p=soc.git;a=commitdiff;h=a320531e88165ae7f5074d583854c5907b6f4429 | 10:26 |
---|---|---|
lkcl | i'm amazed that was the only one in "general" cases | 10:27 |
cesar | Nice. | 10:28 |
lkcl | the NIA was being advanced ahead of the list of instructions. something needs to be done about that. | 10:28 |
lkcl | NIA was being set to 16 (because 12+4=16) | 10:28 |
lkcl | but then branch asked it to jump back to 4... | 10:28 |
lkcl | but of course NIA is being read before that change takes place | 10:29 |
lkcl | by saying "instruction is busy" the test_runner.py delays reading NIA until it's been set to 4... | 10:29 |
lkcl | and then of course it goes, "oh, this PC, 4, is still within the program, let's continue" | 10:29 |
cesar | Right. | 10:31 |
cesar | For my part, I'm planning how to get the FSMs in TestIssuer into shape. | 10:31 |
lkcl | branch tests work too, dang. | 10:32 |
lkcl | great. | 10:32 |
lkcl | do feel free to totally cut SVP64 entirely from a copy first, to save time | 10:33 |
lkcl | the priority is the in-order core: if TestIssuer lags somewhat, as long as it works it's fine. | 10:33 |
lkcl | y'know what? i'm just going to run the entire test suite to see if it works | 10:33 |
lkcl | FOSDEM2022 CfP new VLSI devroom is open! https://libre-soc.org/conferences/fosdem2022/#cfp | 11:03 |
lkcl | woo! dang! a pass! | 12:16 |
sadoon_albader[m | awesome | 13:45 |
octavius | Hello, been awhile. How do I push a submodule? In my case I'm trying to update testing_stage1.py in pinmux submodule within the soc directory. Do I have to specify something other than "origin master"? | 13:51 |
lkcl | ok so whilst technically it's possible to do, generally you do this instead: | 14:07 |
lkcl | * check out the module separately as its own repo | 14:07 |
lkcl | * edit the separate module | 14:07 |
lkcl | * commit the separate module | 14:07 |
lkcl | * go to the repository that has the submodule | 14:07 |
octavius | Ok, so edit only using pinmux repo separately, then execute inside the greater soc repo | 14:07 |
lkcl | * do git pull | 14:08 |
lkcl | * do "git submodule update --init --recursive" | 14:08 |
lkcl | * do "git commit" *ONLY* of the submodule | 14:08 |
lkcl | yes to the 1st bit | 14:08 |
lkcl | but sort-of-not-really for the 2nd | 14:08 |
octavius | Why the "--init --recursive" flags? Doesn't the submodule repo exist already? | 14:08 |
lkcl | the reason is because: having copied code *into* pinmux, the code you are working on requires no modifications to soc | 14:09 |
lkcl | (or, shouldn't) | 14:09 |
lkcl | don't know, don't care, it's one of those "voodoo magic incantations" :) | 14:09 |
octavius | Ok, will do that then | 14:10 |
lkcl | lots of things in computing are like that | 14:10 |
lkcl | understanding is... deferred, shall we say | 14:10 |
octavius | Yep, I got that much X'D | 14:10 |
lkcl | which is an attitude that saves a... vast amount of "but whyyyyyyy" as well as massive distraction :) | 14:10 |
lkcl | what i recommend is: do a unit test that has *absolutely nothing to do with boundary scan at all* | 14:11 |
lkcl | change Blinker (particularly count) so that it is "easy to test in a deterministic way". | 14:11 |
lkcl | shove some input on uart tx, oh look it comes out on uart rx. | 14:12 |
octavius | Ok, I think the jtag_sim is running, but I'm getting KeyError because the test is trying to access non-existing signals. I was thinking of changing those to what's shown on the yosys diagram | 14:12 |
lkcl | shove some stuff on GPIO1, oh look it changes ... say... GPIo2 one clock later | 14:12 |
lkcl | forget that for now | 14:12 |
lkcl | there are about four unknowns here | 14:13 |
octavius | Ok, forget all the existing stuff, do a simple test, got it | 14:13 |
lkcl | ... yes. | 14:13 |
lkcl | then when that simple test is working, you can go, "hmm if i change the boundary scan, It Doesn't Work (tm)" | 14:13 |
lkcl | where you can then go, "But I Had The Simple Test Working Therefore Logically I Can Deduce That The Error Must Be in Boundary Scan" | 14:14 |
lkcl | but if you don't have the simple test working first, you have *no idea* if it was the simple test or the BS. | 14:14 |
octavius | exactly | 14:14 |
octavius | sure | 14:14 |
octavius | which means I can get rid of all the extra modules like SRAM? | 14:15 |
lkcl | feel free to alter Blinker to do whatever-it-is-you-need | 14:15 |
lkcl | yes | 14:15 |
octavius | good | 14:15 |
octavius | thanks | 14:15 |
lkcl | and you'll see that i added an option to JTAG to set the wb width to None. | 14:15 |
octavius | Ok. I'm guessing that normal JTAG module always expects to operate with WB memory attached? | 14:16 |
lkcl | when you get to it i recommend using the non-networked version of jtag client/server | 14:16 |
lkcl | no it doesn't | 14:16 |
lkcl | but, focus on the simple test first | 14:17 |
lkcl | i suggest disconnecting the GPIO from count, but at least using sync on the GPIO inter-connections | 14:17 |
lkcl | up to you, but basically, you want to be able to do: | 14:18 |
lkcl | "if i set these inputs, i know from the way that the code is bleedin obvious, that the outputs should beeee... X" | 14:18 |
lkcl | and always X | 14:18 |
lkcl | by having "count" in the mix, that's not true | 14:18 |
lkcl | because "count" is internal | 14:18 |
octavius | Makes sense | 14:19 |
octavius | For the simple test, can I git rid of everything between lines 335 and 367? https://git.libre-soc.org/?p=pinmux.git;a=blob;f=src/spec/testing_stage1.py;h=a2f1c5c5959d321999ae1bbdf861d414dd5c01a1;hb=a61fe0517a767c5c0985ef8b7d8482c2a1e12a44 | 14:22 |
octavius | Or does the ASICPlatform() object and build() have to stay? | 14:23 |
lkcl | set it to "if False:" | 15:02 |
lkcl | which is a good prototyping way of having "useful stuff" around that you don't have to waste time putting back in | 15:03 |
octavius | Ok | 15:14 |
octavius | And what about the generator function TypeError I have, did you see that? https://bugs.libre-soc.org/show_bug.cgi?id=50#c52 | 15:15 |
lkcl | sim.add_sync_process(wrap(jtag_srv(top))) #? jtag server | 15:22 |
lkcl | put those back, you'll need them later. | 15:22 |
lkcl | try to get out of the habit of deleting code for the sake of it, when all you are doing is: | 15:22 |
lkcl | a) removing use-case examples that show you what you need to copy | 15:22 |
lkcl | 2) making more work for yourself when you know it has to be put back in later | 15:23 |
lkcl | if you had left the code in, you would have noticed the difference between: | 15:23 |
lkcl | sim.add_sync_process(wrap(jtag_srv(top))) #? jtag server | 15:23 |
lkcl | and | 15:23 |
lkcl | sim.add_sync_process(test_case0()) | 15:23 |
octavius | So the wrap() function is important? | 15:23 |
lkcl | that is a question that is easily answered by trying it and seeing what happens | 15:24 |
octavius | From the error, I guess wrap makes it a generator function | 15:24 |
lkcl | the less you change "because it may or may not look obvious", the less there is to go "wrong" | 15:24 |
lkcl | you do not have to do quotes everything yourself quotes | 15:25 |
lkcl | that way lies a world of pain | 15:25 |
lkcl | start from an *existing known good unit test* that "works" | 15:25 |
lkcl | use it verbatim | 15:25 |
lkcl | and only then remove one thing from it | 15:25 |
lkcl | you did two things. | 15:25 |
octavius | But I thought you wanted me to make a basic unit test from scratch? | 15:25 |
lkcl | yes but not by forcing yourself to write *from* scratch | 15:26 |
lkcl | without leveraging some other known-good, known-working, existing code | 15:26 |
lkcl | always always always work from something that has been written by someone else and is known to work | 15:26 |
octavius | So should I use jtag_srv? | 15:26 |
lkcl | whatever, just find something that works and use it | 15:27 |
lkcl | one of cesar's multicompunit tests | 15:27 |
lkcl | there are hundreds of unit tests to work from as a base and copy: you absolutely do not need to abandon all that work and force yourself to completely ignore it and try to "make your life harder for some unknown reason" | 15:28 |
lkcl | make the stepping stones as small as possible | 15:28 |
lkcl | and increment as fast as possible | 15:28 |
lkcl | that way you will make inexplicably rapid progress | 15:29 |
lkcl | unlike me who has just realised i screwed up | 15:30 |
lkcl | but at least have realised that, sigh | 15:30 |
octavius | where can I find cesar's multicompunit tests? soc repo? | 15:31 |
octavius | src/soc/fu/compunits/formal/proof_fu.py | 15:31 |
lkcl | 1 sec | 15:32 |
lkcl | https://git.libre-soc.org/?p=soc.git;a=blob;f=src/soc/experiment/test/test_compalu_multi.py;h=4c2e1347adc29a4d2b05d018746bf6fff1a458a0;hb=565fed200dde2fbd0c8584c0a439d1a51d861c01 | 15:32 |
lkcl | ooo just found a nasty bug | 15:50 |
lkcl | i tried switching off regport number reduction | 15:51 |
lkcl | (the FSM TestIssuer ran with a single read port and a single write port on the Integer regfile) | 15:51 |
lkcl | so that we did not have absolutely massive regfile port proliferation | 15:51 |
lkcl | i just tested out the 4R2W scenario (instead of 1R1W) | 15:52 |
lkcl | failed. no obvious reason | 15:52 |
lkcl | then i realised that the for-loops constructing the write-hazard bitvector protections were not *themselves* using "regfile ports" any more | 15:53 |
lkcl | but instead are using an SRLatch (which only has one set and one clear port) | 15:53 |
lkcl | INT.o protection and INT.o2 (second write port) use the *exact same SRLatch set/get* to indicate an outstanding write is expected | 15:54 |
lkcl | which meant that in the construction of the code, the INT.o tried to update the SRLatch set/get | 15:54 |
lkcl | and then INT.o2 *overwrote* that | 15:54 |
lkcl | destroying the write-hazard protection for INT.o in the process | 15:55 |
lkcl | this is extremely lucky to have found that in such an obvious way | 15:55 |
lkcl | rather than something horribly obscure such as XER (which has 3 write ports) and is not very common | 15:55 |
lkcl | anyway: fixed it by merging the set/clr requests at a higher level | 15:56 |
lkcl | octavius: you're currently trying to get access to local variables, expecting them to magically exist inside the Blinker() instance | 17:14 |
lkcl | without actually ever adding them to Blinker() to make them accessible | 17:14 |
lkcl | local variables inside a function are local for very good reason | 17:15 |
lkcl | plus, you are expecting that nmigen Signal() names should also magically be made available publicly inside the instance | 17:15 |
lkcl | i'll put some comments in for you | 17:15 |
octavius | Ah, so Blinker doesn't have any ports, and thus the test can't drive anything? | 17:16 |
lkcl | basically correct. | 17:19 |
lkcl | you cannot magically expect things to appear that you - or some other function - has not *explicitly* added | 17:19 |
lkcl | python does not work that way | 17:19 |
lkcl | do a "git pull" you will see the technique i used to find out what is going on | 17:20 |
lkcl | i ran the test *five times*, each time adding more exploratory "print" statements | 17:20 |
lkcl | if you had asked me, i would not have been able to tell you what was in the object | 17:20 |
lkcl | but the "print dir(top)" statement showed me, "oh look, it doesn't have a gpio member" | 17:21 |
lkcl | therefore, first, i added one | 17:21 |
lkcl | then, next, i had absolutely no idea what was *in* that gpio object. | 17:21 |
lkcl | but the "print dir(top.gpio)" statement showed me | 17:21 |
lkcl | etc etc. | 17:21 |
lkcl | repeat repeat repeat repeat | 17:21 |
lkcl | explore explore explore explore | 17:21 |
lkcl | do that rapidly and unhesitatingly | 17:22 |
lkcl | quickly drill down to what you want to find | 17:22 |
lkcl | if there was a nicey lovey all-over-it-with-a-mousey clickey GUI explorer around | 17:23 |
lkcl | you could have used that to see the entire tree-view of the Blinker() instance | 17:23 |
lkcl | but it would still not have helped you initially because you hadn't actually added the gpio resource *to* the Blinker instance | 17:24 |
lkcl | therefore gpio was not part of the public API of Blinker() | 17:24 |
lkcl | you get the idea | 17:24 |
lkcl | octavius, what nmigen does inside Simulation() is nothing that you are "permitted" direct access to | 17:28 |
lkcl | the function named elaborate() is called *by* Simulation() | 17:29 |
lkcl | you have not called it yourself, therefore you are *not* getting direct access to the Module (m) returned *by* the Blinker.elaborate() function | 17:29 |
lkcl | that module contains all the nmigen AST.. *and you do not have access to it* | 17:30 |
lkcl | you can see the results of its operation (through gtkwave) | 17:30 |
lkcl | but you cannot manipulate it directly or even get at it | 17:30 |
lkcl | instead, we have to deploy a trick | 17:30 |
lkcl | inside Blinker.elaborate(), where the GPIO resource is obtained, | 17:31 |
lkcl | make that gpio Record a *member of Blinker*. | 17:31 |
lkcl | then, once Simulation() has called the Blinker instance's elaborate() function | 17:31 |
lkcl | oh look! | 17:31 |
lkcl | a gpio instance magically appears! | 17:31 |
*** mepy_ is now known as mepy | 21:57 |
Generated by irclog2html.py 2.17.1 by Marius Gedminas - find it at https://mg.pov.lt/irclog2html/!