Skip to content
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

GPIO straps verif #25868

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

marcelocarvalhoLowRisc
Copy link
Contributor

New sequence to verify the straps feature and some additional description of the behaviour of this feature in the register document.

@marcelocarvalhoLowRisc marcelocarvalhoLowRisc requested a review from a team as a code owner January 14, 2025 15:59
@marcelocarvalhoLowRisc marcelocarvalhoLowRisc requested review from rswarbrick and martin-velay and removed request for a team January 14, 2025 15:59
@marcelocarvalhoLowRisc marcelocarvalhoLowRisc force-pushed the gpio_straps_verif branch 3 times, most recently from 74b9fcd to 7921fc9 Compare January 14, 2025 16:20
Copy link
Contributor

@martin-velay martin-velay left a comment

Choose a reason for hiding this comment

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

I think this PR still requires some changes.

hw/ip/gpio/dv/tb/tb.sv Outdated Show resolved Hide resolved
hw/ip/gpio/data/gpio_testplan.hjson Outdated Show resolved Hide resolved
hw/ip/gpio/dv/tb/tb.sv Outdated Show resolved Hide resolved
hw/ip/gpio/dv/env/gpio_env_cfg.sv Outdated Show resolved Hide resolved
hw/ip/gpio/dv/env/gpio_scoreboard.sv Outdated Show resolved Hide resolved
hw/ip/gpio/dv/env/seq_lib/gpio_rand_straps_vseq.sv Outdated Show resolved Hide resolved
hw/ip/gpio/dv/env/seq_lib/gpio_rand_straps_vseq.sv Outdated Show resolved Hide resolved
hw/ip/gpio/dv/env/seq_lib/gpio_rand_straps_vseq.sv Outdated Show resolved Hide resolved
hw/ip/gpio/dv/env/seq_lib/gpio_rand_straps_vseq.sv Outdated Show resolved Hide resolved
hw/ip/gpio/doc/registers.md Outdated Show resolved Hide resolved
@marcelocarvalhoLowRisc marcelocarvalhoLowRisc force-pushed the gpio_straps_verif branch 4 times, most recently from 05e6443 to 2e49144 Compare January 15, 2025 14:21
hw/ip/gpio/data/gpio.hjson Outdated Show resolved Hide resolved
hw/ip/gpio/data/gpio_testplan.hjson Outdated Show resolved Hide resolved
hw/ip/gpio/data/gpio_testplan.hjson Outdated Show resolved Hide resolved
hw/ip/gpio/data/gpio_testplan.hjson Outdated Show resolved Hide resolved
hw/ip/gpio/dv/env/gpio_scoreboard.sv Outdated Show resolved Hide resolved
hw/ip/gpio/dv/interfaces/gpio_straps_if.sv Outdated Show resolved Hide resolved
hw/ip/gpio/dv/interfaces/gpio_straps_if.sv Outdated Show resolved Hide resolved
hw/ip/gpio/dv/interfaces/gpio_straps_if.sv Outdated Show resolved Hide resolved
hw/ip/gpio/dv/tb/tb.sv Outdated Show resolved Hide resolved
hw/ip/gpio/dv/tb/tb.sv Outdated Show resolved Hide resolved
@marcelocarvalhoLowRisc marcelocarvalhoLowRisc force-pushed the gpio_straps_verif branch 17 times, most recently from 49e465c to fdfba6b Compare January 21, 2025 11:15
@marcelocarvalhoLowRisc marcelocarvalhoLowRisc force-pushed the gpio_straps_verif branch 5 times, most recently from 33ea687 to 1727a74 Compare January 23, 2025 11:30
Comment on lines 36 to 37
// Used to allow reset operation during a stress all tests and check the CSR after that.
can_reset_with_csr_accesses = 1'b1;
Copy link
Contributor

Choose a reason for hiding this comment

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

To avoid everything getting globbed together, can you pull this change into a separate commit (which can come first)?

That commit could be cherry-picked into a separate PR, that could be reviewed and merged without having to pin down the straps behaviour.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is merged from the first PR related with stress_all random reset. So I think we don't need to create a new PR only for this line, because it's include in the PR #25657. Or do you mean something else?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think this suggestion still stands.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I will drop the changes in the line 37, that is part of the PR #25657.
The other things are related with the strap verification updates.

end
endtask : monitor_gpio_straps

virtual protected task handle_reset();
Copy link
Contributor

Choose a reason for hiding this comment

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

I am not sure we need this task as this extended from the cip_scoreboard which is itself inherited from dv_base_scoreboard and where do the same: dv_base_scoreboard line#32. What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Very true, I will remove this and use the dv_base_scoreboard version. Thanks =)

logic strap_en; // Signal to enable straps
gpio_straps_t sampled_straps; // Sampled gpio_i snapshot data from GPIO (DUT)

modport straps_port(input strap_en, output sampled_straps);
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: alignment.

And for my knowledge, can you tell me why this modport is required?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think the idea was that such a port would allow one "actor" to see things in the correct direction.

But (for @marcelocarvalhoLowRisc):

  • Doesn't the DV code need to sample through the port? I'm thinking about tasks like monitor_gpio_straps.
  • But don't we need a port for things driving the strap_en state as well? (gpio_rand_straps_vseq)
  • And the ports should probably be named in a way that relates to who uses them. At the moment, we have a straps port on a straps interface, which is slightly doubled!
  • Finally: The indentation needs sorting out here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Very true, I will do this. Makes more sense to create 2 modports, one for each case.

function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
task reset_phase(uvm_phase phase);
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: can you insert one line break between each task/function ? And same before virtual function void build_phase(uvm_phase phase);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, indeed is visually not good =D

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

@marcelocarvalhoLowRisc marcelocarvalhoLowRisc force-pushed the gpio_straps_verif branch 2 times, most recently from f9a778c to 2449eed Compare January 28, 2025 11:36
Comment on lines 36 to 37
// Used to allow reset operation during a stress all tests and check the CSR after that.
can_reset_with_csr_accesses = 1'b1;
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this suggestion still stands.

{
name: straps_data
desc: '''Verify the straps data/valid ouput expected values based on the strap_en and gpio_i inputs:
- Drives gpio_i input with random values.
Copy link
Contributor

Choose a reason for hiding this comment

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

Grammar nit: I think this should probably be "Drive" to be the same as the other lines.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed

Comment on lines 370 to 371
`DV_CHECK_FATAL(
ral.hw_straps_data_in.predict(.value(gpio_i_driven),
Copy link
Contributor

Choose a reason for hiding this comment

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

Style nit: The indentation looks a bit odd here. I'd suggest this:

  virtual task update_gpio_straps_regs();
    // Update data_in ral register value based on result of input
    `DV_CHECK_FATAL(ral.hw_straps_data_in.predict(.value(gpio_i_driven),
                                                  .kind(UVM_PREDICT_DIRECT)));
    // Update data_in valid register value based on result of input
    `DV_CHECK_FATAL(ral.hw_straps_data_in_valid.predict(.value('b1),
                                                        .kind(UVM_PREDICT_DIRECT)));
  endtask : update_gpio_straps_regs

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

// Update data_in ral register value based on result of input
`DV_CHECK_FATAL(
ral.hw_straps_data_in.predict(.value(gpio_i_driven),
.kind(UVM_PREDICT_DIRECT)));
Copy link
Contributor

Choose a reason for hiding this comment

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

Isn't this going to die if it overlaps with a read of one of the two registers? I think this probably needs to be UVM_PREDICT_READ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, you are correct, this should be UVM_PREDICT_READ, from the documentation:

Predict based on the specified value having been read

@(posedge cfg.clk_rst_vif.clk)
if(!cfg.under_reset) begin
if (|gpio_i_driven === 1'b1) begin
@(posedge cfg.straps_vif_inst.port_out.strap_en) begin
Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm, I don't think this is going to work very nicely: it will block the "every clock" logic that is there otherwise. I think you probably need to rephrase it slightly, updating local variables on every clock edge with the current value of strap_en and then checking each time for a posedge and looking two cycles back (if (cfg.straps_vif_inst.port_out.strap_en && !strap_en_qq) ...).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I implemented the strap_en_qq flop logic inside of the interface, and fixed the statement.

Comment on lines 32 to 30
constraint num_trans_c {
num_trans inside {[20:200]};
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this note still applies?


// Wait at least one clock cycle to drive the strap_en
// Required because is required one clock cycle to update the gpio_in regsisters.
`DV_CHECK_MEMBER_RANDOMIZE_WITH_FATAL(delay, delay >= 1;)
Copy link
Contributor

Choose a reason for hiding this comment

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

This is reusing delay (a base class variable that's supposed to be gaps between transactions) for something else. I'd just randomise a local variable.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

true, fixed

// - Apply reset and make sure the strap registers are clean.
// - Read straps registers after reset.
// - Iterate again the same flow, with new random values.
class gpio_rand_straps_vseq extends gpio_base_vseq;
Copy link
Contributor

Choose a reason for hiding this comment

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

Thinking about this a bit, can't we drop this vseq entirely? Maybe the right approach is:

  • Update the base vseq so that the strap_en signal gets driven at unexpected times.
  • Teach the scoreboard when to sample the pins and store the results in the straps registers, updating the RAL.

Then I think tests like the CSR RW test should get all the behaviour you need?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think having a test case is the right approach. I believe that having a test case for this feature makes it easier to debug in the future if something changes in the RTL and the strap suddenly stops working. Additionally, having a test case for the feature makes it clearer for VPlan and coverage tracking. If the complexity of the feature increases in the future, it will be easier to implement incremental updates, rather than relying on a base class to 'insert' new code. Adding new elements to the base VSeq class could lead to unexpected issues, especially as the complexity of the testbench grows. Eventually, it could become difficult to track what is being driven and what isn’t.

Comment on lines 16 to 17
modport port_in(input strap_en, output sampled_straps);
modport port_out(output strap_en, input sampled_straps);
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure about the naming here: "in" and "out" both have one input and one output! :-)

Maybe name the ports after who is expected to do this sort of access?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, that is true, I was not very creative with that names, I changed it, let me know what do you think now.

@@ -85,7 +85,6 @@ module gpio
assign hw2reg.hw_straps_data_in.d = data_in_d;
assign sampled_straps_o.data = reg2hw.hw_straps_data_in.q;
assign sampled_straps_o.valid = reg2hw.hw_straps_data_in_valid.q;
`ASSUME(StrapSampleOnce_A, ##1 $fell(sample_trigger) |-> always !sample_trigger)
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd probably pull this 1-line change into a separate commit and push it as a PR in parallel. It's obviously correct.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok, I will do that.

marcelocarvalhoLowRisc added a commit to marcelocarvalhoLowRisc/opentitan that referenced this pull request Feb 3, 2025
Merge the PR lowRISC#25868 first.

Signed-off-by: Marcelo Carvalho Faleiro de Almeida <[email protected]>
marcelocarvalhoLowRisc added a commit to marcelocarvalhoLowRisc/opentitan that referenced this pull request Feb 3, 2025
Merge the PR lowRISC#25868 first.

Signed-off-by: Marcelo Carvalho Faleiro de Almeida <[email protected]>
@marcelocarvalhoLowRisc marcelocarvalhoLowRisc force-pushed the gpio_straps_verif branch 5 times, most recently from d06c4fb to b2e32ac Compare February 6, 2025 12:14
Copy link
Contributor Author

@marcelocarvalhoLowRisc marcelocarvalhoLowRisc left a comment

Choose a reason for hiding this comment

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

ready to be reviewed again

function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
task reset_phase(uvm_phase phase);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

modport tb_if(output strap_en, input sampled_straps);


always_ff @(posedge clk or negedge rst_n) begin
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: I think there is still an indentation issue for this whole block.
And by convention, I don't know if usually we do "qq" or "q2" here at lowRISC, @rswarbrick ?

Copy link
Contributor

@martin-velay martin-velay left a comment

Choose a reason for hiding this comment

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

From what I can see most of the comments have been covered and this PR looks better now. If the functionality part is OK, I am keen on having it merged.

@marcelocarvalhoLowRisc marcelocarvalhoLowRisc force-pushed the gpio_straps_verif branch 3 times, most recently from 841b660 to cca3977 Compare February 7, 2025 16:18
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I created this csr_mirror, based on csr_read but with only the necessary parameters. That is more useful instead of doing this all uvm_reg decode and checks and I kept the increment_outstanding.... task as well, that I think is required if with run this with rnd_reset stress all for example...

- Fix the gpio_stress_all with random reset PR:25657 was taking into this
  commit.

Signed-off-by: Marcelo Carvalho Faleiro de Almeida <[email protected]>
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.

3 participants