-
Notifications
You must be signed in to change notification settings - Fork 807
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
base: master
Are you sure you want to change the base?
GPIO straps verif #25868
Conversation
74b9fcd
to
7921fc9
Compare
There was a problem hiding this 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.
05e6443
to
2e49144
Compare
49e465c
to
fdfba6b
Compare
33ea687
to
1727a74
Compare
hw/ip/gpio/dv/env/gpio_env_cfg.sv
Outdated
// Used to allow reset operation during a stress all tests and check the CSR after that. | ||
can_reset_with_csr_accesses = 1'b1; |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
hw/ip/gpio/dv/env/gpio_scoreboard.sv
Outdated
end | ||
endtask : monitor_gpio_straps | ||
|
||
virtual protected task handle_reset(); |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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);
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
f9a778c
to
2449eed
Compare
hw/ip/gpio/dv/env/gpio_env_cfg.sv
Outdated
// Used to allow reset operation during a stress all tests and check the CSR after that. | ||
can_reset_with_csr_accesses = 1'b1; |
There was a problem hiding this comment.
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.
hw/ip/gpio/data/gpio_testplan.hjson
Outdated
{ | ||
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. |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
hw/ip/gpio/dv/env/gpio_scoreboard.sv
Outdated
`DV_CHECK_FATAL( | ||
ral.hw_straps_data_in.predict(.value(gpio_i_driven), |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
hw/ip/gpio/dv/env/gpio_scoreboard.sv
Outdated
// 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))); |
There was a problem hiding this comment.
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
?
There was a problem hiding this comment.
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
hw/ip/gpio/dv/env/gpio_scoreboard.sv
Outdated
@(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 |
There was a problem hiding this comment.
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) ...
).
There was a problem hiding this comment.
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.
constraint num_trans_c { | ||
num_trans inside {[20:200]}; | ||
} |
There was a problem hiding this comment.
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;) |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
modport port_in(input strap_en, output sampled_straps); | ||
modport port_out(output strap_en, input sampled_straps); |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
hw/ip/gpio/rtl/gpio.sv
Outdated
@@ -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) |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
Merge the PR lowRISC#25868 first. Signed-off-by: Marcelo Carvalho Faleiro de Almeida <[email protected]>
Merge the PR lowRISC#25868 first. Signed-off-by: Marcelo Carvalho Faleiro de Almeida <[email protected]>
d06c4fb
to
b2e32ac
Compare
There was a problem hiding this 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); |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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 ?
There was a problem hiding this 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.
841b660
to
cca3977
Compare
hw/dv/sv/csr_utils/csr_utils_pkg.sv
Outdated
There was a problem hiding this comment.
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]>
cca3977
to
390be45
Compare
New sequence to verify the straps feature and some additional description of the behaviour of this feature in the register document.