Skip to content

Commit

Permalink
[hw,dma,rtl] Ability to swap the endianess of 32-byte digest words
Browse files Browse the repository at this point in the history
Signed-off-by: Robert Schilling <[email protected]>
  • Loading branch information
Razer6 committed Feb 20, 2025
1 parent 60640d2 commit 91ee942
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 29 deletions.
9 changes: 9 additions & 0 deletions hw/ip/dma/data/dma.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,15 @@
No explicit clearing necessary.
'''
}
{ bits: "5"
name: "digest_swap"
resval: 0x0
desc: '''Digest register byte swap.

If 1 the value in each digest output register is converted to big-endian byte order.
This setting does not affect the order of the digest output registers, !!SHA2_DIGEST_0 still contains the first 4 bytes of the digest.
'''
}
{ bits: "8"
name: "initial_transfer"
resval: 0x0
Expand Down
13 changes: 10 additions & 3 deletions hw/ip/dma/doc/registers.md
Original file line number Diff line number Diff line change
Expand Up @@ -458,12 +458,12 @@ Other values are reserved.
Control register for DMA data movement.
- Offset: `0x44`
- Reset default: `0x0`
- Reset mask: `0x8800011f`
- Reset mask: `0x8800013f`

### Fields

```wavejson
{"reg": [{"name": "opcode", "bits": 4, "attr": ["rw"], "rotate": 0}, {"name": "hardware_handshake_enable", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 3}, {"name": "initial_transfer", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 18}, {"name": "abort", "bits": 1, "attr": ["wo"], "rotate": -90}, {"bits": 3}, {"name": "go", "bits": 1, "attr": ["rw"], "rotate": -90}], "config": {"lanes": 1, "fontsize": 10, "vspace": 270}}
{"reg": [{"name": "opcode", "bits": 4, "attr": ["rw"], "rotate": 0}, {"name": "hardware_handshake_enable", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "digest_swap", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 2}, {"name": "initial_transfer", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 18}, {"name": "abort", "bits": 1, "attr": ["wo"], "rotate": -90}, {"bits": 3}, {"name": "go", "bits": 1, "attr": ["rw"], "rotate": -90}], "config": {"lanes": 1, "fontsize": 10, "vspace": 270}}
```

| Bits | Type | Reset | Name |
Expand All @@ -473,7 +473,8 @@ Control register for DMA data movement.
| 27 | wo | 0x0 | [abort](#control--abort) |
| 26:9 | | | Reserved |
| 8 | rw | 0x0 | [initial_transfer](#control--initial_transfer) |
| 7:5 | | | Reserved |
| 7:6 | | | Reserved |
| 5 | rw | 0x0 | [digest_swap](#control--digest_swap) |
| 4 | rw | 0x0 | [hardware_handshake_enable](#control--hardware_handshake_enable) |
| 3:0 | rw | 0x0 | [opcode](#control--opcode) |

Expand All @@ -493,6 +494,12 @@ Marks the initial transfer to initialize the DMA and SHA engine for one transfer
Used for hardware handshake and ordinary transfers, in which multiple transfers contribute to a final digest.
Note, for non-handshake transfers with inline hashing mode enabled, this bit must be set to also mark the first transfer.

### CONTROL . digest_swap
Digest register byte swap.

If 1 the value in each digest output register is converted to big-endian byte order.
This setting does not affect the order of the digest output registers, [`SHA2_DIGEST_0`](#sha2_digest_0) still contains the first 4 bytes of the digest.

### CONTROL . hardware_handshake_enable
Enable hardware handshake mode.
Used to clear FIFOs from low speed IO peripherals receiving data, e.g., I3C receive buffer.
Expand Down
16 changes: 11 additions & 5 deletions hw/ip/dma/rtl/dma.sv
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ module dma
always_comb begin
control_d.opcode = opcode_e'(reg2hw.control.opcode.q);
control_d.cfg_handshake_en = reg2hw.control.hardware_handshake_enable.q;
control_d.cfg_digest_swap = reg2hw.control.digest_swap.q;
control_d.range_valid = reg2hw.range_valid.q;
control_d.enabled_memory_range_base = reg2hw.enabled_memory_range_base.q;
control_d.enabled_memory_range_limit = reg2hw.enabled_memory_range_limit.q;
Expand Down Expand Up @@ -1254,17 +1255,22 @@ module dma
for (int unsigned i = 0; i < NR_SHA_DIGEST_ELEMENTS / 2; i++) begin
unique case (control_q.opcode)
OpcSha256: begin
hw2reg.sha2_digest[i].d = sha2_digest[i][0 +: 32];
hw2reg.sha2_digest[i].d = conv_endian32(sha2_digest[i][0 +: 32],
control_q.cfg_digest_swap);
end
OpcSha384: begin
if (i < 6) begin
hw2reg.sha2_digest[i*2].d = sha2_digest[i][32 +: 32];
hw2reg.sha2_digest[(i*2)+1].d = sha2_digest[i][0 +: 32];
hw2reg.sha2_digest[i*2].d = conv_endian32(sha2_digest[i][32 +: 32],
control_q.cfg_digest_swap);
hw2reg.sha2_digest[(i*2)+1].d = conv_endian32(sha2_digest[i][0 +: 32],
control_q.cfg_digest_swap);
end
end
default: begin // SHA2-512
hw2reg.sha2_digest[i*2].d = sha2_digest[i][32 +: 32];
hw2reg.sha2_digest[(i*2)+1].d = sha2_digest[i][0 +: 32];
hw2reg.sha2_digest[i*2].d = conv_endian32(sha2_digest[i][32 +: 32],
control_q.cfg_digest_swap);
hw2reg.sha2_digest[(i*2)+1].d = conv_endian32(sha2_digest[i][0 +: 32],
control_q.cfg_digest_swap);
end
endcase
end
Expand Down
1 change: 1 addition & 0 deletions hw/ip/dma/rtl/dma_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ package dma_pkg;
// Control register
opcode_e opcode;
logic cfg_handshake_en;
logic cfg_digest_swap;
logic range_valid;
// Enabled memory base register
logic [31:0] enabled_memory_range_base;
Expand Down
37 changes: 20 additions & 17 deletions hw/ip/dma/rtl/dma_reg_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,9 @@ package dma_reg_pkg;
struct packed {
logic q;
} initial_transfer;
struct packed {
logic q;
} digest_swap;
struct packed {
logic q;
} hardware_handshake_enable;
Expand Down Expand Up @@ -319,23 +322,23 @@ package dma_reg_pkg;

// Register -> HW type
typedef struct packed {
dma_reg2hw_intr_state_reg_t intr_state; // [1043:1041]
dma_reg2hw_intr_enable_reg_t intr_enable; // [1040:1038]
dma_reg2hw_intr_test_reg_t intr_test; // [1037:1032]
dma_reg2hw_alert_test_reg_t alert_test; // [1031:1030]
dma_reg2hw_src_addr_lo_reg_t src_addr_lo; // [1029:998]
dma_reg2hw_src_addr_hi_reg_t src_addr_hi; // [997:966]
dma_reg2hw_dst_addr_lo_reg_t dst_addr_lo; // [965:934]
dma_reg2hw_dst_addr_hi_reg_t dst_addr_hi; // [933:902]
dma_reg2hw_addr_space_id_reg_t addr_space_id; // [901:894]
dma_reg2hw_enabled_memory_range_base_reg_t enabled_memory_range_base; // [893:861]
dma_reg2hw_enabled_memory_range_limit_reg_t enabled_memory_range_limit; // [860:828]
dma_reg2hw_range_valid_reg_t range_valid; // [827:827]
dma_reg2hw_range_regwen_reg_t range_regwen; // [826:823]
dma_reg2hw_total_data_size_reg_t total_data_size; // [822:791]
dma_reg2hw_chunk_data_size_reg_t chunk_data_size; // [790:759]
dma_reg2hw_transfer_width_reg_t transfer_width; // [758:757]
dma_reg2hw_control_reg_t control; // [756:748]
dma_reg2hw_intr_state_reg_t intr_state; // [1044:1042]
dma_reg2hw_intr_enable_reg_t intr_enable; // [1041:1039]
dma_reg2hw_intr_test_reg_t intr_test; // [1038:1033]
dma_reg2hw_alert_test_reg_t alert_test; // [1032:1031]
dma_reg2hw_src_addr_lo_reg_t src_addr_lo; // [1030:999]
dma_reg2hw_src_addr_hi_reg_t src_addr_hi; // [998:967]
dma_reg2hw_dst_addr_lo_reg_t dst_addr_lo; // [966:935]
dma_reg2hw_dst_addr_hi_reg_t dst_addr_hi; // [934:903]
dma_reg2hw_addr_space_id_reg_t addr_space_id; // [902:895]
dma_reg2hw_enabled_memory_range_base_reg_t enabled_memory_range_base; // [894:862]
dma_reg2hw_enabled_memory_range_limit_reg_t enabled_memory_range_limit; // [861:829]
dma_reg2hw_range_valid_reg_t range_valid; // [828:828]
dma_reg2hw_range_regwen_reg_t range_regwen; // [827:824]
dma_reg2hw_total_data_size_reg_t total_data_size; // [823:792]
dma_reg2hw_chunk_data_size_reg_t chunk_data_size; // [791:760]
dma_reg2hw_transfer_width_reg_t transfer_width; // [759:758]
dma_reg2hw_control_reg_t control; // [757:748]
dma_reg2hw_src_config_reg_t src_config; // [747:746]
dma_reg2hw_dst_config_reg_t dst_config; // [745:744]
dma_reg2hw_status_reg_t status; // [743:737]
Expand Down
40 changes: 36 additions & 4 deletions hw/ip/dma/rtl/dma_reg_top.sv
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,8 @@ module dma_reg_top (
logic [3:0] control_opcode_wd;
logic control_hardware_handshake_enable_qs;
logic control_hardware_handshake_enable_wd;
logic control_digest_swap_qs;
logic control_digest_swap_wd;
logic control_initial_transfer_qs;
logic control_initial_transfer_wd;
logic control_abort_wd;
Expand Down Expand Up @@ -1009,7 +1011,7 @@ module dma_reg_top (

// R[control]: V(False)
logic control_qe;
logic [4:0] control_flds_we;
logic [5:0] control_flds_we;
prim_flop #(
.Width(1),
.ResetValue(0)
Expand Down Expand Up @@ -1073,6 +1075,33 @@ module dma_reg_top (
.qs (control_hardware_handshake_enable_qs)
);

// F[digest_swap]: 5:5
prim_subreg #(
.DW (1),
.SwAccess(prim_subreg_pkg::SwAccessRW),
.RESVAL (1'h0),
.Mubi (1'b0)
) u_control_digest_swap (
.clk_i (clk_i),
.rst_ni (rst_ni),

// from register interface
.we (control_we),
.wd (control_digest_swap_wd),

// from internal hardware
.de (1'b0),
.d ('0),

// to internal hardware
.qe (control_flds_we[2]),
.q (reg2hw.control.digest_swap.q),
.ds (),

// to register interface (read)
.qs (control_digest_swap_qs)
);

// F[initial_transfer]: 8:8
prim_subreg #(
.DW (1),
Expand All @@ -1092,7 +1121,7 @@ module dma_reg_top (
.d (hw2reg.control.initial_transfer.d),

// to internal hardware
.qe (control_flds_we[2]),
.qe (control_flds_we[3]),
.q (reg2hw.control.initial_transfer.q),
.ds (),

Expand All @@ -1119,7 +1148,7 @@ module dma_reg_top (
.d (hw2reg.control.abort.d),

// to internal hardware
.qe (control_flds_we[3]),
.qe (control_flds_we[4]),
.q (reg2hw.control.abort.q),
.ds (),

Expand All @@ -1146,7 +1175,7 @@ module dma_reg_top (
.d (hw2reg.control.go.d),

// to internal hardware
.qe (control_flds_we[4]),
.qe (control_flds_we[5]),
.q (reg2hw.control.go.q),
.ds (),

Expand Down Expand Up @@ -3186,6 +3215,8 @@ module dma_reg_top (

assign control_hardware_handshake_enable_wd = reg_wdata[4];

assign control_digest_swap_wd = reg_wdata[5];

assign control_initial_transfer_wd = reg_wdata[8];

assign control_abort_wd = reg_wdata[27];
Expand Down Expand Up @@ -3436,6 +3467,7 @@ module dma_reg_top (
addr_hit[17]: begin
reg_rdata_next[3:0] = control_opcode_qs;
reg_rdata_next[4] = control_hardware_handshake_enable_qs;
reg_rdata_next[5] = control_digest_swap_qs;
reg_rdata_next[8] = control_initial_transfer_qs;
reg_rdata_next[27] = '0;
reg_rdata_next[31] = control_go_qs;
Expand Down

0 comments on commit 91ee942

Please sign in to comment.