Skip to content

added $random, $urandom_range and better $value$plusargs #780

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 17 commits into
base: main
Choose a base branch
from

Conversation

postoroniy
Copy link

@postoroniy postoroniy commented Apr 14, 2025

Added

  1. $random (no need to link anything for Bluesim)
  2. $urandom_range( max_val,min_val)
  3. better support of $value$plusargs than in Feature/value plusargs #778
    usage of $value$plusargs
//size of seed is handled automatically 
//and can be from 1 bit upto  64 bits and more
//but than 64 bits is caped by strtoll and strtod functions in C, file dollar_plusargs.cxx
//effectively it means the functions returns max 64 bit values only 
Reg#(Bit#(62)) seed <- mkReg(2011111);
//if seed2 is gven more then 2 bits wide( e.g.32)  it will be masked by its max value which is 3
//and for  value of 32 seed2 will be 0;
Reg#(Bit#(2)) seed2 <- mkReg(3);
...
  rule bla;
        let bseed <- $value$plusargs("seed=%d",seed);
        if (bseed)
            $display("Seed = %0d", seed);
        else
            $display("Seed is not given");
        let bseed2 <- $value$plusargs("seed2=%d",seed2);
        if (bseed2)
            $display("Seed2 = %0d", seed2);
        else
            $display("Seed2 is not given");
        let ra <- $urandom_range(111,Just(100));//to limit min value by 100 need to pass param as shown
        $display("Random range= %0d", ra);
        let rb <- $urandom_range(101,Nothing);//default min is 0 here.
        $display("Random range= %0d", rb);

        let r <- $random();//simple $random call, returns 32 bit value
        $display("Random = %0d", r);
  endrule

@postoroniy postoroniy changed the title added $random and better $value$plusargs added $random, $urandom_range and better $value$plusargs Apr 14, 2025
Copy link
Collaborator

@quark17 quark17 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for contributing! It would be great add support for $value$plusargs! Note that Issue #302 is open for this, and includes some discussion of some of the design decisions and how it might be implemented.

I would suggest separating this into at least two PRs, one for the random tasks and one for plusargs, so that one doesn't hold the other up from being accepted.

I did not remember the support for $random, so I had to look up the status. It appears that $random is supported in the Verilog generation, but there are no tests in the testsuite and it is not mentioned in the language guides or the library guide. (That's unfortunate, because we should have tests and it should be documented.) The one documentation mention is in the user guide, which says that Bluesim and Verilog will give different results -- but actually Bluesim doesn't support $random! Bluesim nearly supports it, but is just missing a definition of dollar_random in its codebase.

So one thing you've done is to add dollar_random, which is great! However, it should not be added to the unrelated file dollar_time.cxx. Instead, a new file dollar_random.cxx should be created, in which any random-related tasks can be placed.

A question I have, though, is whether the Bluesim and Verilog implementations need to match. The Verilog spec provides C++ code as a reference definition for uniform random number generation. I assume that we would want to use that code, so that Bluesim matches. However, I have not checked whether various Verilog simulators give the same sequences. I note that Icarus Verilog and Verilator give a different number for $random() called without a seed -- I have not yet tried with a seed, because my version of Verilator is rejecting it. I would also not be surprised if Verilator chose to ignore this part of the spec and just provide an arbitrary RNG, like calling random() as you've done. It might be worth trying some of the commercial simulatirs (I'll see if I can).

Also, I'm unclear on how Bluesim would support a seed. In fact, BSC currently does nothing to guarantee that the seed argument is a state element or a Verilog variable, that can retain the RNG state after each call. It just so happens that if you pass a register, the generated Verilog will have a register there and it will work. If you call $random(17), though, you'll get illegal Verilog, that has a constant instead of a variable (both Icarus Verilog and Verlator will error). And I bet that you would get an error if the register module isn't inlined as an actual reg in the code. (So BSC could be doing more to check the argument and generate proper code, even for Verilog. And it'd help if we had tests for these situations.)

For $value$plusargs, you have to do something similar, because the function has a return value and it also needs to assign a value to one of its arguments. You've implemented this for Bluesim by changing some functions in ForeignFunctions.hs.
I wonder, though, if BSC still needs to check that the argument is just a variable. What happens, say, if the design passes an expression as an argument -- does BSC reject that? This would be an error in the Verilog backend (which is expecting a signal name). But in Bluesim, could it end up creating pointers to odd locations? (Again, it would help to have some testcases for error situations, not just valid situations.)

I also think that BSC should be sanity checking the pattern argument, to check that it's well-formed and is one of the patterns that is supported. As mentioned on Issue #302, that may not be possible in TCheck, and the check would need to be done after elaboration (but before the Verilog and Bluesim backends diverge).

It's really cool that you have something working, though! And limited support is better than no support. So I'm definitely OK with accepting a PR that has limits. But I mention in case you're able to address any of these concerns.

Sorry if that was a lot! I do appreciate the contribution and hope that we can get it merged!

@@ -3269,6 +3270,14 @@ foreign $fdisplayh :: PrimAction = "$fdisplayh"

foreign $random :: ActionValue_ 32 = "$random"

$urandom_range :: Bit 32 -> Maybe (Bit 32) -> ActionValue (Bit 32)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The support for variable arguments of system tasks is handled in TCheck. The declared types of the foreign primitives here are ignored and replaced with special checking. For example, $random can take zero or one argument, despite the declaration (a few lines above this) not mentioning an argument. In TCheck, the function taskCheckRandom is called to perform the checking and it looks for zero or one arguments. These taskCheck* functions not only check the types but also perform any necessary transformations to create the actual implementations.

I suggest implementing $urandom_range in the same way: Declare it here as simply ActionValue_ 32 and then add something like taskCheckURandomRange in TCheck.

Note that $random is signed and the typechecking expects Int#(32) (both for the return type and for the seed). If we're adding $urandom_range, it might be worth adding $urandom (which supports UInt#(32) or possibly also Bit#(32)).


tUInt64 value = 0;
switch (*(percent + 1)) {
case 'd':
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These don't match the Verilog/SystemVerilog spec. For example, from IEEE 1800-2017 (which I had on-hand), the patterns are:

%d      decimal conversion
%o      octal conversion
%h, %x  hexadecimal conversion
%b      binary conversion
%e      real exponential conversion
%f      real decimal conversion
%g      real decimal or exponential conversion
%s      string (no conversion)

and that both lowercase and uppercase are accepted, and leading 0 forms are valid.

It's OK to not accept %s, %o, or %b for now. And it's probably OK to allow %e, %f, and %g to accept all formats (exponentiatial or not). And probably OK not to support leading 0. And probably OK if there are other corner cases that are not right (for example, does strtod allow 0x to appear in the string?).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will change cxx to support all

@@ -11,3 +11,16 @@ tUInt32 dollar_stime(tSimStateHdl simHdl)
{
return (tUInt32) bk_now(simHdl);
}

tUInt32 dollar_random(tSimStateHdl simHdl)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned, these should go in a new file dollar_random.cxx.

Also, they do not use tSimStateHdl and should have the argument removed. There's code in ForeignFunctions.hs that lists whether function needs this argument, and you'll also need to remove these functions from that list.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

made for testing, will split PR possibly for 3 in total

std::memcpy(&value, &d, sizeof(double));
break;
}
default:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the format string isn't recognized, it might help to issue a warning. (But BSC should have reported something before generating code, before getting to this point.)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

during sim by bluesim the $value$plusargs would return False. same as in verilog sims

@@ -364,7 +364,8 @@ fnNeedsSimHdl name = any (`isPrefixOf` name ) tasks

, "$stop", "$finish"

, "$test$plusargs"
, "$test$plusargs", "$value$plusargs"
, "$random", "$urandom_range"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what tells BSC to provide the tSimStateHdl argument. The random-tasks don't need it, so don't add them to this list.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added for future use to keep rand seed which possible depends on sim(?)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

anyway, will remove that

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I see, you're correct. If $random is called without a seed, the simulator needs to keep the seed state.

@@ -0,0 +1 @@
$value$plusargs is not given
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make sure all the files have final newlines. GitHub's web interface shows that these expected files a missing the trailing newline.

conv :: Int -> AExpr -> Argument
conv i e
| is_valueplusargs && i == 1 = Ptr e
| is_str e = Ptr e
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps this should be:

conv i e
      | is_valueplusargs && i == 1 = Ptr e
      | otherwise = convAExprToArgument e

You've inlined convAExprToArgument, which means now there's a copy that needs to be kept in sync, but also it looks like you may have accidentally deleted the arm for is_real?

Copy link
Author

@postoroniy postoroniy Apr 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as per
| otherwise = Arg e would care about is_real, no?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that I misspoke about about duplication. The function convAExprToArgument was only being called from this one place.

And you are correct that removing the is_real branch does not affect the functionality. However, sometimes it is helpful to keep such case arms, to make the code more self-documenting and/or less prone to errors when someone makes changes later. However, in this case, it may not be necessary. I am OK with removing the case arm (however, I am also OK with leaving it).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will update as suggested - keep some branch

Copy link
Collaborator

@quark17 quark17 Apr 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, changing the name convAExprToArgument to just conv loses some clarity of the purpose of the function. I would suggest making it at least convArg.

sim = if add_sim then [SimHdl] else []
this = if add_this then [Module] else []
argstr = if (null args) then [] else [ArgStr]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer if we didn't make unnecessary changes to the code, like removing the parentheses in these two lines. When using git-blame to find the original source of some code, this introduces extra hops. Also, I think some people find the redundant parens to be more readable.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry, what is better for these lines?
give some snippet

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm suggesting to keep these two lines as they were (don't remove the parentheses):

    argstr = if (null args) then [] else [ArgStr]
in sim ++ this ++ argstr ++ (maybeToList ret_arg) ++ rest

@quark17
Copy link
Collaborator

quark17 commented Apr 16, 2025

Ah, I see the following two failures in the CI:

Running ./bsc.verilog/tasks/plusargs/plusargs.exp ...
FAIL: `sysValuePlusargs.test1.c.out' differs from `sysValuePlusargs.test1.out.expected'
FAIL: `sysValuePlusargs.test3.c.out' differs from `sysValuePlusargs.test3.out.expected'

Do these work for you? In both cases, Bluesim is parsing zeros:

--- sysValuePlusargs.test1.out.expected
+++ sysValuePlusargs.test1.c.out
@@ -1 +1 @@
-$value$plusargs = 0000000000000000000000000000007b
+$value$plusargs = 00000000000000000000000000000000

--- sysValuePlusargs.test3.out.expected
+++ sysValuePlusargs.test3.c.out
@@ -1 +1 @@
-$value$plusargs = 000000000000000000000000075bcd15
+$value$plusargs = 00000000000000000000000000000000

@postoroniy
Copy link
Author

postoroniy commented Apr 16, 2025

Ah, I see the following two failures in the CI:

Running ./bsc.verilog/tasks/plusargs/plusargs.exp ...
FAIL: `sysValuePlusargs.test1.c.out' differs from `sysValuePlusargs.test1.out.expected'
FAIL: `sysValuePlusargs.test3.c.out' differs from `sysValuePlusargs.test3.out.expected'

Do these work for you? In both cases, Bluesim is parsing zeros:

--- sysValuePlusargs.test1.out.expected
+++ sysValuePlusargs.test1.c.out
@@ -1 +1 @@
-$value$plusargs = 0000000000000000000000000000007b
+$value$plusargs = 00000000000000000000000000000000

--- sysValuePlusargs.test3.out.expected
+++ sysValuePlusargs.test3.c.out
@@ -1 +1 @@
-$value$plusargs = 000000000000000000000000075bcd15
+$value$plusargs = 00000000000000000000000000000000

weird..
it passes for me, will check
update - nope. I broke it by applying mask for all bit width
anyway, last update - applying mask for 64 and less bits
need fix for WideData though

@quark17
Copy link
Collaborator

quark17 commented Apr 16, 2025

I'm starting to think that $value$plusargs needs to return Maybe t instead of taking a register as an argument. Currently, the argument has to be a register and the value gets written to the register as an action, but It would be nice to eventually be able to use $value$plusargs in value expressions, like rule conditions. And the current way it works is a fluke of code-generation and can easily break. I think the better thing to do is to make BSC aware that some system tasks can have multiple return values, which the backends can carefully implement via pointer arguments to the primitives. Unfortunately, this is a little more work. But perhaps not too difficult.

Although I'm a little unsure of what the best way is to do that. The least invasive would be similar to how ActionValue system tasks work. For those, BSC divides the function into two parts, ATaskAction that appears in the action block and ATaskValue that appears in expressions. Both are tagged with an identifier which links them. BSC then knows that the output of the ATaskAction should be placed in a signal (or variable) which can be referenced wherever ATaskValue occurs. Expressions in ASyntax are kept in a set of "defs" of the form def=expr; BSC makes sure that ATaskValue always has its own def -- that is, it only ever occurs as def=ATaskValue (and not, say, def=foo && ATaskValue). That way, the def name becomes the signal that the action side writes to.

System tasks have an action component, but for system functions (that are just value functions), there is AFCall. I'm thinking that system functions with multiple outputs can result in multiple occurances of AFCall, each tagged with an identifier that links them and indicating which argument they are. These, too can be preserved to have their own def, only ever appearing as def=AFCall. Then, when BSC does code generation, it can combine the related calls. For example, this:

d1 = ATaskValue {name="$value$plusargs", id=17, output_num=0, args=...}
d2 = ATaskValue {name="$value$plusargs", id=17, output_num=1, args=...}

would become this in Verilog:

wire d1;
wire [7:0] d2;

assign d1 = $value$plusargs(..., d2);
// and no assign statement for d2

and in Bluesim would be this:

bool d1;
uint8_t d2;

void rule_foo(...) {
  ...
  d1 = dollar_value_plusargs(..., &d2);
  ...
}

When BSC creates the sequence of statements for a rule action, it starts with a list of actions and a set of defs and BSC inserts the defs where they need to be, according to dependings (after any inputs are computed but before any statements that need its outputs). For functions with multiple outputs, BSC would need to find the linked defs and treat them as one statement in that dependency analysis. (This happens in SimMakeCBlocks.hs, as the name suggests, in tsortActionsAndDefs and tsortADefs. The first is used to construct the bodies of rules and methods; the second is used to create the sequence of statements in the scheduler, which is computing rule predicates and assigning to WILL_FIRE and CAN_FIRE signals.)

I think that is the least invasive. The alternative is to have one AFCall and one def, but then the type of that def would be a Pair (or a Maybe). That requires extending AType to include pairs or maybes, which might ripple through all the code that uses it. Further, any place that uses the def would need to extract out the elements, so ASyntax would need a new construct for getting the first or second of the Pair, or pattern matching the Maybe. And I think that's probably a more invasive change (but I could be wrong).

Anyway, I would prefer that we didn't introduce $value$plusargs with one syntax and then later change the syntax on people. If we ultimately want it to return a Maybe, then I'd prefer we implement that now, rather than support it with an argument syntax and then later change it to return a Maybe output.

The $random system task is fragile in its abuse of the argument, but there, the seed argument is both an input and output. If we add multiple outputs, we would eventually want to fix up $random to use that for its implementation, but the syntax could remain the same. I suspect that the underlying primitive would take an Int#(32) argument and return back a tuple of the new Int#(32) seed value and the random Int#(32) output. The current behavior that stores this in a register could be implemented with a wrapper that writes the new value back to the register. (Eventually we could also implement some way of declaring sim state, and not require a register.)

@quark17
Copy link
Collaborator

quark17 commented Apr 17, 2025

A slight variant would be to have one AFCall and then add a new construct AFValue for referring to any additional outputs (to be passed as pointer arguments).

@postoroniy
Copy link
Author

postoroniy commented Apr 17, 2025

what is this? looks ugly and unfamiliar to me. and impractical IMHO

wire d1;
wire [7:0] d2;

assign d1 = $value$plusargs(..., d2);
// and no assign statement for d2

in Bluesim it's already as you mentioned

...
DEF_TASK_valueplusargs___d164((tUInt8)0u),
..
void MOD_mkTop::RL_testv_rule()
{
  tUInt8 DEF_NOT_TASK_valueplusargs_64___d165;
  tUInt64 DEF_y__h32454;
  DEF_y__h32454 = INST_testv.METH_read();
  DEF_TASK_valueplusargs___d164 = dollar_value_dollar_plusargs(sim_hdl,
							       "s,64p",
							       &__str_literal_5,
							       &DEF_y__h32454);
...

the whole point to use value_plusargs is having sim (one executable file) able to run different e.g. seeds or different parameter injecting into sim env ( iverilog or vcs or xcelium or verilator)
what you propose would make generated verilog is not synthesisable. and this feature in fact killer feature :))
while using value_plusargs in initial begin ..end section is totaly fine
although, having LHS assignable was the problem and only Reg is doable.
and recently I open another can ... it's float or Real to be assigned via value_plusargs - "it does not work".

rule bla;
        let a <- $value$plusargs("testF=%f",testv);
        $display("testv F = %0x", testv);
        Bit#(64) test64 = testv;//64'h123456789abcdef0;
        Real testF = $bitstoreal(test64);
        $display("testF = %02f",testF);
endrule
Error: "mkTop.bsv", line 61, column 22: (G0013)
  Compile time expression did not evaluate:
  Type: Prelude.Real
  PrimBitsToReal (.Prelude.read ·64 testv)

anyway, idea was to use either bluesim to sim or have same args to system calls in case of using verilog sim (commercial or open does not matter) and as soon as $value$plusargs has "predefined" arguments in its call I would rather have it same as other sims around = as is now
it returns bool and has one pointer to args.

@quark17
Copy link
Collaborator

quark17 commented Apr 17, 2025

anyway, idea was to use either bluesim to sim or have same args to system calls in case of using verilog sim (commercial or open does not matter) and as soon as $value$plusargs has "predefined" arguments in its call I would rather have it same as other sims around = as is now it returns bool and has one pointer to args.

I am confused.

There are three things here: the input syntax, that then become an internal representation in BSC, and then the generated code (Bluesim or Verilog) that implements it. I am confused about which of these you are talking about.

I am not proposing any change to the generated code. Sorry if it sounded like that. Ignore my examples!

I did suggest a different input syntax, but I can be convinced to keep it unchanged (see below).

My main concern is the internals of BSC. I want BSC to know what are outputs and what are inputs, when it does transformations and optimisations on the design. Right now, BSC thinks the argument is an input! And BSC just happens to generate code that works, but that is a fluke and is fragile and we should not rely on that. This is entirely independent of what the syntax looks like and what the generated code looks like, both of which we can make be whatever we want.

I suggested that the syntax should return a Maybe type, but I can convinced to keep it as an argument. If we do that, though, the BSV parser needs to know that this system function is special; the parser needs to translate the argument into an internal representation that uses an output not an input -- so that the internals of BSC correctly know what are inputs and outputs.

what is this? looks ugly and unfamiliar to me. and impractical IMHO

wire d1;
wire [7:0] d2;

assign d1 = $value$plusargs(..., d2);
// and no assign statement for d2

I don't understand. That's an example of Verilog output from BSC and it should be identical to what your PR is generating, except maybe the wire for d2 needs to be a reg (sorry). If this is a problem, forget I mentioned it!

in Bluesim it's already as you mentioned

I know. I'm not proposing a different output. However, I'm pointing out that the the def ..._d165 is being used as an output, but BSC thought it was an input! The way BSC elaborated the design, optimised it, and eventually generated code -- all of that thought the def was an input, and treated it like an input -- it's an accident that the generated code happened to work. But it won't always work (I can created a BSV source file that will not), so I'd prefer that we don't lie to BSC, that BSC should have an accurate understanding of the design it is working on.

the whole point to use value_plusargs is having sim (one executable file) able to run different e.g. seeds or different parameter injecting into sim env ( iverilog or vcs or xcelium or verilator) what you propose would make generated verilog is not synthesisable.

Can you explain this? If my output Verilog example was wrong, then ignore it -- I was concerned about the source BSV syntax and the internals of BSC; I was not trying to say anything about what it should generate.

I also don't understand what you mean about not synthesisable. System functions aren't synthesisable anyway, only sim, are they not? In any case, I don't think I'm proposing any change to the output or to what is synthesisable. I am not suggesting that we can't use registers, if that's your concern?

while using value_plusargs in initial begin ..end section is totaly fine

I am not proposing to use initial blocks. I did not mention that at all. Did I say something that suggested that?

recently I open another can ... it's float or Real to be assigned via value_plusargs - "it does not work".

Yes, Real values are mostly supported at compile/elaboration time, and their use at run-time in the hardware is currently limited. I think the problem is that $bitstoreal is currently compile-time only: in your code, the value testv is assigned at runtime of the hardware, so applying $bitstoreal has to be done at runtime of the hardware (and therefore has to exist in the generated Bluesim or Verilog code); but currently BSC expects it to evaluate away to a constant at compile/elaboration-time, and the error is because it did not. The solution is just not to use $bitstoreal. The value that $value$plusargs extracts should be Real when the pattern is %f, and then you can use the value directly, without needing to call $bitstoreal to convert it:

// 'testv' is declared with type Real

rule bla;
        Bool a <- $value$plusargs("testF=%f",testv);
        $display("testF = %02f",testF);
endrule

Of course, it would be good to improve BSC to support more use of Real values in the generated hardware. For example, we can enhance BSC to allow $bitstoreal to remain in the generated code. We can discuss that, but we should open a separate issue for that, I think.

By the way, this is what I'm proposing for the BSV-source syntax:

rule bla;
  Maybe#(Real) mresult = $value$plusargs("testF=%f");
  case (mresult) matches
    tagged Valid .v:
      action
        testv <= v;
        $display("testF = %02f", v);
      endaction
   tagged Invalid:
     action
       $display("testF not found, using default");
       testv <= 0;
       // or consider aborting: $finish(0);
     endaction
  endcase
endrule

In your rule, I notice that you don't check the return value a to confirm that testv has been updated with a value. Using a Maybe would be less error prone.

@quark17
Copy link
Collaborator

quark17 commented Apr 17, 2025

Maybe it wasn't clear, and hopefully my last example illustrates it: I think that the type of testv should vary depending on the format string. If the string is a constant, this can be check in TCheck in the function for checking $test$plusargs. If the string is not yet known, then TCheck can at least assert that the type must be one of the expected types (UInt, Int, Bit, Real, String) and a later function can check this after elaboration is done (and the string is revealed).

@postoroniy
Copy link
Author

postoroniy commented Apr 17, 2025

idea to have same $value$plusargs as standard system task used to be in other sims.
it means when verilog source (in fact testbench) is generated by bsc - $value$plusargs would be as expected and usable there.
same as per $random and $random_range - where I am stuck at varieties of calling tasks with and without arg.
....again, idea to generate verilog and use it in other sims not by bluesim. btw $random can be observed in generated verilog on main branch but obviously bluesim is failing on it.

if bluesim has got all implemented PR's task - it is just good as I would test first in it, later in other sim.

so, arg in functions/tasks are important .. at least to me ))

tried this one

$value$plusargs("testF=%f",testv);

and

testv F = 4611731054423661568.000000
Output error: expected real argument, found non-real argument

here's example what in generated verilog

  // register testv
  reg [63 : 0] testv; //<--- REG! you can not assign to wire from plusargs AFAIK
  wire [63 : 0] testv_D_IN;
  wire testv_EN;
reg TASK_valueplusargs___d164; //<----------- same here!
//should be eiher reg or logic in case of SV
....
    if (RST_N != `BSV_RESET_VALUE)
      if (running &&
	  abort_whas__8_AND_abort_wget__9_0_OR_state_mkF_ETC___d154 &&
	  !start_reg)
	$finish(32'd0);
    begin
      TASK_valueplusargs___d164 = $value$plusargs("testv=%d", testv);
      #0;
    end
    if (TASK_valueplusargs___d164) $display("testv = %0x", testv);

as per MayBe thing need more my time and testing

@postoroniy
Copy link
Author

@quark17 all in all,
I think that valueplusargs (random and its friends) should not be used for verilog generation as such, but should affect actual sim either in bluesim or other sim which uses generated verilog by bsc

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants