Skip to content

Commit

Permalink
[hw,spi_host,rtl] Remove configopts multi register
Browse files Browse the repository at this point in the history
FW needs to set up configopts before starting a transfer

Signed-off-by: Robert Schilling <[email protected]>
  • Loading branch information
Razer6 committed Dec 20, 2024
1 parent ebff68b commit a9be9a9
Show file tree
Hide file tree
Showing 11 changed files with 214 additions and 247 deletions.
146 changes: 72 additions & 74 deletions hw/ip/spi_host/data/spi_host.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -317,81 +317,79 @@
"excl:CsrAllTests:CsrExclCheck"]

},
{ multireg: { name: "CONFIGOPTS",
desc: '''Configuration options register.
{ name: "CONFIGOPTS",
desc: '''Configuration options register.

Contains options for controlling each peripheral. One register per
cs_n line''',
swaccess: "rw",
hwaccess: "hro",
cname: "configopts",
count: "NumCS",
fields: [
{ bits: "31",
name: "CPOL",
desc: '''The polarity of the sck clock signal. When CPOL is 0,
sck is low when idle, and emits high pulses. When CPOL
is 1, sck is high when idle, and emits a series of low
pulses.'''
resval: "0x0"
},
{ bits: "30",
name: "CPHA",
desc: '''The phase of the sck clock signal relative to the data. When
CPHA = 0, the data changes on the trailing edge of sck
and is typically sampled on the leading edge. Conversely
if CPHA = 1 high, data lines change on the leading edge of
sck and are typically sampled on the trailing edge.
CPHA should be chosen to match the phase of the selected
device. The sampling behavior is modified by the
!!CONFIGOPTS.FULLCYC bit.''',
resval: "0x0"
},
{ bits: "29",
name: "FULLCYC",
desc: '''Full cycle. Modifies the CPHA sampling behaviour to allow
for longer device logic setup times. Rather than sampling the SD
bus a half cycle after shifting out data, the data is sampled
a full cycle after shifting data out. This means that if
CPHA = 0, data is shifted out on the trailing edge, and
sampled a full cycle later. If CPHA = 1, data is shifted and
sampled with the trailing edge, also separated by a
full cycle.''',
resval: 0
},
{ bits: "27:24",
name: "CSNLEAD",
desc: '''CS_N Leading Time. Indicates the number of half sck cycles,
CSNLEAD+1, to leave between the falling edge of cs_n and
the first edge of sck. Setting this register to zero
corresponds to the minimum delay of one-half sck cycle'''
resval: 0
},
{ bits: "23:20",
name: "CSNTRAIL"
desc: '''CS_N Trailing Time. Indicates the number of half sck cycles,
CSNTRAIL+1, to leave between last edge of sck and the rising
edge of cs_n. Setting this register to zero corresponds
to the minimum delay of one-half sck cycle.'''
resval: 0
},
{ bits: "19:16",
name: "CSNIDLE"
desc: '''Minimum idle time between commands. Indicates the minimum
number of sck half-cycles to hold cs_n high between commands.
Setting this register to zero creates a minimally-wide CS_N-high
pulse of one-half sck cycle.'''
resval: 0
},
{ bits: "15:0",
name: "CLKDIV",
desc: '''Core clock divider. Slows down subsequent SPI transactions by a
factor of (CLKDIV+1) relative to the core clock frequency. The
period of sck, T(sck) then becomes `2*(CLK_DIV+1)*T(core)`'''
resval: 0
},
]
}
Contains options for controlling the current peripheral.
Firmware needs to configure the options before the transfer.
'''
swaccess: "rw",
hwaccess: "hro",
fields: [
{ bits: "31",
name: "CPOL",
desc: '''The polarity of the sck clock signal. When CPOL is 0,
sck is low when idle, and emits high pulses. When CPOL
is 1, sck is high when idle, and emits a series of low
pulses.'''
resval: "0x0"
},
{ bits: "30",
name: "CPHA",
desc: '''The phase of the sck clock signal relative to the data. When
CPHA = 0, the data changes on the trailing edge of sck
and is typically sampled on the leading edge. Conversely
if CPHA = 1 high, data lines change on the leading edge of
sck and are typically sampled on the trailing edge.
CPHA should be chosen to match the phase of the selected
device. The sampling behavior is modified by the
!!CONFIGOPTS.FULLCYC bit.''',
resval: "0x0"
},
{ bits: "29",
name: "FULLCYC",
desc: '''Full cycle. Modifies the CPHA sampling behaviour to allow
for longer device logic setup times. Rather than sampling the SD
bus a half cycle after shifting out data, the data is sampled
a full cycle after shifting data out. This means that if
CPHA = 0, data is shifted out on the trailing edge, and
sampled a full cycle later. If CPHA = 1, data is shifted and
sampled with the trailing edge, also separated by a
full cycle.''',
resval: 0
},
{ bits: "27:24",
name: "CSNLEAD",
desc: '''CS_N Leading Time. Indicates the number of half sck cycles,
CSNLEAD+1, to leave between the falling edge of cs_n and
the first edge of sck. Setting this register to zero
corresponds to the minimum delay of one-half sck cycle'''
resval: 0
},
{ bits: "23:20",
name: "CSNTRAIL"
desc: '''CS_N Trailing Time. Indicates the number of half sck cycles,
CSNTRAIL+1, to leave between last edge of sck and the rising
edge of cs_n. Setting this register to zero corresponds
to the minimum delay of one-half sck cycle.'''
resval: 0
},
{ bits: "19:16",
name: "CSNIDLE"
desc: '''Minimum idle time between commands. Indicates the minimum
number of sck half-cycles to hold cs_n high between commands.
Setting this register to zero creates a minimally-wide CS_N-high
pulse of one-half sck cycle.'''
resval: 0
},
{ bits: "15:0",
name: "CLKDIV",
desc: '''Core clock divider. Slows down subsequent SPI transactions by a
factor of (CLKDIV+1) relative to the core clock frequency. The
period of sck, T(sck) then becomes `2*(CLK_DIV+1)*T(core)`'''
resval: 0
},
]
},
{ name: "CSID",
desc: '''Chip-Select ID
Expand Down
68 changes: 31 additions & 37 deletions hw/ip/spi_host/doc/registers.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,18 +171,12 @@ Status register
## CONFIGOPTS
Configuration options register.

Contains options for controlling each peripheral. One register per
cs_n line
Contains options for controlling the current peripheral.
Firmware needs to configure the options before the transfer.
- Offset: `0x18`
- Reset default: `0x0`
- Reset mask: `0xefffffff`

### Instances

| Name | Offset |
|:-----------|:---------|
| CONFIGOPTS | 0x18 |


### Fields

```wavejson
Expand All @@ -202,52 +196,52 @@ Configuration options register.

### CONFIGOPTS . CPOL
The polarity of the sck clock signal. When CPOL is 0,
sck is low when idle, and emits high pulses. When CPOL
is 1, sck is high when idle, and emits a series of low
pulses.
sck is low when idle, and emits high pulses. When CPOL
is 1, sck is high when idle, and emits a series of low
pulses.

### CONFIGOPTS . CPHA
The phase of the sck clock signal relative to the data. When
CPHA = 0, the data changes on the trailing edge of sck
and is typically sampled on the leading edge. Conversely
if CPHA = 1 high, data lines change on the leading edge of
sck and are typically sampled on the trailing edge.
CPHA should be chosen to match the phase of the selected
device. The sampling behavior is modified by the
[`CONFIGOPTS.FULLCYC`](#configopts) bit.
CPHA = 0, the data changes on the trailing edge of sck
and is typically sampled on the leading edge. Conversely
if CPHA = 1 high, data lines change on the leading edge of
sck and are typically sampled on the trailing edge.
CPHA should be chosen to match the phase of the selected
device. The sampling behavior is modified by the
[`CONFIGOPTS.FULLCYC`](#configopts) bit.

### CONFIGOPTS . FULLCYC
Full cycle. Modifies the CPHA sampling behaviour to allow
for longer device logic setup times. Rather than sampling the SD
bus a half cycle after shifting out data, the data is sampled
a full cycle after shifting data out. This means that if
CPHA = 0, data is shifted out on the trailing edge, and
sampled a full cycle later. If CPHA = 1, data is shifted and
sampled with the trailing edge, also separated by a
full cycle.
for longer device logic setup times. Rather than sampling the SD
bus a half cycle after shifting out data, the data is sampled
a full cycle after shifting data out. This means that if
CPHA = 0, data is shifted out on the trailing edge, and
sampled a full cycle later. If CPHA = 1, data is shifted and
sampled with the trailing edge, also separated by a
full cycle.

### CONFIGOPTS . CSNLEAD
CS_N Leading Time. Indicates the number of half sck cycles,
CSNLEAD+1, to leave between the falling edge of cs_n and
the first edge of sck. Setting this register to zero
corresponds to the minimum delay of one-half sck cycle
CSNLEAD+1, to leave between the falling edge of cs_n and
the first edge of sck. Setting this register to zero
corresponds to the minimum delay of one-half sck cycle

### CONFIGOPTS . CSNTRAIL
CS_N Trailing Time. Indicates the number of half sck cycles,
CSNTRAIL+1, to leave between last edge of sck and the rising
edge of cs_n. Setting this register to zero corresponds
to the minimum delay of one-half sck cycle.
CSNTRAIL+1, to leave between last edge of sck and the rising
edge of cs_n. Setting this register to zero corresponds
to the minimum delay of one-half sck cycle.

### CONFIGOPTS . CSNIDLE
Minimum idle time between commands. Indicates the minimum
number of sck half-cycles to hold cs_n high between commands.
Setting this register to zero creates a minimally-wide CS_N-high
pulse of one-half sck cycle.
number of sck half-cycles to hold cs_n high between commands.
Setting this register to zero creates a minimally-wide CS_N-high
pulse of one-half sck cycle.

### CONFIGOPTS . CLKDIV
Core clock divider. Slows down subsequent SPI transactions by a
factor of (CLKDIV+1) relative to the core clock frequency. The
period of sck, T(sck) then becomes `2*(CLK_DIV+1)*T(core)`
factor of (CLKDIV+1) relative to the core clock frequency. The
period of sck, T(sck) then becomes `2*(CLK_DIV+1)*T(core)`

## CSID
Chip-Select ID
Expand Down
14 changes: 7 additions & 7 deletions hw/ip/spi_host/dv/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,13 @@ All common types and methods defined at the package level can be found in
// spi config
typedef struct {
// configopts register fields
rand bit cpol[SPI_HOST_NUM_CS];
rand bit cpha[SPI_HOST_NUM_CS];
rand bit fullcyc[SPI_HOST_NUM_CS];
rand bit [3:0] csnlead[SPI_HOST_NUM_CS];
rand bit [3:0] csntrail[SPI_HOST_NUM_CS];
rand bit [3:0] csnidle[SPI_HOST_NUM_CS];
rand bit [15:0] clkdiv[SPI_HOST_NUM_CS];
rand bit cpol;
rand bit cpha;
rand bit fullcyc;
rand bit [3:0] csnlead;
rand bit [3:0] csntrail;
rand bit [3:0] csnidle;
rand bit [15:0] clkdiv;
} spi_host_configopts_t;
typedef struct {
Expand Down
18 changes: 8 additions & 10 deletions hw/ip/spi_host/dv/env/seq_lib/spi_host_base_vseq.sv
Original file line number Diff line number Diff line change
Expand Up @@ -248,16 +248,14 @@ class spi_host_base_vseq extends cip_base_vseq #(

// CONFIGOPTS register fields
virtual task program_configopt_regs();
for (int i = 0; i < SPI_HOST_NUM_CS; i++) begin
ral.configopts[i].cpol.set(spi_config_regs.cpol[0]);
ral.configopts[i].cpha.set(spi_config_regs.cpha[0]);
ral.configopts[i].fullcyc.set(spi_config_regs.fullcyc[0]);
ral.configopts[i].csnlead.set(spi_config_regs.csnlead[0]);
ral.configopts[i].csntrail.set(spi_config_regs.csntrail[0]);
ral.configopts[i].csnidle.set(spi_config_regs.csnidle[0]);
ral.configopts[i].clkdiv.set(spi_config_regs.clkdiv[0]);
csr_wr(ral.configopts[i], .value(ral.configopts[i].get()));
end
ral.configopts.cpol.set(spi_config_regs.cpol[0]);
ral.configopts.cpha.set(spi_config_regs.cpha[0]);
ral.configopts.fullcyc.set(spi_config_regs.fullcyc[0]);
ral.configopts.csnlead.set(spi_config_regs.csnlead[0]);
ral.configopts.csntrail.set(spi_config_regs.csntrail[0]);
ral.configopts.csnidle.set(spi_config_regs.csnidle[0]);
ral.configopts.clkdiv.set(spi_config_regs.clkdiv[0]);
csr_wr(ral.configopts, .value(ral.configopts.get()));
endtask : program_configopt_regs


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class spi_host_overflow_underflow_vseq extends spi_host_tx_rx_vseq;
access_data_fifo(read_q, RxFifo, 1'b0); // attempting empty read error underflow
check_error(ral.error_status.underflow,1);

csr_wr(.ptr(ral.configopts[0].clkdiv), .value(16'h28)); // clk div set to 20
csr_wr(.ptr(ral.configopts.clkdiv), .value(16'h28)); // clk div set to 20

while (segms_words <= (SPI_HOST_TX_DEPTH + 1)) begin
check_error(ral.error_status.overflow,0);
Expand Down
15 changes: 7 additions & 8 deletions hw/ip/spi_host/dv/env/spi_host_env_cov.sv
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
* only in build_phase can be defined here
* Covergroups may also be wrapped inside helper classes if needed.
*/
//TODO(#18886) we only support SPI_HOST_NUM_CS=1

class spi_host_env_cov extends cip_base_env_cov #(.CFG_T(spi_host_env_cfg));
`uvm_component_utils(spi_host_env_cov)
Expand All @@ -29,26 +28,26 @@ class spi_host_env_cov extends cip_base_env_cov #(.CFG_T(spi_host_env_cfg));
endgroup : rx_fifo_underflow_cg

covergroup config_opts_cg with function sample(spi_host_configopts_t spi_configopts);
cpol_cp : coverpoint spi_configopts.cpol[SPI_HOST_NUM_CS-1]{ bins cpol[] = {[0:1]}; }
cpha_cp : coverpoint spi_configopts.cpha[SPI_HOST_NUM_CS-1]{ bins cpha[] = {[0:1]}; }
fullcyc_cp : coverpoint spi_configopts.fullcyc[SPI_HOST_NUM_CS-1]{
cpol_cp : coverpoint spi_configopts.cpol{ bins cpol[] = {[0:1]}; }
cpha_cp : coverpoint spi_configopts.cpha{ bins cpha[] = {[0:1]}; }
fullcyc_cp : coverpoint spi_configopts.fullcyc{
bins fullcyc[] = {[0:1]};
}
csnlead_cp : coverpoint spi_configopts.csnlead[SPI_HOST_NUM_CS-1]{
csnlead_cp : coverpoint spi_configopts.csnlead{
bins csnlead[] = {[0:15]};
}
csnidle_cp : coverpoint spi_configopts.csnidle[SPI_HOST_NUM_CS-1]{
csnidle_cp : coverpoint spi_configopts.csnidle{
bins csnidle[] = {[0:15]};
}
clkdiv_cp : coverpoint spi_configopts.clkdiv[SPI_HOST_NUM_CS-1]{
clkdiv_cp : coverpoint spi_configopts.clkdiv{
// (Period) T_sck = 2*(clkdiv+1)*T_core
// If clkdiv == 16'h00fe, F_sck = F_core / 254
bins clk_div_zero = {0};
bins clk_divm_bottom_eight[30] = {[16'h1:16'h00fe]};
bins clk_divm_upper_eight[30] = {[16'h00ff:16'hfffe]};
bins clk_divm_max = {16'hffff};
}
csntrail_cp : coverpoint spi_configopts.csntrail[SPI_HOST_NUM_CS-1]{
csntrail_cp : coverpoint spi_configopts.csntrail{
bins csntrail[] = {[0:15]};
}
cpol_cpha_cross : cross cpol_cp, cpha_cp;
Expand Down
14 changes: 7 additions & 7 deletions hw/ip/spi_host/dv/env/spi_host_env_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,13 @@ package spi_host_env_pkg;
// spi config
typedef struct {
// configopts register fields
rand bit cpol[SPI_HOST_NUM_CS];
rand bit cpha[SPI_HOST_NUM_CS];
rand bit fullcyc[SPI_HOST_NUM_CS];
rand bit [3:0] csnlead[SPI_HOST_NUM_CS];
rand bit [3:0] csntrail[SPI_HOST_NUM_CS];
rand bit [3:0] csnidle[SPI_HOST_NUM_CS];
rand bit [15:0] clkdiv[SPI_HOST_NUM_CS];
rand bit cpol;
rand bit cpha;
rand bit fullcyc;
rand bit [3:0] csnlead;
rand bit [3:0] csntrail;
rand bit [3:0] csnidle;
rand bit [15:0] clkdiv;
} spi_host_configopts_t;

typedef struct {
Expand Down
Loading

0 comments on commit a9be9a9

Please sign in to comment.