diff --git a/hw/ip/spi_host/data/spi_host.hjson b/hw/ip/spi_host/data/spi_host.hjson index d0dab3059776b..a7209277e556e 100644 --- a/hw/ip/spi_host/data/spi_host.hjson +++ b/hw/ip/spi_host/data/spi_host.hjson @@ -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 diff --git a/hw/ip/spi_host/doc/registers.md b/hw/ip/spi_host/doc/registers.md index b833a4b374ba5..ba8ca623a6a64 100644 --- a/hw/ip/spi_host/doc/registers.md +++ b/hw/ip/spi_host/doc/registers.md @@ -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 @@ -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 diff --git a/hw/ip/spi_host/dv/README.md b/hw/ip/spi_host/dv/README.md index 653f63fc0a80a..f903b58acc031 100644 --- a/hw/ip/spi_host/dv/README.md +++ b/hw/ip/spi_host/dv/README.md @@ -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 { diff --git a/hw/ip/spi_host/dv/env/seq_lib/spi_host_base_vseq.sv b/hw/ip/spi_host/dv/env/seq_lib/spi_host_base_vseq.sv index 36c4a5aecf512..f782b7bb87995 100644 --- a/hw/ip/spi_host/dv/env/seq_lib/spi_host_base_vseq.sv +++ b/hw/ip/spi_host/dv/env/seq_lib/spi_host_base_vseq.sv @@ -49,40 +49,28 @@ class spi_host_base_vseq extends cip_base_vseq #( constraint spi_config_regs_c { // configopts regs - foreach (spi_config_regs.cpol[i]) { - spi_config_regs.cpol[i] dist { - 1'b0 :/ 1, - 1'b1 :/ 1 - }; - } - foreach (spi_config_regs.cpha[i]) { - spi_config_regs.cpha[i] dist { - 1'b0 :/ 1, - 1'b1 :/ 1 - }; - } - foreach (spi_config_regs.csnlead[i]) { - spi_config_regs.csnlead[i] inside {[cfg.seq_cfg.host_spi_min_csn_latency : - cfg.seq_cfg.host_spi_max_csn_latency]}; - } - foreach (spi_config_regs.csntrail[i]) { - spi_config_regs.csntrail[i] inside {[cfg.seq_cfg.host_spi_min_csn_latency : - cfg.seq_cfg.host_spi_max_csn_latency]}; - } - foreach (spi_config_regs.csnidle[i]) { - spi_config_regs.csnidle[i] inside {[cfg.seq_cfg.host_spi_min_csn_latency : - cfg.seq_cfg.host_spi_max_csn_latency]}; - } + spi_config_regs.cpol dist { + 1'b0 :/ 1, + 1'b1 :/ 1 + }; + spi_config_regs.cpha dist { + 1'b0 :/ 1, + 1'b1 :/ 1 + }; + spi_config_regs.csnlead inside {[cfg.seq_cfg.host_spi_min_csn_latency : + cfg.seq_cfg.host_spi_max_csn_latency]}; + spi_config_regs.csntrail inside {[cfg.seq_cfg.host_spi_min_csn_latency : + cfg.seq_cfg.host_spi_max_csn_latency]}; + spi_config_regs.csnidle inside {[cfg.seq_cfg.host_spi_min_csn_latency : + cfg.seq_cfg.host_spi_max_csn_latency]}; } // Separate constraint to allow easy override in child sequences constraint spi_config_regs_clkdiv_c { - foreach (spi_config_regs.clkdiv[i]) { - spi_config_regs.clkdiv[i] dist { - [cfg.seq_cfg.host_spi_min_clkdiv : cfg.seq_cfg.host_spi_lower_middle_clkdiv] :/80, - [cfg.seq_cfg.host_spi_lower_middle_clkdiv+1 : cfg.seq_cfg.host_spi_middle_clkdiv] :/20 - }; - } + spi_config_regs.clkdiv dist { + [cfg.seq_cfg.host_spi_min_clkdiv : cfg.seq_cfg.host_spi_lower_middle_clkdiv] :/80, + [cfg.seq_cfg.host_spi_lower_middle_clkdiv+1 : cfg.seq_cfg.host_spi_middle_clkdiv] :/20 + }; } constraint spi_ctrl_regs_c { @@ -105,8 +93,7 @@ class spi_host_base_vseq extends cip_base_vseq #( function void post_randomize(); super.post_randomize(); - // We currently support 1 chip-select line only - case(spi_config_regs.clkdiv[0]) inside + case(spi_config_regs.clkdiv) inside // After randomization we set a different timeout based on the clock divider [cfg.seq_cfg.host_spi_min_clkdiv : cfg.seq_cfg.host_spi_lower_middle_clkdiv]: ; // no change [cfg.seq_cfg.host_spi_lower_middle_clkdiv+1 : cfg.seq_cfg.host_spi_middle_clkdiv]: begin @@ -114,8 +101,8 @@ class spi_host_base_vseq extends cip_base_vseq #( end [cfg.seq_cfg.host_spi_middle_clkdiv+1 : 16'hFFF] : cfg.csr_spinwait_timeout_ns *= 5; [16'hFFF+1 : cfg.seq_cfg.host_spi_max_clkdiv] : cfg.csr_spinwait_timeout_ns *= 10; - default : `uvm_fatal(`gfn, $sformatf("spi_config_regs.clkdiv[0]=0x%0x is out range", - spi_config_regs.clkdiv[0])) + default : `uvm_fatal(`gfn, $sformatf("spi_config_regs.clkdiv=0x%0x is out range", + spi_config_regs.clkdiv)) endcase endfunction @@ -248,16 +235,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); + ral.configopts.cpha.set(spi_config_regs.cpha); + ral.configopts.fullcyc.set(spi_config_regs.fullcyc); + ral.configopts.csnlead.set(spi_config_regs.csnlead); + ral.configopts.csntrail.set(spi_config_regs.csntrail); + ral.configopts.csnidle.set(spi_config_regs.csnidle); + ral.configopts.clkdiv.set(spi_config_regs.clkdiv); + csr_wr(ral.configopts, .value(ral.configopts.get())); endtask : program_configopt_regs @@ -351,15 +336,13 @@ class spi_host_base_vseq extends cip_base_vseq #( // update spi_agent registers virtual function void update_spi_agent_regs(); - for (int i = 0; i < SPI_HOST_NUM_CS; i++) begin - cfg.m_spi_agent_cfg.sck_polarity[i] = spi_config_regs.cpol[i]; - cfg.m_spi_agent_cfg.sck_phase[i] = spi_config_regs.cpha[i]; - cfg.m_spi_agent_cfg.full_cyc[i] = spi_config_regs.fullcyc[i]; - cfg.m_spi_agent_cfg.csn_lead[i] = spi_config_regs.csnlead[i]; - end - cfg.m_spi_agent_cfg.csid = spi_host_ctrl_reg.csid; - cfg.m_spi_agent_cfg.spi_mode = spi_host_command_reg.mode; - cfg.m_spi_agent_cfg.decode_commands = 1'b1; + cfg.m_spi_agent_cfg.sck_polarity = spi_config_regs.cpol; + cfg.m_spi_agent_cfg.sck_phase = spi_config_regs.cpha; + cfg.m_spi_agent_cfg.full_cyc = spi_config_regs.fullcyc; + cfg.m_spi_agent_cfg.csn_lead = spi_config_regs.csnlead; + cfg.m_spi_agent_cfg.csid = spi_host_ctrl_reg.csid; + cfg.m_spi_agent_cfg.spi_mode = spi_host_command_reg.mode; + cfg.m_spi_agent_cfg.decode_commands = 1'b1; print_spi_host_regs(); endfunction : update_spi_agent_regs @@ -376,16 +359,14 @@ class spi_host_base_vseq extends cip_base_vseq #( str = {str, $sformatf("\n direction %s", spi_host_command_reg.direction.name())}; str = {str, $sformatf("\n csaat %b", spi_host_command_reg.csaat)}; str = {str, $sformatf("\n len %0d", spi_host_command_reg.len)}; - for (int i = 0; i < SPI_HOST_NUM_CS; i++) begin - str = {str, $sformatf("\n config[%0d]", i)}; - str = {str, $sformatf("\n cpol %b", spi_config_regs.cpol[i])}; - str = {str, $sformatf("\n cpha %b", spi_config_regs.cpha[i])}; - str = {str, $sformatf("\n fullcyc %b", spi_config_regs.fullcyc[i])}; - str = {str, $sformatf("\n csnlead %0d", spi_config_regs.csnlead[i])}; - str = {str, $sformatf("\n csntrail %0d", spi_config_regs.csntrail[i])}; - str = {str, $sformatf("\n csnidle %0d", spi_config_regs.csnidle[i])}; - str = {str, $sformatf("\n clkdiv %0d\n", spi_config_regs.clkdiv[i])}; - end + str = {str, $sformatf("\n config")}; + str = {str, $sformatf("\n cpol %b", spi_config_regs.cpol)}; + str = {str, $sformatf("\n cpha %b", spi_config_regs.cpha)}; + str = {str, $sformatf("\n fullcyc %b", spi_config_regs.fullcyc)}; + str = {str, $sformatf("\n csnlead %0d", spi_config_regs.csnlead)}; + str = {str, $sformatf("\n csntrail %0d", spi_config_regs.csntrail)}; + str = {str, $sformatf("\n csnidle %0d", spi_config_regs.csnidle)}; + str = {str, $sformatf("\n clkdiv %0d\n", spi_config_regs.clkdiv)}; `uvm_info(`gfn, str, UVM_LOW) end endfunction : print_spi_host_regs diff --git a/hw/ip/spi_host/dv/env/seq_lib/spi_host_overflow_underflow_vseq.sv b/hw/ip/spi_host/dv/env/seq_lib/spi_host_overflow_underflow_vseq.sv index 7d202f9a11e9b..472a9391b0a32 100644 --- a/hw/ip/spi_host/dv/env/seq_lib/spi_host_overflow_underflow_vseq.sv +++ b/hw/ip/spi_host/dv/env/seq_lib/spi_host_overflow_underflow_vseq.sv @@ -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); diff --git a/hw/ip/spi_host/dv/env/seq_lib/spi_host_performance_vseq.sv b/hw/ip/spi_host/dv/env/seq_lib/spi_host_performance_vseq.sv index a909f31df1665..849ed626cf493 100644 --- a/hw/ip/spi_host/dv/env/seq_lib/spi_host_performance_vseq.sv +++ b/hw/ip/spi_host/dv/env/seq_lib/spi_host_performance_vseq.sv @@ -16,24 +16,16 @@ class spi_host_performance_vseq extends spi_host_smoke_vseq; } constraint spi_config_regs_c { - // configopts regs - foreach (spi_config_regs.cpol[i]) {spi_config_regs.cpol[i] == 1'b0;} - foreach (spi_config_regs.cpha[i]) {spi_config_regs.cpha[i] == 1'b0;} - foreach (spi_config_regs.csnlead[i]) { - spi_config_regs.csnlead[i] == cfg.seq_cfg.host_spi_min_csn_latency; - } - foreach (spi_config_regs.csntrail[i]) { - spi_config_regs.csntrail[i] == cfg.seq_cfg.host_spi_min_csn_latency; - } - foreach (spi_config_regs.csnidle[i]) { - spi_config_regs.csnidle[i] == cfg.seq_cfg.host_spi_min_csn_latency; - } + // configopts regs + spi_config_regs.cpol == 1'b0; + spi_config_regs.cpha == 1'b0; + spi_config_regs.csnlead == cfg.seq_cfg.host_spi_min_csn_latency; + spi_config_regs.csntrail == cfg.seq_cfg.host_spi_min_csn_latency; + spi_config_regs.csnidle == cfg.seq_cfg.host_spi_min_csn_latency; } constraint spi_config_regs_clkdiv_c { - foreach (spi_config_regs.clkdiv[i]) { - spi_config_regs.clkdiv[i] == cfg.seq_cfg.host_spi_min_clkdiv; - } + spi_config_regs.clkdiv == cfg.seq_cfg.host_spi_min_clkdiv; } virtual task body(); diff --git a/hw/ip/spi_host/dv/env/seq_lib/spi_host_smoke_vseq.sv b/hw/ip/spi_host/dv/env/seq_lib/spi_host_smoke_vseq.sv index a502b308d05ea..f06789aeac1ae 100644 --- a/hw/ip/spi_host/dv/env/seq_lib/spi_host_smoke_vseq.sv +++ b/hw/ip/spi_host/dv/env/seq_lib/spi_host_smoke_vseq.sv @@ -7,23 +7,17 @@ class spi_host_smoke_vseq extends spi_host_tx_rx_vseq; `uvm_object_utils(spi_host_smoke_vseq) `uvm_object_new - constraint spi_config_regs_c { - // configopts regs - foreach (spi_config_regs.cpol[i]) {spi_config_regs.cpol[i] == 1'b0;} - foreach (spi_config_regs.cpha[i]) {spi_config_regs.cpha[i] == 1'b0;} - foreach (spi_config_regs.csnlead[i]) { - spi_config_regs.csnlead[i] == cfg.seq_cfg.host_spi_max_csn_latency; - } - foreach (spi_config_regs.csntrail[i]) { - spi_config_regs.csntrail[i] == cfg.seq_cfg.host_spi_max_csn_latency; - } + constraint spi_config_regs_c { + // configopts regs + spi_config_regs.cpol == 1'b0; + spi_config_regs.cpha == 1'b0; + spi_config_regs.csnlead == cfg.seq_cfg.host_spi_max_csn_latency; + spi_config_regs.csntrail == cfg.seq_cfg.host_spi_max_csn_latency; } - constraint spi_config_regs_clkdiv_c { - foreach (spi_config_regs.clkdiv[i]) { - spi_config_regs.clkdiv[i] <= cfg.seq_cfg.host_spi_middle_clkdiv; - } - } + constraint spi_config_regs_clkdiv_c { + spi_config_regs.clkdiv <= cfg.seq_cfg.host_spi_middle_clkdiv; + } virtual task body(); diff --git a/hw/ip/spi_host/dv/env/seq_lib/spi_host_speed_vseq.sv b/hw/ip/spi_host/dv/env/seq_lib/spi_host_speed_vseq.sv index 36410912771be..06981719e0761 100644 --- a/hw/ip/spi_host/dv/env/seq_lib/spi_host_speed_vseq.sv +++ b/hw/ip/spi_host/dv/env/seq_lib/spi_host_speed_vseq.sv @@ -9,40 +9,28 @@ class spi_host_speed_vseq extends spi_host_smoke_vseq; constraint spi_config_regs_c { // configopts regs - foreach (spi_config_regs.cpol[i]) { - spi_config_regs.cpol[i] dist { - 1'b0 :/ 1, - 1'b1 :/ 1 - }; - } - foreach (spi_config_regs.cpha[i]) { - spi_config_regs.cpha[i] dist { - 1'b0 :/ 1, - 1'b1 :/ 1 - }; - } - foreach (spi_config_regs.csnlead[i]) { - spi_config_regs.csnlead[i] inside {[cfg.seq_cfg.host_spi_min_csn_latency : - cfg.seq_cfg.host_spi_max_csn_latency]}; - } - foreach (spi_config_regs.csntrail[i]) { - spi_config_regs.csntrail[i] inside {[cfg.seq_cfg.host_spi_min_csn_latency : - cfg.seq_cfg.host_spi_max_csn_latency]}; - } - foreach (spi_config_regs.csnidle[i]) { - spi_config_regs.csnidle[i] inside {[cfg.seq_cfg.host_spi_min_csn_latency : - cfg.seq_cfg.host_spi_max_csn_latency]}; - } + spi_config_regs.cpol dist { + 1'b0 :/ 1, + 1'b1 :/ 1 + }; + spi_config_regs.cpha dist { + 1'b0 :/ 1, + 1'b1 :/ 1 + }; + spi_config_regs.csnlead inside {[cfg.seq_cfg.host_spi_min_csn_latency : + cfg.seq_cfg.host_spi_max_csn_latency]}; + spi_config_regs.csntrail inside {[cfg.seq_cfg.host_spi_min_csn_latency : + cfg.seq_cfg.host_spi_max_csn_latency]}; + spi_config_regs.csnidle inside {[cfg.seq_cfg.host_spi_min_csn_latency : + cfg.seq_cfg.host_spi_max_csn_latency]}; } constraint spi_config_regs_clkdiv_c { - foreach (spi_config_regs.clkdiv[i]) { - // CLKDIV randomised not in the whole range since there's a dedicated VSEQ: - // spi_host_upper_range_clkdiv_vseq.sv which uses the upper range of clock - // divider values - this way we won't have super long tests when running this VSEQ - spi_config_regs.clkdiv[i] inside {[cfg.seq_cfg.host_spi_min_clkdiv : - cfg.seq_cfg.host_spi_lower_middle_clkdiv]}; - } + // CLKDIV randomised not in the whole range since there's a dedicated VSEQ: + // spi_host_upper_range_clkdiv_vseq.sv which uses the upper range of clock + // divider values - this way we won't have super long tests when running this VSEQ + spi_config_regs.clkdiv inside {[cfg.seq_cfg.host_spi_min_clkdiv : + cfg.seq_cfg.host_spi_lower_middle_clkdiv]}; } virtual task start_spi_host_trans(int num_transactions, bit wait_ready = 1'b1); diff --git a/hw/ip/spi_host/dv/env/seq_lib/spi_host_upper_range_clkdiv_vseq.sv b/hw/ip/spi_host/dv/env/seq_lib/spi_host_upper_range_clkdiv_vseq.sv index 9de85b6366c7e..563eeac449efd 100644 --- a/hw/ip/spi_host/dv/env/seq_lib/spi_host_upper_range_clkdiv_vseq.sv +++ b/hw/ip/spi_host/dv/env/seq_lib/spi_host_upper_range_clkdiv_vseq.sv @@ -13,14 +13,12 @@ class spi_host_upper_range_clkdiv_vseq extends spi_host_speed_vseq; constraint spi_config_regs_clkdiv_c { solve max_range_value before spi_config_regs.clkdiv; max_range_value dist { 0 :/ 7, 1 :/ 3}; - foreach (spi_config_regs.clkdiv[i]) { - // CLKDIV randomised not in the whole range since there's a dedicated VSEQ: seq_name - // which uses the upper range of clock divider values - this way we won't have super long - // tests when running this VSEQ - max_range_value -> (spi_config_regs.clkdiv[i] == cfg.seq_cfg.host_spi_max_clkdiv); - !max_range_value -> (spi_config_regs.clkdiv[i] inside {[cfg.seq_cfg.host_spi_middle_clkdiv : - cfg.seq_cfg.host_spi_max_clkdiv]}); - } + // CLKDIV randomised not in the whole range since there's a dedicated VSEQ: seq_name + // which uses the upper range of clock divider values - this way we won't have super long + // tests when running this VSEQ + max_range_value -> (spi_config_regs.clkdiv == cfg.seq_cfg.host_spi_max_clkdiv); + !max_range_value -> (spi_config_regs.clkdiv inside {[cfg.seq_cfg.host_spi_middle_clkdiv : + cfg.seq_cfg.host_spi_max_clkdiv]}); } constraint num_trans_c { diff --git a/hw/ip/spi_host/dv/env/spi_host_env_cov.sv b/hw/ip/spi_host/dv/env/spi_host_env_cov.sv index cd2b651addcf6..1bde1766ccc44 100644 --- a/hw/ip/spi_host/dv/env/spi_host_env_cov.sv +++ b/hw/ip/spi_host/dv/env/spi_host_env_cov.sv @@ -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) @@ -29,18 +28,18 @@ 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}; @@ -48,7 +47,7 @@ class spi_host_env_cov extends cip_base_env_cov #(.CFG_T(spi_host_env_cfg)); 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; diff --git a/hw/ip/spi_host/dv/env/spi_host_env_pkg.sv b/hw/ip/spi_host/dv/env/spi_host_env_pkg.sv index c035f53683c03..be553ca0c2443 100644 --- a/hw/ip/spi_host/dv/env/spi_host_env_pkg.sv +++ b/hw/ip/spi_host/dv/env/spi_host_env_pkg.sv @@ -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 { diff --git a/hw/ip/spi_host/dv/env/spi_host_scoreboard.sv b/hw/ip/spi_host/dv/env/spi_host_scoreboard.sv index ccbf808a8807a..9bc2edc6ff7d0 100644 --- a/hw/ip/spi_host/dv/env/spi_host_scoreboard.sv +++ b/hw/ip/spi_host/dv/env/spi_host_scoreboard.sv @@ -387,24 +387,13 @@ class spi_host_scoreboard extends cip_base_scoreboard #( end "configopts": begin - // Note: CONFIGOPTS is actually a multireg, but we've only got a count of 1, which means - // the CSR is called "configopts" (instead of e.g. configopts0). Manufacture CSR index - // accordingly. - int csr_idx = 0; - spi_configopts.cpol[csr_idx] = get_field_val(ral.configopts[csr_idx].cpol, - item.a_data); - spi_configopts.cpha[csr_idx] = get_field_val(ral.configopts[csr_idx].cpha, - item.a_data); - spi_configopts.fullcyc[csr_idx] = get_field_val(ral.configopts[csr_idx].fullcyc, - item.a_data); - spi_configopts.csnlead[csr_idx] = get_field_val(ral.configopts[csr_idx].csnlead, - item.a_data); - spi_configopts.csnidle[csr_idx] = get_field_val(ral.configopts[csr_idx].csnidle, - item.a_data); - spi_configopts.clkdiv[csr_idx] = get_field_val(ral.configopts[csr_idx].clkdiv, - item.a_data); - spi_configopts.csntrail[csr_idx] = get_field_val(ral.configopts[csr_idx].csntrail, - item.a_data); + spi_configopts.cpol = get_field_val(ral.configopts.cpol, item.a_data); + spi_configopts.cpha = get_field_val(ral.configopts.cpha, item.a_data); + spi_configopts.fullcyc = get_field_val(ral.configopts.fullcyc, item.a_data); + spi_configopts.csnlead = get_field_val(ral.configopts.csnlead, item.a_data); + spi_configopts.csnidle = get_field_val(ral.configopts.csnidle, item.a_data); + spi_configopts.clkdiv = get_field_val(ral.configopts.clkdiv, item.a_data); + spi_configopts.csntrail = get_field_val(ral.configopts.csntrail, item.a_data); if (cfg.en_cov) begin cov.config_opts_cg.sample(spi_configopts); end diff --git a/hw/ip/spi_host/dv/sva/spi_host_bind.sv b/hw/ip/spi_host/dv/sva/spi_host_bind.sv index 3d595a07bd41b..cdeb86dc32a4b 100644 --- a/hw/ip/spi_host/dv/sva/spi_host_bind.sv +++ b/hw/ip/spi_host/dv/sva/spi_host_bind.sv @@ -20,6 +20,14 @@ module spi_host_bind; .d2h (tl_o) ); - bind spi_host spi_host_data_stable_sva spi_host_data_stable_assert (.*); + bind spi_host spi_host_data_stable_sva spi_host_data_stable_assert ( + .rst_ni, + .cio_sck_o, + .cio_csb_o, + .cio_sd_i, + .cio_sd_en_o, + .configopts(reg2hw.configopts), + .passthrough_i + ); endmodule diff --git a/hw/ip/spi_host/dv/sva/spi_host_data_stable_sva.sv b/hw/ip/spi_host/dv/sva/spi_host_data_stable_sva.sv index f95d4958a3501..d2662cc96058a 100644 --- a/hw/ip/spi_host/dv/sva/spi_host_data_stable_sva.sv +++ b/hw/ip/spi_host/dv/sva/spi_host_data_stable_sva.sv @@ -3,13 +3,13 @@ // SPDX-License-Identifier: Apache-2.0 module spi_host_data_stable_sva ( - input logic rst_ni, - input logic cio_sck_o, - input logic [spi_host_reg_pkg::NumCS-1:0] cio_csb_o, - input logic [3:0] cio_sd_i, - input logic [3:0] cio_sd_en_o, - input spi_host_reg_pkg::spi_host_reg2hw_configopts_mreg_t configopts, - input spi_device_pkg::passthrough_req_t passthrough_i + input logic rst_ni, + input logic cio_sck_o, + input logic [spi_host_reg_pkg::NumCS-1:0] cio_csb_o, + input logic [3:0] cio_sd_i, + input logic [3:0] cio_sd_en_o, + input spi_host_reg_pkg::spi_host_reg2hw_configopts_reg_t configopts, + input spi_device_pkg::passthrough_req_t passthrough_i ); // Check to ensure cio_sd_o[i] stays stable for a whole clock cycle diff --git a/hw/ip/spi_host/rtl/spi_host.sv b/hw/ip/spi_host/rtl/spi_host.sv index ab91529fe902f..4b8d768e41df5 100644 --- a/hw/ip/spi_host/rtl/spi_host.sv +++ b/hw/ip/spi_host/rtl/spi_host.sv @@ -216,25 +216,15 @@ module spi_host assign error_cmd_inval = command_valid & ~command_busy & (test_speed_inval | test_dir_inval); - spi_host_reg_pkg::spi_host_reg2hw_configopts_mreg_t configopts; - - if (NumCS == 1) begin : gen_single_device - assign configopts = reg2hw.configopts[0]; - assign command.csid = '0; - end else begin : gen_multiple_devices - logic [CSW-1:0] csid; - assign csid = (test_csid_inval) ? '0 : reg2hw.csid.q[CSW-1:0]; - assign configopts = reg2hw.configopts[csid]; - assign command.csid = csid; - end : gen_multiple_devices - - assign command.configopts.clkdiv = configopts.clkdiv.q; - assign command.configopts.csnidle = configopts.csnidle.q; - assign command.configopts.csnlead = configopts.csnlead.q; - assign command.configopts.csntrail = configopts.csntrail.q; - assign command.configopts.full_cyc = configopts.fullcyc.q; - assign command.configopts.cpha = configopts.cpha.q; - assign command.configopts.cpol = configopts.cpol.q; + assign command.csid = (test_csid_inval) ? '0 : reg2hw.csid.q[CSW-1:0]; + + assign command.configopts.clkdiv = reg2hw.configopts.clkdiv.q; + assign command.configopts.csnidle = reg2hw.configopts.csnidle.q; + assign command.configopts.csnlead = reg2hw.configopts.csnlead.q; + assign command.configopts.csntrail = reg2hw.configopts.csntrail.q; + assign command.configopts.full_cyc = reg2hw.configopts.fullcyc.q; + assign command.configopts.cpha = reg2hw.configopts.cpha.q; + assign command.configopts.cpol = reg2hw.configopts.cpol.q; assign command.segment.len = reg2hw.command.len.q; assign command.segment.csaat = reg2hw.command.csaat.q; diff --git a/hw/ip/spi_host/rtl/spi_host_reg_pkg.sv b/hw/ip/spi_host/rtl/spi_host_reg_pkg.sv index bf2b032c71d1d..1d3717142c6ea 100644 --- a/hw/ip/spi_host/rtl/spi_host_reg_pkg.sv +++ b/hw/ip/spi_host/rtl/spi_host_reg_pkg.sv @@ -95,7 +95,7 @@ package spi_host_reg_pkg; struct packed { logic [15:0] q; } clkdiv; - } spi_host_reg2hw_configopts_mreg_t; + } spi_host_reg2hw_configopts_reg_t; typedef struct packed { logic [31:0] q; @@ -284,7 +284,7 @@ package spi_host_reg_pkg; spi_host_reg2hw_intr_test_reg_t intr_test; // [133:130] spi_host_reg2hw_alert_test_reg_t alert_test; // [129:128] spi_host_reg2hw_control_reg_t control; // [127:109] - spi_host_reg2hw_configopts_mreg_t [0:0] configopts; // [108:78] + spi_host_reg2hw_configopts_reg_t configopts; // [108:78] spi_host_reg2hw_csid_reg_t csid; // [77:46] spi_host_reg2hw_command_reg_t command; // [45:17] spi_host_reg2hw_error_enable_reg_t error_enable; // [16:12] diff --git a/hw/ip/spi_host/rtl/spi_host_reg_top.sv b/hw/ip/spi_host/rtl/spi_host_reg_top.sv index c22f9ea75f104..1140141725aa8 100644 --- a/hw/ip/spi_host/rtl/spi_host_reg_top.sv +++ b/hw/ip/spi_host/rtl/spi_host_reg_top.sv @@ -213,20 +213,20 @@ module spi_host_reg_top ( logic status_active_qs; logic status_ready_qs; logic configopts_we; - logic [15:0] configopts_clkdiv_0_qs; - logic [15:0] configopts_clkdiv_0_wd; - logic [3:0] configopts_csnidle_0_qs; - logic [3:0] configopts_csnidle_0_wd; - logic [3:0] configopts_csntrail_0_qs; - logic [3:0] configopts_csntrail_0_wd; - logic [3:0] configopts_csnlead_0_qs; - logic [3:0] configopts_csnlead_0_wd; - logic configopts_fullcyc_0_qs; - logic configopts_fullcyc_0_wd; - logic configopts_cpha_0_qs; - logic configopts_cpha_0_wd; - logic configopts_cpol_0_qs; - logic configopts_cpol_0_wd; + logic [15:0] configopts_clkdiv_qs; + logic [15:0] configopts_clkdiv_wd; + logic [3:0] configopts_csnidle_qs; + logic [3:0] configopts_csnidle_wd; + logic [3:0] configopts_csntrail_qs; + logic [3:0] configopts_csntrail_wd; + logic [3:0] configopts_csnlead_qs; + logic [3:0] configopts_csnlead_wd; + logic configopts_fullcyc_qs; + logic configopts_fullcyc_wd; + logic configopts_cpha_qs; + logic configopts_cpha_wd; + logic configopts_cpol_qs; + logic configopts_cpol_wd; logic csid_we; logic [31:0] csid_qs; logic [31:0] csid_wd; @@ -960,21 +960,20 @@ module spi_host_reg_top ( ); - // Subregister 0 of Multireg configopts // R[configopts]: V(False) - // F[clkdiv_0]: 15:0 + // F[clkdiv]: 15:0 prim_subreg #( .DW (16), .SwAccess(prim_subreg_pkg::SwAccessRW), .RESVAL (16'h0), .Mubi (1'b0) - ) u_configopts_clkdiv_0 ( + ) u_configopts_clkdiv ( .clk_i (clk_i), .rst_ni (rst_ni), // from register interface .we (configopts_we), - .wd (configopts_clkdiv_0_wd), + .wd (configopts_clkdiv_wd), // from internal hardware .de (1'b0), @@ -982,26 +981,26 @@ module spi_host_reg_top ( // to internal hardware .qe (), - .q (reg2hw.configopts[0].clkdiv.q), + .q (reg2hw.configopts.clkdiv.q), .ds (), // to register interface (read) - .qs (configopts_clkdiv_0_qs) + .qs (configopts_clkdiv_qs) ); - // F[csnidle_0]: 19:16 + // F[csnidle]: 19:16 prim_subreg #( .DW (4), .SwAccess(prim_subreg_pkg::SwAccessRW), .RESVAL (4'h0), .Mubi (1'b0) - ) u_configopts_csnidle_0 ( + ) u_configopts_csnidle ( .clk_i (clk_i), .rst_ni (rst_ni), // from register interface .we (configopts_we), - .wd (configopts_csnidle_0_wd), + .wd (configopts_csnidle_wd), // from internal hardware .de (1'b0), @@ -1009,26 +1008,26 @@ module spi_host_reg_top ( // to internal hardware .qe (), - .q (reg2hw.configopts[0].csnidle.q), + .q (reg2hw.configopts.csnidle.q), .ds (), // to register interface (read) - .qs (configopts_csnidle_0_qs) + .qs (configopts_csnidle_qs) ); - // F[csntrail_0]: 23:20 + // F[csntrail]: 23:20 prim_subreg #( .DW (4), .SwAccess(prim_subreg_pkg::SwAccessRW), .RESVAL (4'h0), .Mubi (1'b0) - ) u_configopts_csntrail_0 ( + ) u_configopts_csntrail ( .clk_i (clk_i), .rst_ni (rst_ni), // from register interface .we (configopts_we), - .wd (configopts_csntrail_0_wd), + .wd (configopts_csntrail_wd), // from internal hardware .de (1'b0), @@ -1036,26 +1035,26 @@ module spi_host_reg_top ( // to internal hardware .qe (), - .q (reg2hw.configopts[0].csntrail.q), + .q (reg2hw.configopts.csntrail.q), .ds (), // to register interface (read) - .qs (configopts_csntrail_0_qs) + .qs (configopts_csntrail_qs) ); - // F[csnlead_0]: 27:24 + // F[csnlead]: 27:24 prim_subreg #( .DW (4), .SwAccess(prim_subreg_pkg::SwAccessRW), .RESVAL (4'h0), .Mubi (1'b0) - ) u_configopts_csnlead_0 ( + ) u_configopts_csnlead ( .clk_i (clk_i), .rst_ni (rst_ni), // from register interface .we (configopts_we), - .wd (configopts_csnlead_0_wd), + .wd (configopts_csnlead_wd), // from internal hardware .de (1'b0), @@ -1063,26 +1062,26 @@ module spi_host_reg_top ( // to internal hardware .qe (), - .q (reg2hw.configopts[0].csnlead.q), + .q (reg2hw.configopts.csnlead.q), .ds (), // to register interface (read) - .qs (configopts_csnlead_0_qs) + .qs (configopts_csnlead_qs) ); - // F[fullcyc_0]: 29:29 + // F[fullcyc]: 29:29 prim_subreg #( .DW (1), .SwAccess(prim_subreg_pkg::SwAccessRW), .RESVAL (1'h0), .Mubi (1'b0) - ) u_configopts_fullcyc_0 ( + ) u_configopts_fullcyc ( .clk_i (clk_i), .rst_ni (rst_ni), // from register interface .we (configopts_we), - .wd (configopts_fullcyc_0_wd), + .wd (configopts_fullcyc_wd), // from internal hardware .de (1'b0), @@ -1090,26 +1089,26 @@ module spi_host_reg_top ( // to internal hardware .qe (), - .q (reg2hw.configopts[0].fullcyc.q), + .q (reg2hw.configopts.fullcyc.q), .ds (), // to register interface (read) - .qs (configopts_fullcyc_0_qs) + .qs (configopts_fullcyc_qs) ); - // F[cpha_0]: 30:30 + // F[cpha]: 30:30 prim_subreg #( .DW (1), .SwAccess(prim_subreg_pkg::SwAccessRW), .RESVAL (1'h0), .Mubi (1'b0) - ) u_configopts_cpha_0 ( + ) u_configopts_cpha ( .clk_i (clk_i), .rst_ni (rst_ni), // from register interface .we (configopts_we), - .wd (configopts_cpha_0_wd), + .wd (configopts_cpha_wd), // from internal hardware .de (1'b0), @@ -1117,26 +1116,26 @@ module spi_host_reg_top ( // to internal hardware .qe (), - .q (reg2hw.configopts[0].cpha.q), + .q (reg2hw.configopts.cpha.q), .ds (), // to register interface (read) - .qs (configopts_cpha_0_qs) + .qs (configopts_cpha_qs) ); - // F[cpol_0]: 31:31 + // F[cpol]: 31:31 prim_subreg #( .DW (1), .SwAccess(prim_subreg_pkg::SwAccessRW), .RESVAL (1'h0), .Mubi (1'b0) - ) u_configopts_cpol_0 ( + ) u_configopts_cpol ( .clk_i (clk_i), .rst_ni (rst_ni), // from register interface .we (configopts_we), - .wd (configopts_cpol_0_wd), + .wd (configopts_cpol_wd), // from internal hardware .de (1'b0), @@ -1144,11 +1143,11 @@ module spi_host_reg_top ( // to internal hardware .qe (), - .q (reg2hw.configopts[0].cpol.q), + .q (reg2hw.configopts.cpol.q), .ds (), // to register interface (read) - .qs (configopts_cpol_0_qs) + .qs (configopts_cpol_qs) ); @@ -1781,19 +1780,19 @@ module spi_host_reg_top ( assign control_spien_wd = reg_wdata[31]; assign configopts_we = addr_hit[6] & reg_we & !reg_error; - assign configopts_clkdiv_0_wd = reg_wdata[15:0]; + assign configopts_clkdiv_wd = reg_wdata[15:0]; - assign configopts_csnidle_0_wd = reg_wdata[19:16]; + assign configopts_csnidle_wd = reg_wdata[19:16]; - assign configopts_csntrail_0_wd = reg_wdata[23:20]; + assign configopts_csntrail_wd = reg_wdata[23:20]; - assign configopts_csnlead_0_wd = reg_wdata[27:24]; + assign configopts_csnlead_wd = reg_wdata[27:24]; - assign configopts_fullcyc_0_wd = reg_wdata[29]; + assign configopts_fullcyc_wd = reg_wdata[29]; - assign configopts_cpha_0_wd = reg_wdata[30]; + assign configopts_cpha_wd = reg_wdata[30]; - assign configopts_cpol_0_wd = reg_wdata[31]; + assign configopts_cpol_wd = reg_wdata[31]; assign csid_we = addr_hit[7] & reg_we & !reg_error; assign csid_wd = reg_wdata[31:0]; @@ -1910,13 +1909,13 @@ module spi_host_reg_top ( end addr_hit[6]: begin - reg_rdata_next[15:0] = configopts_clkdiv_0_qs; - reg_rdata_next[19:16] = configopts_csnidle_0_qs; - reg_rdata_next[23:20] = configopts_csntrail_0_qs; - reg_rdata_next[27:24] = configopts_csnlead_0_qs; - reg_rdata_next[29] = configopts_fullcyc_0_qs; - reg_rdata_next[30] = configopts_cpha_0_qs; - reg_rdata_next[31] = configopts_cpol_0_qs; + reg_rdata_next[15:0] = configopts_clkdiv_qs; + reg_rdata_next[19:16] = configopts_csnidle_qs; + reg_rdata_next[23:20] = configopts_csntrail_qs; + reg_rdata_next[27:24] = configopts_csnlead_qs; + reg_rdata_next[29] = configopts_fullcyc_qs; + reg_rdata_next[30] = configopts_cpha_qs; + reg_rdata_next[31] = configopts_cpol_qs; end addr_hit[7]: begin diff --git a/sw/device/lib/dif/dif_spi_host.c b/sw/device/lib/dif/dif_spi_host.c index e741f978705ed..dabebd3739450 100644 --- a/sw/device/lib/dif/dif_spi_host.c +++ b/sw/device/lib/dif/dif_spi_host.c @@ -77,24 +77,23 @@ dif_result_t dif_spi_host_configure(const dif_spi_host_t *spi_host, uint32_t divider = ((config.peripheral_clock_freq_hz / config.spi_clock) / 2) - 1; - if (divider & ~(uint32_t)SPI_HOST_CONFIGOPTS_CLKDIV_0_MASK) { + if (divider & ~(uint32_t)SPI_HOST_CONFIGOPTS_CLKDIV_MASK) { return kDifBadArg; } spi_host_reset(spi_host); uint32_t reg = 0; - reg = - bitfield_field32_write(reg, SPI_HOST_CONFIGOPTS_CLKDIV_0_FIELD, divider); - reg = bitfield_field32_write(reg, SPI_HOST_CONFIGOPTS_CSNIDLE_0_FIELD, + reg = bitfield_field32_write(reg, SPI_HOST_CONFIGOPTS_CLKDIV_FIELD, divider); + reg = bitfield_field32_write(reg, SPI_HOST_CONFIGOPTS_CSNIDLE_FIELD, config.chip_select.idle); - reg = bitfield_field32_write(reg, SPI_HOST_CONFIGOPTS_CSNTRAIL_0_FIELD, + reg = bitfield_field32_write(reg, SPI_HOST_CONFIGOPTS_CSNTRAIL_FIELD, config.chip_select.trail); - reg = bitfield_field32_write(reg, SPI_HOST_CONFIGOPTS_CSNLEAD_0_FIELD, + reg = bitfield_field32_write(reg, SPI_HOST_CONFIGOPTS_CSNLEAD_FIELD, config.chip_select.lead); - reg = bitfield_bit32_write(reg, SPI_HOST_CONFIGOPTS_FULLCYC_0_BIT, + reg = bitfield_bit32_write(reg, SPI_HOST_CONFIGOPTS_FULLCYC_BIT, config.full_cycle); - reg = bitfield_bit32_write(reg, SPI_HOST_CONFIGOPTS_CPHA_0_BIT, config.cpha); - reg = bitfield_bit32_write(reg, SPI_HOST_CONFIGOPTS_CPOL_0_BIT, config.cpol); + reg = bitfield_bit32_write(reg, SPI_HOST_CONFIGOPTS_CPHA_BIT, config.cpha); + reg = bitfield_bit32_write(reg, SPI_HOST_CONFIGOPTS_CPOL_BIT, config.cpol); mmio_region_write32(spi_host->base_addr, SPI_HOST_CONFIGOPTS_REG_OFFSET, reg); reg = mmio_region_read32(spi_host->base_addr, SPI_HOST_CONTROL_REG_OFFSET); diff --git a/sw/device/lib/dif/dif_spi_host_unittest.cc b/sw/device/lib/dif/dif_spi_host_unittest.cc index 587fc9d78a81f..da85ddb7800b4 100644 --- a/sw/device/lib/dif/dif_spi_host_unittest.cc +++ b/sw/device/lib/dif/dif_spi_host_unittest.cc @@ -130,13 +130,13 @@ TEST_F(ConfigTest, Default) { ExpectDeviceReset(); EXPECT_WRITE32(SPI_HOST_CONFIGOPTS_REG_OFFSET, { - {SPI_HOST_CONFIGOPTS_CLKDIV_0_OFFSET, 0}, - {SPI_HOST_CONFIGOPTS_CSNIDLE_0_OFFSET, 0}, - {SPI_HOST_CONFIGOPTS_CSNTRAIL_0_OFFSET, 0}, - {SPI_HOST_CONFIGOPTS_CSNLEAD_0_OFFSET, 0}, - {SPI_HOST_CONFIGOPTS_FULLCYC_0_BIT, false}, - {SPI_HOST_CONFIGOPTS_CPHA_0_BIT, false}, - {SPI_HOST_CONFIGOPTS_CPOL_0_BIT, false}, + {SPI_HOST_CONFIGOPTS_CLKDIV_OFFSET, 0}, + {SPI_HOST_CONFIGOPTS_CSNIDLE_OFFSET, 0}, + {SPI_HOST_CONFIGOPTS_CSNTRAIL_OFFSET, 0}, + {SPI_HOST_CONFIGOPTS_CSNLEAD_OFFSET, 0}, + {SPI_HOST_CONFIGOPTS_FULLCYC_BIT, false}, + {SPI_HOST_CONFIGOPTS_CPHA_BIT, false}, + {SPI_HOST_CONFIGOPTS_CPOL_BIT, false}, }); EXPECT_READ32(SPI_HOST_CONTROL_REG_OFFSET, 0); @@ -172,13 +172,13 @@ TEST_F(ConfigTest, ClockRate) { ExpectDeviceReset(); EXPECT_WRITE32(SPI_HOST_CONFIGOPTS_REG_OFFSET, { - {SPI_HOST_CONFIGOPTS_CLKDIV_0_OFFSET, 0}, - {SPI_HOST_CONFIGOPTS_CSNIDLE_0_OFFSET, 0}, - {SPI_HOST_CONFIGOPTS_CSNTRAIL_0_OFFSET, 0}, - {SPI_HOST_CONFIGOPTS_CSNLEAD_0_OFFSET, 0}, - {SPI_HOST_CONFIGOPTS_FULLCYC_0_BIT, false}, - {SPI_HOST_CONFIGOPTS_CPHA_0_BIT, false}, - {SPI_HOST_CONFIGOPTS_CPOL_0_BIT, false}, + {SPI_HOST_CONFIGOPTS_CLKDIV_OFFSET, 0}, + {SPI_HOST_CONFIGOPTS_CSNIDLE_OFFSET, 0}, + {SPI_HOST_CONFIGOPTS_CSNTRAIL_OFFSET, 0}, + {SPI_HOST_CONFIGOPTS_CSNLEAD_OFFSET, 0}, + {SPI_HOST_CONFIGOPTS_FULLCYC_BIT, false}, + {SPI_HOST_CONFIGOPTS_CPHA_BIT, false}, + {SPI_HOST_CONFIGOPTS_CPOL_BIT, false}, }); EXPECT_READ32(SPI_HOST_CONTROL_REG_OFFSET, 0); EXPECT_WRITE32(SPI_HOST_CONTROL_REG_OFFSET, 0); @@ -201,13 +201,13 @@ TEST_F(ConfigTest, ChipSelectOptions) { ExpectDeviceReset(); EXPECT_WRITE32(SPI_HOST_CONFIGOPTS_REG_OFFSET, { - {SPI_HOST_CONFIGOPTS_CLKDIV_0_OFFSET, 0}, - {SPI_HOST_CONFIGOPTS_CSNIDLE_0_OFFSET, 1}, - {SPI_HOST_CONFIGOPTS_CSNTRAIL_0_OFFSET, 2}, - {SPI_HOST_CONFIGOPTS_CSNLEAD_0_OFFSET, 3}, - {SPI_HOST_CONFIGOPTS_FULLCYC_0_BIT, false}, - {SPI_HOST_CONFIGOPTS_CPHA_0_BIT, false}, - {SPI_HOST_CONFIGOPTS_CPOL_0_BIT, false}, + {SPI_HOST_CONFIGOPTS_CLKDIV_OFFSET, 0}, + {SPI_HOST_CONFIGOPTS_CSNIDLE_OFFSET, 1}, + {SPI_HOST_CONFIGOPTS_CSNTRAIL_OFFSET, 2}, + {SPI_HOST_CONFIGOPTS_CSNLEAD_OFFSET, 3}, + {SPI_HOST_CONFIGOPTS_FULLCYC_BIT, false}, + {SPI_HOST_CONFIGOPTS_CPHA_BIT, false}, + {SPI_HOST_CONFIGOPTS_CPOL_BIT, false}, }); EXPECT_READ32(SPI_HOST_CONTROL_REG_OFFSET, 0); EXPECT_WRITE32(SPI_HOST_CONTROL_REG_OFFSET, 0); @@ -230,13 +230,13 @@ TEST_F(ConfigTest, SpiOptions) { ExpectDeviceReset(); EXPECT_WRITE32(SPI_HOST_CONFIGOPTS_REG_OFFSET, { - {SPI_HOST_CONFIGOPTS_CLKDIV_0_OFFSET, 0}, - {SPI_HOST_CONFIGOPTS_CSNIDLE_0_OFFSET, 0}, - {SPI_HOST_CONFIGOPTS_CSNTRAIL_0_OFFSET, 0}, - {SPI_HOST_CONFIGOPTS_CSNLEAD_0_OFFSET, 0}, - {SPI_HOST_CONFIGOPTS_FULLCYC_0_BIT, true}, - {SPI_HOST_CONFIGOPTS_CPHA_0_BIT, true}, - {SPI_HOST_CONFIGOPTS_CPOL_0_BIT, true}, + {SPI_HOST_CONFIGOPTS_CLKDIV_OFFSET, 0}, + {SPI_HOST_CONFIGOPTS_CSNIDLE_OFFSET, 0}, + {SPI_HOST_CONFIGOPTS_CSNTRAIL_OFFSET, 0}, + {SPI_HOST_CONFIGOPTS_CSNLEAD_OFFSET, 0}, + {SPI_HOST_CONFIGOPTS_FULLCYC_BIT, true}, + {SPI_HOST_CONFIGOPTS_CPHA_BIT, true}, + {SPI_HOST_CONFIGOPTS_CPOL_BIT, true}, }); EXPECT_READ32(SPI_HOST_CONTROL_REG_OFFSET, 0); EXPECT_WRITE32(SPI_HOST_CONTROL_REG_OFFSET, 0); @@ -257,13 +257,13 @@ TEST_F(ConfigTest, SpiTxRxWatermark) { ExpectDeviceReset(); EXPECT_WRITE32(SPI_HOST_CONFIGOPTS_REG_OFFSET, { - {SPI_HOST_CONFIGOPTS_CLKDIV_0_OFFSET, 0}, - {SPI_HOST_CONFIGOPTS_CSNIDLE_0_OFFSET, 0}, - {SPI_HOST_CONFIGOPTS_CSNTRAIL_0_OFFSET, 0}, - {SPI_HOST_CONFIGOPTS_CSNLEAD_0_OFFSET, 0}, - {SPI_HOST_CONFIGOPTS_FULLCYC_0_BIT, false}, - {SPI_HOST_CONFIGOPTS_CPHA_0_BIT, false}, - {SPI_HOST_CONFIGOPTS_CPOL_0_BIT, false}, + {SPI_HOST_CONFIGOPTS_CLKDIV_OFFSET, 0}, + {SPI_HOST_CONFIGOPTS_CSNIDLE_OFFSET, 0}, + {SPI_HOST_CONFIGOPTS_CSNTRAIL_OFFSET, 0}, + {SPI_HOST_CONFIGOPTS_CSNLEAD_OFFSET, 0}, + {SPI_HOST_CONFIGOPTS_FULLCYC_BIT, false}, + {SPI_HOST_CONFIGOPTS_CPHA_BIT, false}, + {SPI_HOST_CONFIGOPTS_CPOL_BIT, false}, }); EXPECT_READ32(SPI_HOST_CONTROL_REG_OFFSET, 0); EXPECT_WRITE32(SPI_HOST_CONTROL_REG_OFFSET,