Skip to content

Commit

Permalink
[hw,dma,rtl] Add a chunk done interrupt
Browse files Browse the repository at this point in the history
Signed-off-by: Robert Schilling <[email protected]>
  • Loading branch information
Razer6 committed Nov 5, 2024
1 parent 707e55b commit 4602495
Show file tree
Hide file tree
Showing 9 changed files with 162 additions and 24 deletions.
3 changes: 3 additions & 0 deletions hw/ip/dma/data/dma.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@
desc: "DMA operation has been completed."
type: "status"
}
{ name: "dma_chunk_done"
desc: "Indicated the transfer of a single chunk has been completed."
}
{ name: "dma_error"
desc: "DMA error has occurred. DMA_STATUS.error_code register shows the details."
type: "status"
Expand Down
4 changes: 3 additions & 1 deletion hw/ip/dma/dv/env/dma_env_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,13 @@ package dma_env_pkg;

// Index of interrupt in intf_vif
parameter uint DMA_DONE = 0;
parameter uint DMA_ERROR = 1;
parameter uint DMA_CHUNK_DONE = 1;
parameter uint DMA_ERROR = 2;

// Completion status bits (DV-internal)
typedef enum {
StatusDone,
StatusChunkDone,
StatusError,
StatusAborted,
StatusTimeout
Expand Down
7 changes: 4 additions & 3 deletions hw/ip/dma/dv/env/dma_scoreboard.sv
Original file line number Diff line number Diff line change
Expand Up @@ -605,9 +605,10 @@ class dma_scoreboard extends cip_base_scoreboard #(
if (curr_intr[i] !== exp_intr[i]) begin
// Collect a list of the mismatched interrupts
unique case (i)
DMA_DONE: rsn = {rsn, "Done "};
DMA_ERROR: rsn = {rsn, "Error "};
default: rsn = {rsn, "Unknown intr"};
DMA_DONE: rsn = {rsn, "Done "};
DMA_CHUNK_DONE: rsn = {rsn, "Done "};
DMA_ERROR: rsn = {rsn, "Error "};
default: rsn = {rsn, "Unknown intr"};
endcase
end
end
Expand Down
17 changes: 13 additions & 4 deletions hw/ip/dma/dv/env/seq_lib/dma_base_vseq.sv
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,13 @@ class dma_base_vseq extends cip_base_vseq #(
csr_update(.csr(ral.status));
endtask : clear_done

// Clear 'STATUS.chunk_done' field after a chunk transfer has completed.
task clear_chunk_done();
`uvm_info(`gfn, "DMA: Clear STATUS.chunk_done", UVM_HIGH)
ral.status.chunk_done.set(1'b1);
csr_update(.csr(ral.status));
endtask : clear_chunk_done

// Task: Abort the current transaction
task abort();
uvm_reg_data_t data = 0;
Expand Down Expand Up @@ -717,8 +724,9 @@ class dma_base_vseq extends cip_base_vseq #(
if (intr_driven) begin
forever begin
delay(1);
if (cfg.intr_vif.pins[DMA_DONE]) status[StatusDone] = 1'b1;
if (cfg.intr_vif.pins[DMA_ERROR]) status[StatusError] = 1'b1;
if (cfg.intr_vif.pins[DMA_DONE]) status[StatusDone] = 1'b1;
if (cfg.intr_vif.pins[DMA_CHUNK_DONE]) status[StatusChunkDone] = 1'b1;
if (cfg.intr_vif.pins[DMA_ERROR]) status[StatusError] = 1'b1;
end
end else begin
// Rely upon the CSR reading in `poll_status` to detect completion.
Expand All @@ -739,8 +747,9 @@ class dma_base_vseq extends cip_base_vseq #(
// Respond to the STATUS.done and STATUS.error bits only if we're not insisting upon
// interrupt-driven completion.
if (!intr_driven) begin
if (v[1]) status[StatusDone] = 1'b1;
if (v[3]) status[StatusError] = 1'b1;
if (v[1]) status[StatusDone] = 1'b1;
if (v[3]) status[StatusError] = 1'b1;
if (v[5]) status[StatusChunkDone] = 1'b1;
end
// Note: sha2_digest_valid is not a completion event
// v[12]
Expand Down
6 changes: 6 additions & 0 deletions hw/ip/dma/dv/env/seq_lib/dma_generic_vseq.sv
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,12 @@ class dma_generic_vseq extends dma_base_vseq;
clear_done();
status[StatusDone] = 1'b0;
end
if (status[StatusChunkDone]) begin
// Clear STATUS.chunk_done bit and then clear the interrupt, if enabled.
clear_chunk_done();
clear_interrupts(1 << DMA_CHUNK_DONE);
status[StatusChunkDone] = 1'b0;
end
if (status[StatusError]) begin
// Clear STATUS.error condition and associcated interrupt.
clear_errors(dma_config);
Expand Down
1 change: 1 addition & 0 deletions hw/ip/dma/dv/tb/tb.sv
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ module tb;
.scanmode_i (prim_mubi_pkg::MuBi4False),
.lsio_trigger_i (handshake_i),
.intr_dma_done_o (interrupts[DMA_DONE]),
.intr_dma_chunk_done_o (interrupts[DMA_CHUNK_DONE]),
.intr_dma_error_o (interrupts[DMA_ERROR]),
.alert_rx_i (alert_rx),
.alert_tx_o (alert_tx),
Expand Down
17 changes: 16 additions & 1 deletion hw/ip/dma/rtl/dma.sv
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ module dma
input prim_mubi_pkg::mubi4_t scanmode_i,
// DMA interrupts and incoming LSIO triggers
output logic intr_dma_done_o,
output logic intr_dma_chunk_done_o,
output logic intr_dma_error_o,
input lsio_trigger_t lsio_trigger_i,
// Alerts
Expand Down Expand Up @@ -1094,6 +1095,21 @@ module dma
.intr_o ( intr_dma_done_o )
);

prim_intr_hw #(
.IntrT ( "Status" )
) u_intr_chunk_dma_done (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.event_intr_i ( reg2hw.intr_state.dma_chunk_done.q ),
.reg2hw_intr_enable_q_i ( reg2hw.intr_enable.dma_chunk_done.q ),
.reg2hw_intr_test_q_i ( reg2hw.intr_test.dma_chunk_done.q ),
.reg2hw_intr_test_qe_i ( reg2hw.intr_test.dma_chunk_done.qe ),
.reg2hw_intr_state_q_i ( reg2hw.intr_state.dma_chunk_done.q ),
.hw2reg_intr_state_de_o ( hw2reg.intr_state.dma_chunk_done.de ),
.hw2reg_intr_state_d_o ( hw2reg.intr_state.dma_chunk_done.d ),
.intr_o ( intr_dma_chunk_done_o )
);

prim_intr_hw #(
.IntrT ( "Status" )
) u_intr_error (
Expand All @@ -1112,7 +1128,6 @@ module dma
logic data_move_state;
logic update_dst_addr_reg, update_src_addr_reg;


assign data_move_state = (ctrl_state_q == DmaSendWrite) ||
(ctrl_state_q == DmaWaitWriteResponse) ||
(ctrl_state_q == DmaShaWait) ||
Expand Down
25 changes: 20 additions & 5 deletions hw/ip/dma/rtl/dma_reg_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ package dma_reg_pkg;
struct packed {
logic q;
} dma_error;
struct packed {
logic q;
} dma_chunk_done;
struct packed {
logic q;
} dma_done;
Expand All @@ -30,6 +33,9 @@ package dma_reg_pkg;
struct packed {
logic q;
} dma_error;
struct packed {
logic q;
} dma_chunk_done;
struct packed {
logic q;
} dma_done;
Expand All @@ -40,6 +46,10 @@ package dma_reg_pkg;
logic q;
logic qe;
} dma_error;
struct packed {
logic q;
logic qe;
} dma_chunk_done;
struct packed {
logic q;
logic qe;
Expand Down Expand Up @@ -179,6 +189,10 @@ package dma_reg_pkg;
logic d;
logic de;
} dma_done;
struct packed {
logic d;
logic de;
} dma_chunk_done;
struct packed {
logic d;
logic de;
Expand Down Expand Up @@ -293,9 +307,9 @@ package dma_reg_pkg;

// Register -> HW type
typedef struct packed {
dma_reg2hw_intr_state_reg_t intr_state; // [1038:1037]
dma_reg2hw_intr_enable_reg_t intr_enable; // [1036:1035]
dma_reg2hw_intr_test_reg_t intr_test; // [1034:1031]
dma_reg2hw_intr_state_reg_t intr_state; // [1042:1040]
dma_reg2hw_intr_enable_reg_t intr_enable; // [1039:1037]
dma_reg2hw_intr_test_reg_t intr_test; // [1036:1031]
dma_reg2hw_alert_test_reg_t alert_test; // [1030:1029]
dma_reg2hw_src_addr_lo_reg_t src_addr_lo; // [1028:997]
dma_reg2hw_src_addr_hi_reg_t src_addr_hi; // [996:965]
Expand All @@ -320,7 +334,7 @@ package dma_reg_pkg;

// HW -> register type
typedef struct packed {
dma_hw2reg_intr_state_reg_t intr_state; // [701:698]
dma_hw2reg_intr_state_reg_t intr_state; // [703:698]
dma_hw2reg_src_addr_lo_reg_t src_addr_lo; // [697:665]
dma_hw2reg_src_addr_hi_reg_t src_addr_hi; // [664:632]
dma_hw2reg_dst_addr_lo_reg_t dst_addr_lo; // [631:599]
Expand Down Expand Up @@ -396,8 +410,9 @@ package dma_reg_pkg;
parameter logic [BlockAw-1:0] DMA_INTR_SRC_WR_VAL_10_OFFSET = 9'h 144;

// Reset values for hwext registers and their fields
parameter logic [1:0] DMA_INTR_TEST_RESVAL = 2'h 0;
parameter logic [2:0] DMA_INTR_TEST_RESVAL = 3'h 0;
parameter logic [0:0] DMA_INTR_TEST_DMA_DONE_RESVAL = 1'h 0;
parameter logic [0:0] DMA_INTR_TEST_DMA_CHUNK_DONE_RESVAL = 1'h 0;
parameter logic [0:0] DMA_INTR_TEST_DMA_ERROR_RESVAL = 1'h 0;
parameter logic [0:0] DMA_ALERT_TEST_RESVAL = 1'h 0;
parameter logic [0:0] DMA_ALERT_TEST_FATAL_FAULT_RESVAL = 1'h 0;
Expand Down
Loading

0 comments on commit 4602495

Please sign in to comment.