Skip to content

Commit

Permalink
[hw,spi_host,rtl] Increase command length to 20-bit
Browse files Browse the repository at this point in the history
Currently the SPI host only supports a 9-bit command length, meaning a SPI
transaction can only transfer 512b. This especially problematic, for integrated
devices, where large FW blobs (>5MB) need to be fetched from the external SPI
flash. When using in conjunction with the DMA (hardware-handshake mode), only
a few chunks can be transferred before needing to re-program the SPI host and
DMA.

To overcome this problem, extend the command length to 20-bit.

Signed-off-by: Robert Schilling <[email protected]>
  • Loading branch information
Razer6 authored and andreaskurth committed Dec 20, 2024
1 parent 91944c5 commit b058bfe
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 100 deletions.
34 changes: 17 additions & 17 deletions hw/ip/spi_host/data/spi_host.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -419,20 +419,34 @@
hwext: "true",
hwqe: "true",
fields: [
{ bits: "13:12",
{ bits: "24:5",
name: "LEN",
desc: '''Segment Length.

For read or write segments, this field controls the
number of 1-byte bursts to transmit and or receive in
this command segment. The number of cyles required
to send or received a byte will depend on !!COMMAND.SPEED.
For dummy segments, (!!COMMAND.DIRECTION == 0), this register
controls the number of dummy cycles to issue.
The number of bytes (or dummy cycles) in the segment will be
equal to !!COMMAND.LEN + 1.''',
resval: "0x0"
},
{ bits: "4:3",
name: "DIRECTION",
desc: '''The direction for the following command: "0" = Dummy cycles
(no TX/RX). "1" = Rx only, "2" = Tx only, "3" = Bidirectional
Tx/Rx (Standard SPI mode only).'''
resval: "0x0"
}
{ bits: "11:10",
{ bits: "2:1",
name: "SPEED",
desc: '''The speed for this command segment: "0" = Standard SPI. "1" = Dual SPI.
"2"=Quad SPI, "3": RESERVED.''',
resval: "0x0"
},
{ bits: "9",
{ bits: "0",
name: "CSAAT",
desc: '''**C**hip **S**elect **A**ctive **A**fter **T**ransaction.
If !!COMMAND.CSAAT = 0, the chip select line is raised immediately
Expand All @@ -445,20 +459,6 @@
the device.''',
resval: "0x0"
},
{ bits: "8:0",
name: "LEN",
desc: '''Segment Length.

For read or write segments, this field controls the
number of 1-byte bursts to transmit and or receive in
this command segment. The number of cyles required
to send or received a byte will depend on !!COMMAND.SPEED.
For dummy segments, (!!COMMAND.DIRECTION == 0), this register
controls the number of dummy cycles to issue.
The number of bytes (or dummy cycles) in the segment will be
equal to !!COMMAND.LEN + 1.''',
resval: "0x0"
},
],
tags: [// Triggers exceptions if registers are improperly configured
// Exclude from RW tests
Expand Down
38 changes: 19 additions & 19 deletions hw/ip/spi_host/doc/registers.md
Original file line number Diff line number Diff line change
Expand Up @@ -276,21 +276,33 @@ Command Register
there is only one command register for controlling all attached SPI devices
- Offset: `0x20`
- Reset default: `0x0`
- Reset mask: `0x3fff`
- Reset mask: `0x1ffffff`

### Fields

```wavejson
{"reg": [{"name": "LEN", "bits": 9, "attr": ["wo"], "rotate": 0}, {"name": "CSAAT", "bits": 1, "attr": ["wo"], "rotate": -90}, {"name": "SPEED", "bits": 2, "attr": ["wo"], "rotate": -90}, {"name": "DIRECTION", "bits": 2, "attr": ["wo"], "rotate": -90}, {"bits": 18}], "config": {"lanes": 1, "fontsize": 10, "vspace": 110}}
{"reg": [{"name": "CSAAT", "bits": 1, "attr": ["wo"], "rotate": -90}, {"name": "SPEED", "bits": 2, "attr": ["wo"], "rotate": -90}, {"name": "DIRECTION", "bits": 2, "attr": ["wo"], "rotate": -90}, {"name": "LEN", "bits": 20, "attr": ["wo"], "rotate": 0}, {"bits": 7}], "config": {"lanes": 1, "fontsize": 10, "vspace": 110}}
```

| Bits | Type | Reset | Name |
|:------:|:------:|:-------:|:---------------------------------|
| 31:14 | | | Reserved |
| 13:12 | wo | 0x0 | [DIRECTION](#command--direction) |
| 11:10 | wo | 0x0 | [SPEED](#command--speed) |
| 9 | wo | 0x0 | [CSAAT](#command--csaat) |
| 8:0 | wo | 0x0 | [LEN](#command--len) |
| 31:25 | | | Reserved |
| 24:5 | wo | 0x0 | [LEN](#command--len) |
| 4:3 | wo | 0x0 | [DIRECTION](#command--direction) |
| 2:1 | wo | 0x0 | [SPEED](#command--speed) |
| 0 | wo | 0x0 | [CSAAT](#command--csaat) |

### COMMAND . LEN
Segment Length.

For read or write segments, this field controls the
number of 1-byte bursts to transmit and or receive in
this command segment. The number of cyles required
to send or received a byte will depend on [`COMMAND.SPEED.`](#command)
For dummy segments, ([`COMMAND.DIRECTION`](#command) == 0), this register
controls the number of dummy cycles to issue.
The number of bytes (or dummy cycles) in the segment will be
equal to [`COMMAND.LEN`](#command) + 1.

### COMMAND . DIRECTION
The direction for the following command: "0" = Dummy cycles
Expand All @@ -312,18 +324,6 @@ The speed for this command segment: "0" = Standard SPI. "1" = Dual SPI.
pausing for dummy cycles, and transmitting or receiving data from
the device.

### COMMAND . LEN
Segment Length.

For read or write segments, this field controls the
number of 1-byte bursts to transmit and or receive in
this command segment. The number of cyles required
to send or received a byte will depend on [`COMMAND.SPEED.`](#command)
For dummy segments, ([`COMMAND.DIRECTION`](#command) == 0), this register
controls the number of dummy cycles to issue.
The number of bytes (or dummy cycles) in the segment will be
equal to [`COMMAND.LEN`](#command) + 1.

## RXDATA
SPI Receive Data.

Expand Down
2 changes: 1 addition & 1 deletion hw/ip/spi_host/dv/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ All common types and methods defined at the package level can be found in
rand spi_mode_e mode;
rand spi_dir_e direction;
rand bit csaat;
rand bit [8:0] len;
rand bit [19:0] len;
} spi_host_command_t;
typedef struct packed {
Expand Down
2 changes: 1 addition & 1 deletion hw/ip/spi_host/dv/env/spi_host_env_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ package spi_host_env_pkg;
parameter uint SPI_HOST_RX_FIFO_END = (SPI_HOST_RX_FIFO_START - 1) +
spi_host_reg_pkg::SPI_HOST_RXDATA_SIZE;

parameter uint SPI_HOST_COMMAND_LEN_SIZE_BITS = 9;
parameter uint SPI_HOST_COMMAND_LEN_SIZE_BITS = 20;
// macro includes
`include "uvm_macros.svh"
`include "dv_macros.svh"
Expand Down
12 changes: 6 additions & 6 deletions hw/ip/spi_host/rtl/spi_host_cmd_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
package spi_host_cmd_pkg;

parameter int CSW = prim_util_pkg::vbits(spi_host_reg_pkg::NumCS);
parameter int CmdSize = CSW + 45;
parameter int CmdSize = CSW + 56;

// For decoding the direction register
typedef enum logic [1:0] {
Expand Down Expand Up @@ -37,11 +37,11 @@ package spi_host_cmd_pkg;
} configopts_t;

typedef struct packed {
logic [1:0] speed;
logic cmd_wr_en;
logic cmd_rd_en;
logic [8:0] len;
logic csaat;
logic [1:0] speed;
logic cmd_wr_en;
logic cmd_rd_en;
logic [19:0] len;
logic csaat;
} segment_t;

typedef struct packed {
Expand Down
20 changes: 10 additions & 10 deletions hw/ip/spi_host/rtl/spi_host_fsm.sv
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,13 @@ module spi_host_fsm
logic [1:0] cmd_speed_d, cmd_speed_q;
logic cmd_wr_en_d, cmd_wr_en_q;
logic cmd_rd_en_d, cmd_rd_en_q;
logic [8:0] cmd_len_d, cmd_len_q;
logic [19:0] cmd_len_d, cmd_len_q;
logic csaat;
logic csaat_q;

logic [2:0] bit_cntr_d, bit_cntr_q;
logic [8:0] byte_cntr_cpha0_d, byte_cntr_cpha1_d, byte_cntr_cpha0_q, byte_cntr_cpha1_q;
logic [8:0] byte_cntr_early, byte_cntr_late;
logic [19:0] byte_cntr_cpha0_d, byte_cntr_cpha1_d, byte_cntr_cpha0_q, byte_cntr_cpha1_q;
logic [19:0] byte_cntr_early, byte_cntr_late;
logic [3:0] wait_cntr_d, wait_cntr_q;
logic last_bit, last_byte;

Expand Down Expand Up @@ -157,7 +157,7 @@ module spi_host_fsm
cmd_rd_en_q <= 1'b0;
cmd_wr_en_q <= 1'b0;
cmd_speed_q <= 2'b00;
cmd_len_q <= 9'h0;
cmd_len_q <= 20'h0;
end else begin
csid_q <= (new_command && !stall) ? csid : csid_q;
cpol_q <= (new_command && !stall) ? cpol : cpol_q;
Expand Down Expand Up @@ -442,21 +442,21 @@ module spi_host_fsm
//
always_comb begin
if (cpha_q) begin
last_byte = (byte_cntr_cpha1_q == 9'h0);
last_byte = (byte_cntr_cpha1_q == 20'h0);
end else begin
last_byte = (byte_cntr_cpha0_q == 9'h0);
last_byte = (byte_cntr_cpha0_q == 20'h0);
end
end

// Note: when updating the byte_cntr in CPHA=0 mode with a new command value, the length must
// be pulled in directly from the command bus, cmd_len_d;
assign byte_cntr_cpha0_d = sw_rst_i ? 9'h0 :
assign byte_cntr_cpha0_d = sw_rst_i ? 20'h0 :
!fsm_en ? byte_cntr_cpha0_q :
new_command ? cmd_len_d :
byte_ending_cpha0 ? byte_cntr_cpha0_q - 1 :
byte_cntr_cpha0_q;

assign byte_cntr_cpha1_d = sw_rst_i ? 9'h0 :
assign byte_cntr_cpha1_d = sw_rst_i ? 20'h0 :
!fsm_en ? byte_cntr_cpha1_q :
new_command ? cmd_len_d :
byte_ending_cpha1 ? byte_cntr_cpha1_q - 1 :
Expand Down Expand Up @@ -497,8 +497,8 @@ module spi_host_fsm
always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin
bit_cntr_q <= 3'h0;
byte_cntr_cpha0_q <= 9'h0;
byte_cntr_cpha1_q <= 9'h0;
byte_cntr_cpha0_q <= 20'h0;
byte_cntr_cpha1_q <= 20'h0;
wait_cntr_q <= 4'h0;
end else begin
bit_cntr_q <= stall ? bit_cntr_q : bit_cntr_d;
Expand Down
30 changes: 15 additions & 15 deletions hw/ip/spi_host/rtl/spi_host_reg_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ package spi_host_reg_pkg;
} spi_host_reg2hw_csid_reg_t;

typedef struct packed {
struct packed {
logic [19:0] q;
logic qe;
} len;
struct packed {
logic [1:0] q;
logic qe;
Expand All @@ -114,10 +118,6 @@ package spi_host_reg_pkg;
logic q;
logic qe;
} csaat;
struct packed {
logic [8:0] q;
logic qe;
} len;
} spi_host_reg2hw_command_reg_t;

typedef struct packed {
Expand Down Expand Up @@ -279,14 +279,14 @@ package spi_host_reg_pkg;

// Register -> HW type
typedef struct packed {
spi_host_reg2hw_intr_state_reg_t intr_state; // [126:125]
spi_host_reg2hw_intr_enable_reg_t intr_enable; // [124:123]
spi_host_reg2hw_intr_test_reg_t intr_test; // [122:119]
spi_host_reg2hw_alert_test_reg_t alert_test; // [118:117]
spi_host_reg2hw_control_reg_t control; // [116:98]
spi_host_reg2hw_configopts_mreg_t [0:0] configopts; // [97:67]
spi_host_reg2hw_csid_reg_t csid; // [66:35]
spi_host_reg2hw_command_reg_t command; // [34:17]
spi_host_reg2hw_intr_state_reg_t intr_state; // [137:136]
spi_host_reg2hw_intr_enable_reg_t intr_enable; // [135:134]
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_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]
spi_host_reg2hw_error_status_reg_t error_status; // [11:6]
spi_host_reg2hw_event_enable_reg_t event_enable; // [5:0]
Expand Down Expand Up @@ -319,11 +319,11 @@ package spi_host_reg_pkg;
parameter logic [0:0] SPI_HOST_INTR_TEST_SPI_EVENT_RESVAL = 1'h 0;
parameter logic [0:0] SPI_HOST_ALERT_TEST_RESVAL = 1'h 0;
parameter logic [0:0] SPI_HOST_ALERT_TEST_FATAL_FAULT_RESVAL = 1'h 0;
parameter logic [13:0] SPI_HOST_COMMAND_RESVAL = 14'h 0;
parameter logic [8:0] SPI_HOST_COMMAND_LEN_RESVAL = 9'h 0;
parameter logic [24:0] SPI_HOST_COMMAND_RESVAL = 25'h 0;
parameter logic [0:0] SPI_HOST_COMMAND_CSAAT_RESVAL = 1'h 0;
parameter logic [1:0] SPI_HOST_COMMAND_SPEED_RESVAL = 2'h 0;
parameter logic [1:0] SPI_HOST_COMMAND_DIRECTION_RESVAL = 2'h 0;
parameter logic [19:0] SPI_HOST_COMMAND_LEN_RESVAL = 20'h 0;

// Window parameters
parameter logic [BlockAw-1:0] SPI_HOST_RXDATA_OFFSET = 6'h 24;
Expand Down Expand Up @@ -359,7 +359,7 @@ package spi_host_reg_pkg;
4'b 1111, // index[ 5] SPI_HOST_STATUS
4'b 1111, // index[ 6] SPI_HOST_CONFIGOPTS
4'b 1111, // index[ 7] SPI_HOST_CSID
4'b 0011, // index[ 8] SPI_HOST_COMMAND
4'b 1111, // index[ 8] SPI_HOST_COMMAND
4'b 0001, // index[ 9] SPI_HOST_ERROR_ENABLE
4'b 0001, // index[10] SPI_HOST_ERROR_STATUS
4'b 0001 // index[11] SPI_HOST_EVENT_ENABLE
Expand Down
Loading

0 comments on commit b058bfe

Please sign in to comment.