@@ -37,7 +37,8 @@ module dmac_data_mover #(
37
37
38
38
parameter ID_WIDTH = 3 ,
39
39
parameter DATA_WIDTH = 64 ,
40
- parameter BEATS_PER_BURST_WIDTH = 4 ) (
40
+ parameter BEATS_PER_BURST_WIDTH = 4 ,
41
+ parameter ALLOW_ABORT = 0 ) (
41
42
42
43
input clk,
43
44
input resetn,
@@ -51,6 +52,7 @@ module dmac_data_mover #(
51
52
output s_axi_ready,
52
53
input s_axi_valid,
53
54
input [DATA_WIDTH- 1 :0 ] s_axi_data,
55
+ input s_axi_last,
54
56
input s_axi_sync,
55
57
56
58
output m_axi_valid,
@@ -60,7 +62,8 @@ module dmac_data_mover #(
60
62
input req_valid,
61
63
output req_ready,
62
64
input [BEATS_PER_BURST_WIDTH- 1 :0 ] req_last_burst_length,
63
- input req_sync_transfer_start
65
+ input req_sync_transfer_start,
66
+ input req_xlast
64
67
);
65
68
66
69
localparam BEAT_COUNTER_MAX = {BEATS_PER_BURST_WIDTH{1'b1 }};
@@ -81,7 +84,7 @@ reg needs_sync = 1'b0;
81
84
wire has_sync = ~ needs_sync | s_axi_sync;
82
85
83
86
wire s_axi_sync_valid = has_sync & s_axi_valid;
84
- wire s_axi_beat = s_axi_sync_valid & s_axi_ready ;
87
+ wire transfer_abort_s ;
85
88
86
89
wire last_load;
87
90
wire last;
@@ -92,18 +95,51 @@ assign response_id = id;
92
95
93
96
assign last = eot ? last_eot : last_non_eot;
94
97
95
- assign s_axi_ready = pending_burst & active;
96
- assign m_axi_valid = s_axi_sync_valid & pending_burst & active;
97
- assign m_axi_data = s_axi_data;
98
+ assign s_axi_ready = ( pending_burst & active) & ~ transfer_abort_s ;
99
+ assign m_axi_valid = ( s_axi_sync_valid | transfer_abort_s) & pending_burst & active;
100
+ assign m_axi_data = transfer_abort_s == 1'b1 ? {DATA_WIDTH{ 1'b0 }} : s_axi_data;
98
101
assign m_axi_last = last;
99
- assign m_axi_eot = last & eot;
102
+
103
+ generate if (ALLOW_ABORT == 1 ) begin
104
+ reg transfer_abort = 1'b0 ;
105
+ reg req_xlast_d = 1'b0 ;
106
+
107
+ /*
108
+ * A 'last' on the external interface indicates the end of an packet. If such a
109
+ * 'last' indicator is observed before the end of the current transfer stop
110
+ * accepting data on the external interface and complete the current transfer by
111
+ * writing zeros to the buffer.
112
+ */
113
+ always @(posedge clk) begin
114
+ if (resetn == 1'b0 ) begin
115
+ transfer_abort <= 1'b0 ;
116
+ end else if (m_axi_valid == 1'b1 ) begin
117
+ if (last == 1'b1 && eot == 1'b1 && req_xlast_d == 1'b1 ) begin
118
+ transfer_abort <= 1'b0 ;
119
+ end else if (s_axi_last == 1'b1 ) begin
120
+ transfer_abort <= 1'b1 ;
121
+ end
122
+ end
123
+ end
124
+
125
+ always @(posedge clk) begin
126
+ if (req_ready == 1'b1 ) begin
127
+ req_xlast_d <= req_xlast;
128
+ end
129
+ end
130
+
131
+ assign transfer_abort_s = transfer_abort;
132
+
133
+ end else begin
134
+ assign transfer_abort_s = 1'b0 ;
135
+ end endgenerate
100
136
101
137
/*
102
138
* If req_sync_transfer_start is set all incoming beats will be skipped until
103
139
* one has s_axi_sync set. This will be the first beat that is passsed through.
104
140
*/
105
141
always @(posedge clk) begin
106
- if (s_axi_beat == 1'b1 )
142
+ if (m_axi_valid == 1'b1 ) begin
107
143
needs_sync <= 1'b0 ;
108
144
end else if (req_ready == 1'b1 ) begin
109
145
needs_sync <= req_sync_transfer_start;
@@ -112,15 +148,15 @@ end
112
148
113
149
// If we want to support zero delay between transfers we have to assert
114
150
// req_ready on the same cycle on which the last load happens.
115
- assign last_load = s_axi_beat && last_eot && eot;
151
+ assign last_load = m_axi_valid && last_eot && eot;
116
152
assign req_ready = last_load || ~ active;
117
153
118
154
always @(posedge clk) begin
119
155
if (req_ready) begin
120
156
last_eot <= req_last_burst_length == 'h0;
121
157
last_non_eot <= 1'b0 ;
122
158
beat_counter <= 'h1;
123
- end else if (s_axi_beat == 1'b1 ) begin
159
+ end else if (m_axi_valid == 1'b1 ) begin
124
160
last_eot <= beat_counter == last_burst_length;
125
161
last_non_eot <= beat_counter == BEAT_COUNTER_MAX;
126
162
beat_counter <= beat_counter + 1'b1 ;
144
180
145
181
always @(* )
146
182
begin
147
- if (s_axi_beat == 1'b1 && last == 1'b1 )
183
+ if (m_axi_valid == 1'b1 && last == 1'b1 )
148
184
id_next <= inc_id(id);
149
185
else
150
186
id_next <= id;
0 commit comments