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

[edn/rtl] Adapt sw_cmd_sts register #20873

Merged
merged 8 commits into from
Jan 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions hw/dv/sv/csrng_agent/csrng_monitor.sv
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class csrng_monitor extends dv_base_monitor #(
// uvm_analysis_port #(csrng_item): analysis_port

// Analysis port for the csrng_rsp_sts.
uvm_analysis_port #(bit) rsp_sts_ap;
uvm_analysis_port #(csrng_rsp_t) rsp_sts_ap;

uvm_tlm_analysis_fifo#(push_pull_item#(.HostDataWidth(csrng_pkg::CSRNG_CMD_WIDTH)))
csrng_cmd_fifo;
Expand Down Expand Up @@ -156,7 +156,7 @@ class csrng_monitor extends dv_base_monitor #(
end
end

rsp_sts_ap.write(cfg.vif.cmd_rsp.csrng_rsp_sts);
rsp_sts_ap.write(cfg.vif.cmd_rsp);
end
end
endtask
Expand Down
38 changes: 32 additions & 6 deletions hw/ip/edn/data/edn.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -309,19 +309,45 @@
"excl:CsrNonInitTests:CsrExclCheck"]
fields: [
{ bits: "0",
name: "CMD_RDY",
name: "CMD_REG_RDY",
desc: '''
This bit indicates when the command interface is ready to accept commands.
This bit indicates when !!SW_CMD_REQ is ready to accept the next word.
vogelpi marked this conversation as resolved.
Show resolved Hide resolved
This bit has to be polled before each word of a command is written to !!SW_CMD_REQ.
0b0: The EDN is not ready to accept the next word yet.
0b1: The EDN is ready to accept the next word.
'''
resval: "0"
}
{ bits: "1",
name: "CMD_RDY",
desc: '''
This bit indicates when the EDN is ready to accept the next command.
Before starting to write a new command to !!SW_CMD_REQ, this field needs to be polled.
0b0: The EDN is not ready to accept commands or the last command hasn't been acked yet.
0b1: The EDN is ready to accept the next command.
'''
resval: "0"
}
{ bits: "2",
name: "CMD_STS",
desc: '''
This one bit field is the status code returned with the application command ack.
It is updated each time a command ack is asserted on the CSRNG interface.
0b0: Request completed successfully
0b1: Request completed with an error
This one bit field represents the status code returned with the CSRNG application command ack.
It is updated each time a command is acknowledged by CSRNG.
To check whether a command was succesful, wait for !!INTR_STATE.EDN_CMD_REQ_DONE or
!!SW_CMD_STS.CMD_ACK to be high and then check the value of this field.
0b0: Request completed successfully.
0b1: Request completed with an error.
'''
resval: "0"
}
{ bits: "3",
name: "CMD_ACK",
desc: '''
This one bit field indicates when a command has been acknowledged by the CSRNG.
It is set to low each time a new command is written to !!SW_CMD_REQ.
The field is set to high once a SW command request has been acknowledged by the CSRNG.
0b0: The last command has not been acknowledged yet.
0b1: The last command has been acknowledged.
'''
resval: "0"
}
Expand Down
43 changes: 36 additions & 7 deletions hw/ip/edn/doc/registers.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,19 +226,48 @@ in the CSRNG documentation.
EDN command status register
- Offset: `0x24`
- Reset default: `0x0`
- Reset mask: `0x3`
- Reset mask: `0xf`

### Fields

```wavejson
{"reg": [{"name": "CMD_RDY", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "CMD_STS", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 30}], "config": {"lanes": 1, "fontsize": 10, "vspace": 90}}
{"reg": [{"name": "CMD_REG_RDY", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "CMD_RDY", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "CMD_STS", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "CMD_ACK", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 28}], "config": {"lanes": 1, "fontsize": 10, "vspace": 130}}
```

| Bits | Type | Reset | Name | Description |
|:------:|:------:|:-------:|:--------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 31:2 | | | | Reserved |
| 1 | ro | 0x0 | CMD_STS | This one bit field is the status code returned with the application command ack. It is updated each time a command ack is asserted on the CSRNG interface. 0b0: Request completed successfully 0b1: Request completed with an error |
| 0 | ro | 0x0 | CMD_RDY | This bit indicates when the command interface is ready to accept commands. |
| Bits | Type | Reset | Name |
|:------:|:------:|:-------:|:----------------------------------------|
| 31:4 | | | Reserved |
| 3 | ro | 0x0 | [CMD_ACK](#sw_cmd_sts--cmd_ack) |
| 2 | ro | 0x0 | [CMD_STS](#sw_cmd_sts--cmd_sts) |
| 1 | ro | 0x0 | [CMD_RDY](#sw_cmd_sts--cmd_rdy) |
| 0 | ro | 0x0 | [CMD_REG_RDY](#sw_cmd_sts--cmd_reg_rdy) |

### SW_CMD_STS . CMD_ACK
This one bit field indicates when a command has been acknowledged by the CSRNG.
It is set to low each time a new command is written to [`SW_CMD_REQ.`](#sw_cmd_req)
The field is set to high once a SW command request has been acknowledged by the CSRNG.
0b0: The last command has not been acknowledged yet.
0b1: The last command has been acknowledged.

### SW_CMD_STS . CMD_STS
This one bit field represents the status code returned with the CSRNG application command ack.
It is updated each time a command is acknowledged by CSRNG.
To check whether a command was succesful, wait for [`INTR_STATE.EDN_CMD_REQ_DONE`](#intr_state) or
[`SW_CMD_STS.CMD_ACK`](#sw_cmd_sts) to be high and then check the value of this field.
0b0: Request completed successfully.
0b1: Request completed with an error.

### SW_CMD_STS . CMD_RDY
This bit indicates when the EDN is ready to accept the next command.
Before starting to write a new command to [`SW_CMD_REQ`](#sw_cmd_req), this field needs to be polled.
0b0: The EDN is not ready to accept commands or the last command hasn't been acked yet.
0b1: The EDN is ready to accept the next command.

### SW_CMD_STS . CMD_REG_RDY
This bit indicates when [`SW_CMD_REQ`](#sw_cmd_req) is ready to accept the next word.
This bit has to be polled before each word of a command is written to [`SW_CMD_REQ.`](#sw_cmd_req)
0b0: The EDN is not ready to accept the next word yet.
0b1: The EDN is ready to accept the next word.

## RESEED_CMD
EDN csrng reseed command register
Expand Down
7 changes: 6 additions & 1 deletion hw/ip/edn/doc/theory_of_operation.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@ The CSRNG application interface implements the "function envelopes" recommended
For instance, the application interface port must receive an explicit `instantiate` command before receiving any `generate` commands.
The sequences of commands generated by a particular EDN are either controlled by the EDN state machine or by commands forwarded from firmware through the [`SW_CMD_REQ`](registers.md#sw_cmd_req) register.

Whenever commands are directly forwarded from firmware to the CSRNG through the [`SW_CMD_REQ`](registers.md#sw_cmd_req) register, firmware must poll and clear the `CMD_ACK` bit of the [`SW_CMD_STS`](registers.md#sw_cmd_sts) register before sending any further commands.
Whenever commands are directly forwarded from firmware to the CSRNG through the [`SW_CMD_REQ`](registers.md#sw_cmd_req) register, firmware must poll the `CMD_REG_RDY` and the `CMD_RDY` bits of the [`SW_CMD_STS`](registers.md#sw_cmd_sts) register before sending any further commands.
`CMD_RDY` indicates whether the EDN is ready to receive a new command, whereas `CMD_REG_RDY` indicates whether the EDN is ready to accept the next word of the command.
Each command consists of a command header, which is represented by a single word.
Furthermore, a command can have up to 12 words of additional data.
To check whether a command has been acknowledged by the CSRNG, the `CMD_ACK` bit of the [`SW_CMD_STS`](registers.md#sw_cmd_sts) register can be polled.
Whenever `CMD_ACK` is high, the `CMD_STS` bit can be checked to find out if an error occured.

Note that CSRNG commands are to be written into the [`SW_CMD_REQ`](registers.md#sw_cmd_req), [`RESEED_CMD`](registers.md#reseed_cmd), and [`GENERATE_CMD`](registers.md#generate_cmd) registers.
CSRNG command format details can be found in [CSRNG](../../csrng/README.md).
Expand Down
49 changes: 49 additions & 0 deletions hw/ip/edn/dv/cov/edn_cov_if.sv
Original file line number Diff line number Diff line change
Expand Up @@ -227,11 +227,49 @@ interface edn_cov_if (
cp_recov_alert_cg: coverpoint recov_alert;
endgroup : edn_alert_cg

covergroup edn_cs_cmd_response_cg with function sample(bit csrng_rsp_sts);
option.name = "edn_cs_cmd_response_cg";
option.per_instance = 1;

cp_csrng_rsp_sts_cg: coverpoint csrng_rsp_sts {
bins error = { 1'b1 };
bins success = { 1'b0 };
}
endgroup : edn_cs_cmd_response_cg

covergroup edn_sw_cmd_sts_cg with function sample(bit cmd_rdy, bit cmd_reg_rdy,
bit cmd_sts, bit cmd_ack);
option.name = "edn_sw_cmd_sts_cg";
option.per_instance = 1;

cp_cmd_rdy_cg: coverpoint cmd_rdy {
bins ready = { 1'b1 };
bins not_ready = { 1'b0 };
}

cp_cmd_reg_rdy_cg: coverpoint cmd_reg_rdy {
bins ready = { 1'b1 };
bins not_ready = { 1'b0 };
}

cp_cmd_sts_cg: coverpoint cmd_sts {
bins error = { 1'b1 };
bins success = { 1'b0 };
}

cp_cmd_ack_cg: coverpoint cmd_ack {
bins ack = { 1'b1 };
bins no_ack = { 1'b0 };
}
endgroup : edn_sw_cmd_sts_cg

`DV_FCOV_INSTANTIATE_CG(edn_cfg_cg, en_full_cov)
`DV_FCOV_INSTANTIATE_CG(edn_endpoints_cg, en_full_cov)
`DV_FCOV_INSTANTIATE_CG(edn_cs_cmds_cg, en_full_cov)
`DV_FCOV_INSTANTIATE_CG(edn_error_cg, en_full_cov)
`DV_FCOV_INSTANTIATE_CG(edn_alert_cg, en_full_cov)
`DV_FCOV_INSTANTIATE_CG(edn_cs_cmd_response_cg, en_full_cov)
`DV_FCOV_INSTANTIATE_CG(edn_sw_cmd_sts_cg, en_full_cov)

// Sample functions needed for xcelium
function automatic void cg_cfg_sample(edn_env_cfg cfg);
Expand Down Expand Up @@ -275,4 +313,15 @@ interface edn_cov_if (
end
endfunction : cg_alert_sample

function automatic void cg_cs_cmd_response_sample(bit csrng_rsp_sts, bit csrng_rsp_ack);
if (csrng_rsp_ack) begin
edn_cs_cmd_response_cg_inst.sample(csrng_rsp_sts);
end
endfunction : cg_cs_cmd_response_sample

function automatic void cg_edn_sw_cmd_sts_sample(bit cmd_rdy, bit cmd_reg_rdy,
bit cmd_sts, bit cmd_ack);
edn_sw_cmd_sts_cg_inst.sample(cmd_rdy, cmd_reg_rdy, cmd_sts, cmd_ack);
endfunction : cg_edn_sw_cmd_sts_sample

endinterface : edn_cov_if
7 changes: 7 additions & 0 deletions hw/ip/edn/dv/env/edn_env_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,13 @@ package edn_env_pkg;
AckError = 9'b111010001 // illegal state reached and hang
} state_ack_e;

typedef enum int {
cmd_reg_rdy = 0,
cmd_rdy = 1,
cmd_sts = 2,
cmd_ack = 3
} sw_cmd_sts_e;

// package sources
`include "edn_env_cfg.sv"
`include "edn_env_cov.sv"
Expand Down
53 changes: 46 additions & 7 deletions hw/ip/edn/dv/env/edn_scoreboard.sv
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class edn_scoreboard extends cip_base_scoreboard #(
uvm_tlm_analysis_fifo#(cs_cmd_item_t) cs_cmd_fifo;
uvm_tlm_analysis_fifo#(genbits_item_t) genbits_fifo;
uvm_tlm_analysis_fifo#(endpoint_item_t) endpoint_fifo[MAX_NUM_ENDPOINTS];
uvm_tlm_analysis_fifo#(bit) rsp_sts_fifo;
uvm_tlm_analysis_fifo#(csrng_pkg::csrng_rsp_t) rsp_sts_fifo;

// local queues to hold incoming packets pending comparison
bit [FIPS_ENDPOINT_BUS_WIDTH - 1:0] endpoint_data_q[$];
Expand All @@ -42,6 +42,8 @@ class edn_scoreboard extends cip_base_scoreboard #(
bit auto_mode = 1'b0;
// indicator bit, 1'b1 if EDN was instantiated
bit instantiated = 1'b0;
// indicator bit, 1'b1 if EDN instantiate was not acked yet
bit inst_ack_outstanding = 1'b0;
// indicator bit, 1'b1 if in boot_req_mode and generate cmd has been sent
bit boot_gen_cmd_sent = 1'b0;
// Indicator bit that equals 1'b1 if a backdoor disable has happened and
Expand All @@ -59,6 +61,12 @@ class edn_scoreboard extends cip_base_scoreboard #(
// Sample interrupt pins at read data phase. This is used to compare with intr_state read value.
bit [NumEdnIntr-1:0] intr_pins;

// Variables to track the SW_CMD_STS bits.
// TODO: (#15561) replace this by using predicts. e.g. ral.sw_cmd_sts.sw_cmd_ack.predict(.value(1'b0));
// This can be done once there is a proper prediction model for the ready fields.
bit sw_cmd_ack = 1'b0;
bit sw_cmd_sts = 1'b0;

`uvm_component_new

function void build_phase(uvm_phase phase);
Expand Down Expand Up @@ -208,6 +216,8 @@ class edn_scoreboard extends cip_base_scoreboard #(
reqs_between_reseeds_ctr = 32'b0;
instantiated = 1'b0;
boot_gen_cmd_sent = 1'b0;
sw_cmd_ack = 1'b0;
sw_cmd_sts = 1'b0;
sw_cmd_req_q.delete();

// Clear the auto mode FIFOs if Main_SM enters SW_Port_Mode or if the EDN has been
Expand Down Expand Up @@ -244,12 +254,26 @@ class edn_scoreboard extends cip_base_scoreboard #(
(!boot_mode && !auto_mode) ||
(auto_mode && !instantiated);

if (addr_phase_write && `gmv(ral.sw_cmd_sts.cmd_rdy) && sw_cmd_allowed) begin
if (addr_phase_write && `gmv(ral.sw_cmd_sts.cmd_reg_rdy) && sw_cmd_allowed) begin
sw_cmd_ack = 0;
sw_cmd_req_q.push_back(item.a_data);
end
end
"sw_cmd_sts": begin
do_read_check = 1'b0;
// If the EDN was disabled via back door, the state tracking bits need to be cleared.
if (cfg.backdoor_disable) begin
sw_cmd_ack = 1'b0;
sw_cmd_sts = 1'b0;
end
if (data_phase_read) begin
`DV_CHECK_EQ(sw_cmd_ack, item.d_data[cmd_ack])
`DV_CHECK_EQ(sw_cmd_sts, item.d_data[cmd_sts])
if (cfg.en_cov) begin
cov_vif.cg_edn_sw_cmd_sts_sample(item.d_data[cmd_rdy], item.d_data[cmd_reg_rdy],
item.d_data[cmd_sts], item.d_data[cmd_ack]);
end
end
end
"boot_ins_cmd": begin
if (addr_phase_write) begin
Expand Down Expand Up @@ -326,6 +350,7 @@ class edn_scoreboard extends cip_base_scoreboard #(
// If this is the last word of an instantiate command, set the appropriate flags
if ((acmd_cur == csrng_pkg::INS) && (clen_cntr == 0)) begin
instantiated = 1'b1;
inst_ack_outstanding = 1'b1;
end

// Determine which fifo to compare the additional data with
Expand Down Expand Up @@ -405,6 +430,7 @@ class edn_scoreboard extends cip_base_scoreboard #(
// and set flags accordingly
if (clen_cntr == 0) begin
instantiated = 1'b1;
inst_ack_outstanding = 1'b1;
end

// If EDN is in boot_req_mode and boot sequence is not done
Expand Down Expand Up @@ -554,11 +580,12 @@ class edn_scoreboard extends cip_base_scoreboard #(

if (boot_gen_cmd_sent) begin
boot_gen_cmd_sent = 1'b0;
boot_mode = 1'b0;
`DV_CHECK_FATAL(cs_cmd == edn_pkg::BOOT_UNINSTANTIATE,
$sformatf({"Uninstantiate command 0x%h has to match",
" the boot mode uninstantiate command 0x%h."},
cs_cmd, edn_pkg::BOOT_UNINSTANTIATE))
csr_spinwait(.ptr(ral.main_sm_state), .exp_data(edn_pkg::Idle), .backdoor(1'b1));
boot_mode = 1'b0;
end

instantiated = 1'b0;
Expand Down Expand Up @@ -588,13 +615,23 @@ class edn_scoreboard extends cip_base_scoreboard #(
endtask

task process_rsp_sts_fifo();
bit rsp_sts;
csrng_pkg::csrng_rsp_t rsp_sts;

forever begin
rsp_sts_fifo.get(rsp_sts);
if ((cfg.boot_req_mode == MuBi4False) && (cfg.auto_req_mode == MuBi4False)) begin
// Check register value if not boot_req_mode/auto_req_mode
csr_spinwait(.ptr(ral.sw_cmd_sts.cmd_sts), .exp_data(rsp_sts));
if (cfg.en_cov) begin
cov_vif.cg_cs_cmd_response_sample(rsp_sts.csrng_rsp_sts, rsp_sts.csrng_rsp_ack);
end
// Check the register value if we are not in boot_req_mode and not
// in auto_req_mode after the instantiate.
if (!boot_mode && (!auto_mode || inst_ack_outstanding)) begin
// Wait until the ack has propagated through the EDN to the register.
`DV_SPINWAIT_EXIT(
csr_spinwait(.ptr(ral.sw_cmd_sts.cmd_ack), .exp_data(rsp_sts.csrng_rsp_ack), .backdoor(1'b1));
sw_cmd_ack = rsp_sts.csrng_rsp_ack;
sw_cmd_sts = rsp_sts.csrng_rsp_sts;,
wait (cfg.backdoor_disable);)
inst_ack_outstanding = 0;
end
end
endtask
Expand Down Expand Up @@ -628,6 +665,8 @@ class edn_scoreboard extends cip_base_scoreboard #(
virtual function void reset(string kind = "HARD");
super.reset(kind);
// reset local fifos queues and variables
sw_cmd_ack = 1'b0;
sw_cmd_sts = 1'b0;
endfunction

function void check_phase(uvm_phase phase);
Expand Down
8 changes: 8 additions & 0 deletions hw/ip/edn/dv/env/seq_lib/edn_base_vseq.sv
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,11 @@ class edn_base_vseq extends cip_base_vseq #(
end
edn_env_pkg::Sw: begin
if (additional_data) begin
`DV_SPINWAIT_EXIT(
csr_spinwait(.ptr(ral.sw_cmd_sts.cmd_reg_rdy), .exp_data(1'b1));,
wait(cfg.abort_sw_cmd);,
"Aborted SW command"
)
csr_wr(.ptr(ral.sw_cmd_req), .value(cmd_data));
additional_data -= 1;
end
Expand All @@ -213,9 +218,12 @@ class edn_base_vseq extends cip_base_vseq #(
endtask

virtual task wait_cmd_req_done();
bit [TL_DW-1:0] val;
// Expect/Clear interrupt bit
csr_spinwait(.ptr(ral.intr_state.edn_cmd_req_done), .exp_data(1'b1));
check_interrupts(.interrupts((1 << CmdReqDone)), .check_set(1'b1));
// Read the sw_cmd_sts reg such that the scoreboard can check if the values are correct.
csr_rd(.ptr(ral.sw_cmd_sts), .value(val));
endtask

task force_fifo_err(string path1, string path2, bit value1, bit value2,
Expand Down
Loading
Loading