Thursday, 2020-05-28

*** tpb has joined #yosys00:00
*** rjo has quit IRC00:28
*** rjo has joined #yosys00:36
*** simeonm has quit IRC00:56
*** futarisIRCcloud has quit IRC01:31
*** N2TOH has joined #yosys01:35
*** lambda has quit IRC01:46
*** lambda has joined #yosys02:04
*** simeonm has joined #yosys02:05
*** citypw has joined #yosys02:18
*** lambda has quit IRC02:21
*** Degi has quit IRC02:59
*** Degi has joined #yosys03:00
*** lambda has joined #yosys03:03
*** Cerpin has quit IRC03:14
*** Cerpin has joined #yosys03:16
*** BinaryLust has quit IRC05:07
*** BinaryLust has joined #yosys06:18
*** emeb_mac has quit IRC06:31
*** futarisIRCcloud has joined #yosys07:06
*** dys has joined #yosys07:15
*** jakobwenzel has joined #yosys07:29
*** Asu has joined #yosys08:46
*** BinaryLust has quit IRC09:59
*** rswarbrick has joined #yosys10:08
*** jfcaron has joined #yosys10:30
rswarbrickI'm still hacking away at adding bind support, and have got to the stage where I'm trying to insert cells in the hierarchy pass. Is the hierarchy command supposed to be idempotent?10:37
rswarbrickIf so, I need to track "I inserted a top-level bind here"10:38
ZirconiumXYes, hierarchy should do nothing if there's nothing to do10:39
*** vidbina has joined #yosys10:39
rswarbrickThe point is that I might have a top-level bind statement that applies to all modules of type FOO. If I run hierarchy, then load foo.sv, then run hierarchy again, I'd like to get the cell bound in properly. But if I load foo.sv then run hierarchy twice, do I need to make sure I don't get 2 cells? (I think yes, but wanted to check)10:40
daveshahYes, ideally the bind would be removed by hierarchy10:42
daveshahBut that depends on how the bind is represented10:43
rswarbrickWell, it's a new module-like thing. A module can contain one, and so can the design (to allow bind directives at top-level).10:43
rswarbrick(module-like for technical reasons to do with where we instantiate cells in genrtlil)10:44
rswarbrickDo we support things like "load x.sv; hierarchy; load a.sv; hierarchy" ? If so, I think I have to ensure idempotence by setting a flag where the bind occurs, rather than on the bind object itself, no?10:45
rswarbrick(because a top-level bind might have an effect on modules in x.sv and also on modules in a.sv)10:46
daveshahOh, I don't really know the bind semantics well enough here10:50
rswarbrickWell, one thing you can do is "bind foo bar bar_i(.*)", which means "put a bar called bar_i into every module of type foo". I guess we could delete a bind directive like this after applying it (since we now have the definition of foo), but I'm not sure that's right if you can do stuff like deleting modules and reloading them.10:52
daveshahYeah, it might get complicated if you derive a new parameterisation of foo, too10:53
daveshahthen I think the attribute approach is indeed best10:53
rswarbrickCool, makes sense.10:53
rswarbrickBecause "naming things is hard", do we have a name for a non-abstract module? That is, one that's either derived already or one that had no parameters? "concrete"?11:02
whitequarkconcrete seems reasonable11:10
rswarbrickThanks!11:10
rswarbrickAlso, is there a neat way to find all modules with a given original name? Looking at derive_common in ast.cc, it looks like a module called FOO might come out as $paramodFOOx=1 or $paramod$1234abcdFOO. Searching the strings seems a bit icky. Is there a better way?11:10
rswarbrick(I'm asking because I can't guarantee that I see a bind directive before I specialise the module)11:10
rswarbrickOhh. I've just seen the hdlname attribute. I guess I can work from there.11:12
Sarayanisn't it hdlname that's going to slightly change for the better?11:13
whitequarkhm?11:17
whitequarkhdlname on modules won't change11:17
Sarayandots to spaces11:17
whitequarknope, currently there is no hdlname with dots11:17
whitequarkit's just the wire name11:17
Sarayanok cool then :-)11:17
*** vidbina has quit IRC11:43
*** vidbina has joined #yosys12:08
*** vidbina has quit IRC14:12
*** X-Scale` has joined #yosys14:53
*** X-Scale has quit IRC14:54
*** X-Scale` is now known as X-Scale14:54
*** X-Scale has quit IRC14:56
*** dys has quit IRC15:02
*** emeb has joined #yosys15:35
*** Cerpin has quit IRC15:35
ZirconiumXdaveshah, mwk: https://github.com/YosysHQ/yosys/pull/2096 <-- thoughts?15:57
tpbTitle: [RFC] Add conditional-insert operator to pool/dict by ZirconiumX · Pull Request #2096 · YosysHQ/yosys · GitHub (at github.com)15:57
*** jfcaron has quit IRC16:03
mwkI'm not convinced it improves readability16:08
whitequarkneither am I16:13
whitequarkI'm not strongly opposed but I don't see the benefit16:13
ZirconiumXMmm16:23
rswarbrickZirconiumX: Could you use something like std::copy_if for this?16:34
ZirconiumXI don't think so16:37
ZirconiumXYou'd have to make two passes over the data16:37
rswarbrickYou'd need something like std::back_inserter too.16:37
rswarbrickSo std::copy_if(pool.begin(), pool.end(), dest_pool.inserter(), my_predicate);16:38
ZirconiumXI feel like ranges are really important for readability16:39
ZirconiumXpool.begin()/pool.end() is a bit messy16:40
rswarbrickIn which case, I don't understand your PR: isn't it basically the same syntax?16:40
ZirconiumXI feel like range-style insert_if *is* an improvement though16:40
*** citypw has quit IRC17:17
*** vidbina has joined #yosys17:37
*** Cerpin has joined #yosys18:08
*** jakobwenzel has quit IRC18:10
*** rlee287 has joined #yosys18:47
*** jakobwenzel has joined #yosys19:41
*** BinaryLust has joined #yosys19:49
*** dys has joined #yosys19:51
*** vidbina has quit IRC20:03
*** jfcaron_ has joined #yosys20:17
*** emeb_mac has joined #yosys20:30
*** jakobwenzel has quit IRC20:33
rlee287In the Verilog backend, the code generation for the $_DFF_ cells determines a boolean "out_is_reg_wire" that seems to check if reg_name already exists and declares a new reg if it does not20:37
rlee287Is this understanding correct?20:37
*** rswarbrick has quit IRC20:57
*** rlee287 has quit IRC21:14
*** jfcaron_ has quit IRC21:43
*** Asu has quit IRC21:49
*** captain_morgan has quit IRC21:56
*** captain_morgan has joined #yosys21:57
*** emeb has quit IRC22:59
*** alcorn has joined #yosys23:19
alcornI'm seeing something weird with a Symbiyosys spec. I have a property that I can `cover` but can't `assume` https://pastebin.com/kX36Nbvi .Can someone help me understand if I'm missing some crucial concept? Or perhaps this is a bug?23:27
tpbTitle: [SystemVerilog] Cover passes but assume fails - Pastebin.com (at pastebin.com)23:27
ZirconiumXZipCPU: ^23:34
ZipCPUalcorn: You can't assume it because it's false on the first clock tick23:35
ZipCPUZirconiumX: Thanks for the flag23:35
ZirconiumXnp23:35
ZipCPUAssuming something for which there's no way to make it true leads to what's known as a "WARMUP FAILURE"23:35
ZipCPUThis is one of the reasons why I have a rule regarding assumptions: Only assume design *inputs*.  Everything else, internal state and design outputs, should be constrained via assertions and your design logic.23:36
ZipCPUCover succeeds because there's a way to make the statement true ... eventually, even though it's not true on the first clock tick23:38
alcornok thanks, I haven't quite yet wrapped my head around what assume/assert really do. What's the best way to tell the solver "I only care about situations where f_past_valid is true"? If I just assert(f_past_valid), can't the solver just issue a reset to find a counter example?23:38
ZipCPUI'm not normally asserting f_past_valid.  That's constrained enough by logic, and I can verify it by cover(f_past_valid) if I want.23:39
ZipCPUassume limits the size of the search space the solver works with.23:39
ZipCPUSee ... https://zipcpu.com/quiz/2019/08/03/quiz01.html for more information23:40
tpbTitle: Quiz #1: Will the assertion below ever fail? (at zipcpu.com)23:40
ZipCPUIn that design, you have a counter that is assumed to be less than 90, and an assertion that it will remain less than 10023:40
ZipCPUThe logic of the counter, however, will have it just counting up to 65535 and then rolling over23:40
ZipCPUSo, will it ever reach 100?  The answer is, No, because the assumption tells the solver not to ever consider cases where the assumption might be false.23:41
* ZipCPU needs to run for supper23:41
ZipCPUConsider checking out my first experiences here: https://zipcpu.com/blog/2017/10/19/formal-intro.html  The descriptions of what assumptions and assertions are should be about right.23:42
tpbTitle: My first experience with Formal Methods (at zipcpu.com)23:42
alcornthanks for the tips! I think I now understand that you can only assume things that can be true on the first cycle. I had thought that it was possible to assume anything as long as it's reachable at some point... and that the solver would just figure out how to set up a sequence of input cycles that validate the assumption23:42
ZipCPUalcorn, that's not quite true.  You can do an: always @(*) if (f_past_valid) assume(something_true_only_after_the_first_clock);23:43
alcornI have actually read a few of your blog posts before and they have been very illuminating, so thank you!23:43
ZipCPUNp23:44
alcornok so you just have to guard your assumes with some other logic23:44
alcorna naked assume has to be satisfiable on the first cycle23:44
alcorn?23:44
ZipCPUYou may.  It depends on what you want to do.23:44
ZipCPUA naked assume needs to be satisfied on *EVERY* cycle23:44
alcornOk I see23:45
ZipCPUalways @(*) assume(!S_AXI_ARVALID); // will keep a slave component from ever receiving an AXI read request23:45
alcornThis has helped. The solver is a bit less magical than I thought but perhaps less magic is good when you're trying to prove things correct23:46
ZipCPUAbsolutely!23:46
ZipCPUThe solver has to be ... very exacting.  It must follow very strict rules, set forth by you.  That's sort of the point.23:47
alcornRight23:47
ZipCPUIt's quite the stickler for details.23:47
alcornReally I was just confusing the semantics of cover and assume23:47
ZipCPUcover(X) -> find one way, any way, to make X true23:47
ZipCPUassume(X) -> don't consider any circumstances where !X23:48
ZipCPUassert(X) -> a challenge to the solver.  I don't think X will ever happen.  Go ahead, prove me wrong, I dare you.23:48
alcornHow would you go about assuming that f_past_valid has been true for several cycles?23:49
alcornI've been using this construction `assume(f_past_valid && $past(f_past_valid, 1) && $past(f_past_valid, 2) && ...)`23:49
ZipCPUinitial f_past_valid_counter = 0; always @(*) if (f_past_valid && f_past_valid_counter < 200) f_past_valid_counter <= f_past_valid_counter + 1;23:50
alcornbut this discussion has me questioning if it is right23:50
ZipCPUif (f_past_valid_counter > 10) assume(XYZ);23:50
ZipCPUNo, that's not how you'd do it.  Use f_past_valid in a condition, sort of like:23:50
ZipCPUif (f_past_valid && $past(f_past_valid) && $past(f_past_valid, 2)) assert(XYZ);23:51
ZipCPURemember: Don't *assume* anything but inputs.23:51
alcornOk this is sinking in23:51
ZipCPUYou shouldn't be making assumptions about f_past_valid at all23:51
alcornRighto23:51
alcornOk I need to go back and rewrite a bunch of specs now that I understand assume a little better!23:52
alcornThanks again23:52
ZipCPUGlad I could help!23:52
* ZipCPU steps away for supper23:53

Generated by irclog2html.py 2.17.2 by Marius Gedminas - find it at https://mg.pov.lt/irclog2html/!