1 |
221 |
olivier.gi |
// (C) 2001-2014 Altera Corporation. All rights reserved.
|
2 |
|
|
// Your use of Altera Corporation's design tools, logic functions and other
|
3 |
|
|
// software and tools, and its AMPP partner logic functions, and any output
|
4 |
|
|
// files any of the foregoing (including device programming or simulation
|
5 |
|
|
// files), and any associated documentation or information are expressly subject
|
6 |
|
|
// to the terms and conditions of the Altera Program License Subscription
|
7 |
|
|
// Agreement, Altera MegaCore Function License Agreement, or other applicable
|
8 |
|
|
// license agreement, including, without limitation, that your use is for the
|
9 |
|
|
// sole purpose of programming logic devices manufactured by Altera and sold by
|
10 |
|
|
// Altera or its authorized distributors. Please refer to the applicable
|
11 |
|
|
// agreement for further details.
|
12 |
|
|
|
13 |
|
|
|
14 |
|
|
// $Id: //acds/rel/14.0/ip/merlin/altera_merlin_master_translator/altera_merlin_master_translator.sv#1 $
|
15 |
|
|
// $Revision: #1 $
|
16 |
|
|
// $Date: 2014/02/16 $
|
17 |
|
|
// $Author: swbranch $
|
18 |
|
|
|
19 |
|
|
// --------------------------------------
|
20 |
|
|
// Merlin Master Translator
|
21 |
|
|
//
|
22 |
|
|
// Converts Avalon-MM Master Interfaces into
|
23 |
|
|
// Avalon-MM Universal Master Interfaces
|
24 |
|
|
// --------------------------------------
|
25 |
|
|
|
26 |
|
|
`timescale 1 ns / 1 ns
|
27 |
|
|
|
28 |
|
|
|
29 |
|
|
|
30 |
|
|
module altera_merlin_master_translator #(
|
31 |
|
|
parameter
|
32 |
|
|
AV_ADDRESS_W = 32,
|
33 |
|
|
AV_DATA_W = 32,
|
34 |
|
|
AV_BURSTCOUNT_W = 4,
|
35 |
|
|
AV_BYTEENABLE_W = 4,
|
36 |
|
|
|
37 |
|
|
//Optional Port Declarations
|
38 |
|
|
|
39 |
|
|
USE_BURSTCOUNT = 1,
|
40 |
|
|
USE_BEGINBURSTTRANSFER = 0,
|
41 |
|
|
USE_BEGINTRANSFER = 0,
|
42 |
|
|
USE_CHIPSELECT = 0,
|
43 |
|
|
USE_READ = 1,
|
44 |
|
|
USE_READDATAVALID = 1,
|
45 |
|
|
USE_WRITE = 1,
|
46 |
|
|
USE_WAITREQUEST = 1,
|
47 |
|
|
USE_WRITERESPONSE = 0,
|
48 |
|
|
USE_READRESPONSE = 0,
|
49 |
|
|
|
50 |
|
|
AV_REGISTERINCOMINGSIGNALS = 0,
|
51 |
|
|
AV_SYMBOLS_PER_WORD = 4,
|
52 |
|
|
AV_ADDRESS_SYMBOLS = 0,
|
53 |
|
|
AV_CONSTANT_BURST_BEHAVIOR = 1,
|
54 |
|
|
AV_BURSTCOUNT_SYMBOLS = 0,
|
55 |
|
|
AV_LINEWRAPBURSTS = 0,
|
56 |
|
|
UAV_ADDRESS_W = 38,
|
57 |
|
|
UAV_BURSTCOUNT_W = 10,
|
58 |
|
|
UAV_CONSTANT_BURST_BEHAVIOR = 0
|
59 |
|
|
)(
|
60 |
|
|
//Universal Avalon Master
|
61 |
|
|
input wire clk,
|
62 |
|
|
input wire reset,
|
63 |
|
|
output reg uav_write,
|
64 |
|
|
output reg uav_read,
|
65 |
|
|
output reg [UAV_ADDRESS_W -1 : 0] uav_address,
|
66 |
|
|
output reg [UAV_BURSTCOUNT_W -1 : 0] uav_burstcount,
|
67 |
|
|
output wire [AV_BYTEENABLE_W -1 : 0] uav_byteenable,
|
68 |
|
|
output wire [AV_DATA_W -1 : 0] uav_writedata,
|
69 |
|
|
output wire uav_lock,
|
70 |
|
|
output wire uav_debugaccess,
|
71 |
|
|
output wire uav_clken,
|
72 |
|
|
|
73 |
|
|
input wire [ AV_DATA_W -1 : 0] uav_readdata,
|
74 |
|
|
input wire uav_readdatavalid,
|
75 |
|
|
input wire uav_waitrequest,
|
76 |
|
|
input wire [1:0] uav_response,
|
77 |
|
|
output reg uav_writeresponserequest,
|
78 |
|
|
input wire uav_writeresponsevalid,
|
79 |
|
|
|
80 |
|
|
//Avalon-MM !Master
|
81 |
|
|
input reg av_write,
|
82 |
|
|
input reg av_read,
|
83 |
|
|
input wire [AV_ADDRESS_W -1 : 0] av_address,
|
84 |
|
|
input wire [AV_BYTEENABLE_W -1 : 0] av_byteenable,
|
85 |
|
|
input wire [AV_BURSTCOUNT_W -1 : 0] av_burstcount,
|
86 |
|
|
input wire [AV_DATA_W -1 : 0] av_writedata,
|
87 |
|
|
input wire av_begintransfer,
|
88 |
|
|
input wire av_beginbursttransfer,
|
89 |
|
|
input wire av_lock,
|
90 |
|
|
input wire av_chipselect,
|
91 |
|
|
input wire av_debugaccess,
|
92 |
|
|
input wire av_clken,
|
93 |
|
|
|
94 |
|
|
output wire [AV_DATA_W -1 : 0] av_readdata,
|
95 |
|
|
output wire av_readdatavalid,
|
96 |
|
|
output reg av_waitrequest,
|
97 |
|
|
output reg [1:0] av_response,
|
98 |
|
|
input wire av_writeresponserequest,
|
99 |
|
|
output reg av_writeresponsevalid
|
100 |
|
|
|
101 |
|
|
);
|
102 |
|
|
|
103 |
|
|
|
104 |
|
|
localparam BITS_PER_WORD = clog2(AV_SYMBOLS_PER_WORD - 1);
|
105 |
|
|
localparam AV_MAX_SYMBOL_BURST = flog2( pow2(AV_BURSTCOUNT_W - 1) * (AV_BURSTCOUNT_SYMBOLS ? 1 : (AV_SYMBOLS_PER_WORD)) );
|
106 |
|
|
localparam AV_MAX_SYMBOL_BURST_MINUS_ONE = AV_MAX_SYMBOL_BURST ? AV_MAX_SYMBOL_BURST - 1 : 0 ;
|
107 |
|
|
|
108 |
|
|
localparam UAV_BURSTCOUNT_W_OR_32 = UAV_BURSTCOUNT_W > 32 ? 31 : UAV_BURSTCOUNT_W -1;
|
109 |
|
|
localparam UAV_ADDRESS_W_OR_32 = UAV_ADDRESS_W > 32 ? 31 : UAV_ADDRESS_W -1;
|
110 |
|
|
|
111 |
|
|
|
112 |
|
|
// -1 for burstcount restriction 2^(n-1)
|
113 |
|
|
|
114 |
|
|
localparam BITS_PER_WORD_BURSTCOUNT = UAV_BURSTCOUNT_W == 1 ? 0 : BITS_PER_WORD;
|
115 |
|
|
localparam BITS_PER_WORD_ADDRESS = UAV_ADDRESS_W == 1 ? 0 : BITS_PER_WORD;
|
116 |
|
|
|
117 |
|
|
localparam ADDRESS_LOW = AV_ADDRESS_SYMBOLS ? 0 : BITS_PER_WORD_ADDRESS;
|
118 |
|
|
localparam BURSTCOUNT_LOW = AV_BURSTCOUNT_SYMBOLS ? 0 : BITS_PER_WORD_BURSTCOUNT;
|
119 |
|
|
|
120 |
|
|
localparam ADDRESS_HIGH = UAV_ADDRESS_W > AV_ADDRESS_W + ADDRESS_LOW ? AV_ADDRESS_W : UAV_ADDRESS_W - ADDRESS_LOW;
|
121 |
|
|
localparam BURSTCOUNT_HIGH = UAV_BURSTCOUNT_W > AV_BURSTCOUNT_W + BURSTCOUNT_LOW ? AV_BURSTCOUNT_W : UAV_BURSTCOUNT_W - BURSTCOUNT_LOW;
|
122 |
|
|
|
123 |
|
|
function integer flog2;
|
124 |
|
|
input [31:0] Depth;
|
125 |
|
|
integer i;
|
126 |
|
|
begin
|
127 |
|
|
i = Depth;
|
128 |
|
|
if ( i <= 0 ) flog2 = 0;
|
129 |
|
|
else begin
|
130 |
|
|
for(flog2 = -1; i > 0; flog2 = flog2 + 1)
|
131 |
|
|
i = i >> 1;
|
132 |
|
|
end
|
133 |
|
|
end
|
134 |
|
|
|
135 |
|
|
endfunction // flog2
|
136 |
|
|
|
137 |
|
|
function integer clog2;
|
138 |
|
|
input [31:0] Depth;
|
139 |
|
|
integer i;
|
140 |
|
|
begin
|
141 |
|
|
i = Depth;
|
142 |
|
|
for(clog2 = 0; i > 0; clog2 = clog2 + 1)
|
143 |
|
|
i = i >> 1;
|
144 |
|
|
end
|
145 |
|
|
|
146 |
|
|
endfunction
|
147 |
|
|
|
148 |
|
|
function integer pow2;
|
149 |
|
|
input [31:0] toShift;
|
150 |
|
|
begin
|
151 |
|
|
pow2=1;
|
152 |
|
|
pow2= pow2 << toShift;
|
153 |
|
|
end
|
154 |
|
|
endfunction // pow2
|
155 |
|
|
|
156 |
|
|
// -------------------------------------------------
|
157 |
|
|
// Assign some constants to appropriately-sized signals to
|
158 |
|
|
// avoid synthesis warnings. This also helps some simulators
|
159 |
|
|
// with their inferred sensitivity lists.
|
160 |
|
|
// -------------------------------------------------
|
161 |
|
|
// Calculate the symbols per word as the power of 2 extended symbols per word
|
162 |
|
|
wire [31:0] symbols_per_word_int = 2**(clog2(AV_SYMBOLS_PER_WORD[UAV_BURSTCOUNT_W_OR_32 : 0] - 1));
|
163 |
|
|
wire [UAV_BURSTCOUNT_W_OR_32 : 0] symbols_per_word = symbols_per_word_int[UAV_BURSTCOUNT_W_OR_32 : 0];
|
164 |
|
|
|
165 |
|
|
|
166 |
|
|
reg internal_beginbursttransfer;
|
167 |
|
|
reg internal_begintransfer;
|
168 |
|
|
reg [UAV_ADDRESS_W - 1: 0 ] uav_address_pre;
|
169 |
|
|
reg [UAV_BURSTCOUNT_W - 1 : 0 ] uav_burstcount_pre;
|
170 |
|
|
|
171 |
|
|
|
172 |
|
|
|
173 |
|
|
reg uav_read_pre;
|
174 |
|
|
reg uav_write_pre;
|
175 |
|
|
reg read_accepted;
|
176 |
|
|
|
177 |
|
|
//Passthru assignmenst
|
178 |
|
|
|
179 |
|
|
assign uav_writedata = av_writedata;
|
180 |
|
|
assign av_readdata = uav_readdata;
|
181 |
|
|
assign uav_byteenable = av_byteenable;
|
182 |
|
|
assign uav_lock = av_lock;
|
183 |
|
|
assign av_readdatavalid = uav_readdatavalid;
|
184 |
|
|
assign uav_debugaccess = av_debugaccess;
|
185 |
|
|
assign uav_clken = av_clken;
|
186 |
|
|
|
187 |
|
|
//Response signals
|
188 |
|
|
always_comb
|
189 |
|
|
begin
|
190 |
|
|
if (!USE_READRESPONSE && !USE_WRITERESPONSE)
|
191 |
|
|
av_response = '0;
|
192 |
|
|
else
|
193 |
|
|
av_response = uav_response;
|
194 |
|
|
if (USE_WRITERESPONSE) begin
|
195 |
|
|
uav_writeresponserequest = av_writeresponserequest;
|
196 |
|
|
av_writeresponsevalid = uav_writeresponsevalid;
|
197 |
|
|
end else begin
|
198 |
|
|
uav_writeresponserequest = '0;
|
199 |
|
|
av_writeresponsevalid = '0;
|
200 |
|
|
end
|
201 |
|
|
end
|
202 |
|
|
|
203 |
|
|
//address + burstcount assignment
|
204 |
|
|
|
205 |
|
|
reg [UAV_ADDRESS_W - 1 : 0] address_register;
|
206 |
|
|
wire [UAV_BURSTCOUNT_W - 1 : 0] burstcount_register;
|
207 |
|
|
reg [UAV_BURSTCOUNT_W : 0] burstcount_register_lint;
|
208 |
|
|
|
209 |
|
|
assign burstcount_register = burstcount_register_lint [UAV_BURSTCOUNT_W - 1 : 0];
|
210 |
|
|
|
211 |
|
|
always @* begin
|
212 |
|
|
uav_address=uav_address_pre;
|
213 |
|
|
uav_burstcount=uav_burstcount_pre;
|
214 |
|
|
|
215 |
|
|
if(AV_CONSTANT_BURST_BEHAVIOR && !UAV_CONSTANT_BURST_BEHAVIOR && ~internal_beginbursttransfer) begin
|
216 |
|
|
uav_address=address_register;
|
217 |
|
|
uav_burstcount=burstcount_register;
|
218 |
|
|
end
|
219 |
|
|
end
|
220 |
|
|
|
221 |
|
|
reg first_burst_stalled;
|
222 |
|
|
reg burst_stalled;
|
223 |
|
|
|
224 |
|
|
|
225 |
|
|
wire[UAV_ADDRESS_W-1:0] combi_burst_addr_reg;
|
226 |
|
|
wire [UAV_ADDRESS_W-1:0] combi_addr_reg;
|
227 |
|
|
generate
|
228 |
|
|
if(AV_LINEWRAPBURSTS && AV_MAX_SYMBOL_BURST!=0) begin
|
229 |
|
|
if(AV_MAX_SYMBOL_BURST > UAV_ADDRESS_W - 1) begin
|
230 |
|
|
assign combi_burst_addr_reg = { uav_address_pre[UAV_ADDRESS_W-1:0] + AV_SYMBOLS_PER_WORD[UAV_ADDRESS_W-1:0] };
|
231 |
|
|
assign combi_addr_reg = { address_register[UAV_ADDRESS_W-1:0] + AV_SYMBOLS_PER_WORD[UAV_ADDRESS_W-1:0] };
|
232 |
|
|
end
|
233 |
|
|
else begin
|
234 |
|
|
assign combi_burst_addr_reg = { uav_address_pre[UAV_ADDRESS_W - 1 : AV_MAX_SYMBOL_BURST], uav_address_pre[AV_MAX_SYMBOL_BURST_MINUS_ONE:0] + AV_SYMBOLS_PER_WORD[AV_MAX_SYMBOL_BURST_MINUS_ONE:0] };
|
235 |
|
|
assign combi_addr_reg = { address_register[UAV_ADDRESS_W - 1 : AV_MAX_SYMBOL_BURST], address_register[AV_MAX_SYMBOL_BURST_MINUS_ONE:0] + AV_SYMBOLS_PER_WORD[AV_MAX_SYMBOL_BURST_MINUS_ONE:0] };
|
236 |
|
|
end
|
237 |
|
|
end
|
238 |
|
|
else begin
|
239 |
|
|
assign combi_burst_addr_reg =
|
240 |
|
|
uav_address_pre + AV_SYMBOLS_PER_WORD[UAV_ADDRESS_W_OR_32:0];
|
241 |
|
|
assign combi_addr_reg =
|
242 |
|
|
address_register + AV_SYMBOLS_PER_WORD[UAV_ADDRESS_W_OR_32:0];
|
243 |
|
|
end
|
244 |
|
|
endgenerate
|
245 |
|
|
|
246 |
|
|
always@(posedge clk, posedge reset) begin
|
247 |
|
|
|
248 |
|
|
if(reset) begin
|
249 |
|
|
address_register <= '0;
|
250 |
|
|
burstcount_register_lint <= '0;
|
251 |
|
|
first_burst_stalled <= 1'b0;
|
252 |
|
|
burst_stalled <= 1'b0;
|
253 |
|
|
end
|
254 |
|
|
else begin
|
255 |
|
|
address_register <= address_register;
|
256 |
|
|
burstcount_register_lint <= burstcount_register_lint;
|
257 |
|
|
|
258 |
|
|
if(internal_beginbursttransfer||first_burst_stalled) begin
|
259 |
|
|
|
260 |
|
|
if(av_waitrequest) begin
|
261 |
|
|
first_burst_stalled <= 1'b1;
|
262 |
|
|
address_register <= uav_address_pre;
|
263 |
|
|
burstcount_register_lint [UAV_BURSTCOUNT_W - 1 : 0] <= uav_burstcount_pre;
|
264 |
|
|
end else begin
|
265 |
|
|
first_burst_stalled <= 1'b0;
|
266 |
|
|
address_register <= combi_burst_addr_reg;
|
267 |
|
|
burstcount_register_lint <= uav_burstcount_pre - symbols_per_word;
|
268 |
|
|
end
|
269 |
|
|
end
|
270 |
|
|
|
271 |
|
|
else if(internal_begintransfer || burst_stalled) begin
|
272 |
|
|
if(~av_waitrequest) begin
|
273 |
|
|
burst_stalled <= 1'b0;
|
274 |
|
|
address_register <= combi_addr_reg;
|
275 |
|
|
burstcount_register_lint <= burstcount_register - symbols_per_word;
|
276 |
|
|
end else
|
277 |
|
|
burst_stalled<=1'b1;
|
278 |
|
|
end
|
279 |
|
|
end
|
280 |
|
|
|
281 |
|
|
end
|
282 |
|
|
|
283 |
|
|
//Address
|
284 |
|
|
always @* begin
|
285 |
|
|
uav_address_pre = {UAV_ADDRESS_W{1'b0}};
|
286 |
|
|
|
287 |
|
|
if(AV_ADDRESS_SYMBOLS)
|
288 |
|
|
uav_address_pre[ ( ADDRESS_HIGH ? ADDRESS_HIGH - 1 : 0 ) : 0 ] =av_address[ ( ADDRESS_HIGH ? ADDRESS_HIGH - 1 : 0 ) : 0 ];
|
289 |
|
|
else begin
|
290 |
|
|
uav_address_pre[ ADDRESS_LOW + ADDRESS_HIGH - 1 : ADDRESS_LOW ] = av_address[( ADDRESS_HIGH ? ADDRESS_HIGH - 1 : 0) : 0 ];
|
291 |
|
|
end
|
292 |
|
|
end
|
293 |
|
|
|
294 |
|
|
//Burstcount
|
295 |
|
|
always@* begin
|
296 |
|
|
uav_burstcount_pre = symbols_per_word; // default to a single transfer
|
297 |
|
|
|
298 |
|
|
if(USE_BURSTCOUNT) begin
|
299 |
|
|
uav_burstcount_pre = {UAV_BURSTCOUNT_W{1'b0}};
|
300 |
|
|
|
301 |
|
|
if(AV_BURSTCOUNT_SYMBOLS)
|
302 |
|
|
uav_burstcount_pre[( BURSTCOUNT_HIGH ? BURSTCOUNT_HIGH - 1 : 0 ) :0 ] = av_burstcount[( BURSTCOUNT_HIGH ? BURSTCOUNT_HIGH - 1 : 0 ) :0 ];
|
303 |
|
|
else begin
|
304 |
|
|
uav_burstcount_pre[ UAV_BURSTCOUNT_W - 1 : BURSTCOUNT_LOW] = av_burstcount[( BURSTCOUNT_HIGH ? BURSTCOUNT_HIGH - 1 : 0 ) : 0 ];
|
305 |
|
|
end
|
306 |
|
|
|
307 |
|
|
end
|
308 |
|
|
|
309 |
|
|
end
|
310 |
|
|
|
311 |
|
|
|
312 |
|
|
//waitrequest translation
|
313 |
|
|
|
314 |
|
|
always@(posedge clk, posedge reset) begin
|
315 |
|
|
if(reset)
|
316 |
|
|
read_accepted <= 1'b0;
|
317 |
|
|
else begin
|
318 |
|
|
read_accepted <= read_accepted;
|
319 |
|
|
|
320 |
|
|
if(read_accepted == 0)
|
321 |
|
|
read_accepted<=av_waitrequest ? uav_read_pre & ~uav_waitrequest : 1'b0;
|
322 |
|
|
else if(read_accepted == 1 && uav_readdatavalid == 1) // reset acceptance only when rdv arrives
|
323 |
|
|
read_accepted <= 1'b0;
|
324 |
|
|
end
|
325 |
|
|
|
326 |
|
|
end
|
327 |
|
|
|
328 |
|
|
reg write_accepted = 0;
|
329 |
|
|
generate if (AV_REGISTERINCOMINGSIGNALS) begin
|
330 |
|
|
always@(posedge clk, posedge reset) begin
|
331 |
|
|
if(reset)
|
332 |
|
|
write_accepted <= 1'b0;
|
333 |
|
|
else begin
|
334 |
|
|
write_accepted <=
|
335 |
|
|
~av_waitrequest ? 1'b0 :
|
336 |
|
|
uav_write & ~uav_waitrequest? 1'b1 :
|
337 |
|
|
write_accepted;
|
338 |
|
|
end
|
339 |
|
|
end
|
340 |
|
|
end endgenerate
|
341 |
|
|
|
342 |
|
|
always@* begin
|
343 |
|
|
av_waitrequest = uav_waitrequest;
|
344 |
|
|
|
345 |
|
|
if(USE_READDATAVALID == 0 ) begin
|
346 |
|
|
av_waitrequest = uav_read_pre ? ~uav_readdatavalid : uav_waitrequest;
|
347 |
|
|
end
|
348 |
|
|
|
349 |
|
|
if (AV_REGISTERINCOMINGSIGNALS) begin
|
350 |
|
|
av_waitrequest =
|
351 |
|
|
uav_read_pre ? ~uav_readdatavalid :
|
352 |
|
|
uav_write_pre ? (internal_begintransfer | uav_waitrequest) & ~write_accepted :
|
353 |
|
|
1'b1;
|
354 |
|
|
end
|
355 |
|
|
|
356 |
|
|
if(USE_WAITREQUEST == 0) begin
|
357 |
|
|
av_waitrequest = 0;
|
358 |
|
|
end
|
359 |
|
|
end
|
360 |
|
|
|
361 |
|
|
//read/write generation
|
362 |
|
|
always@* begin
|
363 |
|
|
|
364 |
|
|
uav_write = 1'b0;
|
365 |
|
|
uav_write_pre = 1'b0;
|
366 |
|
|
uav_read = 1'b0;
|
367 |
|
|
uav_read_pre = 1'b0;
|
368 |
|
|
|
369 |
|
|
if(!USE_CHIPSELECT) begin
|
370 |
|
|
if (USE_READ) begin
|
371 |
|
|
uav_read_pre=av_read;
|
372 |
|
|
end
|
373 |
|
|
|
374 |
|
|
if (USE_WRITE) begin
|
375 |
|
|
uav_write_pre=av_write;
|
376 |
|
|
end
|
377 |
|
|
end
|
378 |
|
|
else begin
|
379 |
|
|
if(!USE_WRITE && USE_READ) begin
|
380 |
|
|
uav_read_pre=av_read;
|
381 |
|
|
uav_write_pre=av_chipselect & ~av_read;
|
382 |
|
|
end
|
383 |
|
|
else if(!USE_READ && USE_WRITE) begin
|
384 |
|
|
uav_write_pre=av_write;
|
385 |
|
|
uav_read_pre = av_chipselect & ~av_write;
|
386 |
|
|
end
|
387 |
|
|
else if (USE_READ && USE_WRITE) begin
|
388 |
|
|
uav_write_pre=av_write;
|
389 |
|
|
uav_read_pre=av_read;
|
390 |
|
|
end
|
391 |
|
|
end
|
392 |
|
|
|
393 |
|
|
if(USE_READDATAVALID == 0)
|
394 |
|
|
uav_read = uav_read_pre & ~read_accepted;
|
395 |
|
|
else
|
396 |
|
|
uav_read = uav_read_pre;
|
397 |
|
|
|
398 |
|
|
if(AV_REGISTERINCOMINGSIGNALS == 0)
|
399 |
|
|
uav_write=uav_write_pre;
|
400 |
|
|
else
|
401 |
|
|
uav_write=uav_write_pre & ~write_accepted;
|
402 |
|
|
|
403 |
|
|
|
404 |
|
|
end
|
405 |
|
|
|
406 |
|
|
// -------------------
|
407 |
|
|
// Begintransfer Assigment
|
408 |
|
|
// -------------------
|
409 |
|
|
|
410 |
|
|
reg end_begintransfer;
|
411 |
|
|
|
412 |
|
|
always@* begin
|
413 |
|
|
if(USE_BEGINTRANSFER) begin
|
414 |
|
|
internal_begintransfer = av_begintransfer;
|
415 |
|
|
end else begin
|
416 |
|
|
internal_begintransfer = ( uav_write | uav_read ) & ~end_begintransfer;
|
417 |
|
|
end
|
418 |
|
|
end
|
419 |
|
|
|
420 |
|
|
always@ ( posedge clk or posedge reset ) begin
|
421 |
|
|
|
422 |
|
|
if(reset) begin
|
423 |
|
|
end_begintransfer <= 1'b0;
|
424 |
|
|
end
|
425 |
|
|
else begin
|
426 |
|
|
|
427 |
|
|
if(internal_begintransfer == 1 && uav_waitrequest)
|
428 |
|
|
end_begintransfer <= 1'b1;
|
429 |
|
|
else if(uav_waitrequest)
|
430 |
|
|
end_begintransfer <= end_begintransfer;
|
431 |
|
|
else
|
432 |
|
|
end_begintransfer <= 1'b0;
|
433 |
|
|
|
434 |
|
|
end
|
435 |
|
|
|
436 |
|
|
end
|
437 |
|
|
|
438 |
|
|
// -------------------
|
439 |
|
|
// Beginbursttransfer Assigment
|
440 |
|
|
// -------------------
|
441 |
|
|
|
442 |
|
|
reg end_beginbursttransfer;
|
443 |
|
|
wire last_burst_transfer_pre;
|
444 |
|
|
wire last_burst_transfer_reg;
|
445 |
|
|
wire last_burst_transfer;
|
446 |
|
|
|
447 |
|
|
// compare values before the mux to shorten critical path; benchmark before changing
|
448 |
|
|
assign last_burst_transfer_pre = (uav_burstcount_pre == symbols_per_word);
|
449 |
|
|
assign last_burst_transfer_reg = (burstcount_register == symbols_per_word);
|
450 |
|
|
assign last_burst_transfer = (internal_beginbursttransfer) ? last_burst_transfer_pre : last_burst_transfer_reg;
|
451 |
|
|
|
452 |
|
|
always@* begin
|
453 |
|
|
if(USE_BEGINBURSTTRANSFER) begin
|
454 |
|
|
internal_beginbursttransfer = av_beginbursttransfer;
|
455 |
|
|
end else begin
|
456 |
|
|
internal_beginbursttransfer = uav_read ? internal_begintransfer : internal_begintransfer && ~end_beginbursttransfer;
|
457 |
|
|
end
|
458 |
|
|
end
|
459 |
|
|
|
460 |
|
|
always@ ( posedge clk or posedge reset ) begin
|
461 |
|
|
|
462 |
|
|
if(reset) begin
|
463 |
|
|
end_beginbursttransfer <= 1'b0;
|
464 |
|
|
end
|
465 |
|
|
else begin
|
466 |
|
|
end_beginbursttransfer <= end_beginbursttransfer;
|
467 |
|
|
if( last_burst_transfer && internal_begintransfer || uav_read ) begin
|
468 |
|
|
end_beginbursttransfer <= 1'b0;
|
469 |
|
|
end
|
470 |
|
|
else if(uav_write && internal_begintransfer) begin
|
471 |
|
|
end_beginbursttransfer <= 1'b1;
|
472 |
|
|
end
|
473 |
|
|
end
|
474 |
|
|
|
475 |
|
|
end
|
476 |
|
|
|
477 |
|
|
// synthesis translate_off
|
478 |
|
|
|
479 |
|
|
// ------------------------------------------------
|
480 |
|
|
// check_1 : for waitrequest signal violation
|
481 |
|
|
// Ensure that when waitreqeust is asserted, the master is not allowed to change its controls
|
482 |
|
|
// Exception : begintransfer / beginbursttransfer
|
483 |
|
|
// : previously not in any transaction (idle)
|
484 |
|
|
// Note : Not checking clken which is not exactly part of Avalon controls/inputs
|
485 |
|
|
// : Not using system verilog assertions (seq/prop) since it is not supported if using Modelsim_SE
|
486 |
|
|
// ------------------------------------------------
|
487 |
|
|
|
488 |
|
|
reg av_waitrequest_r;
|
489 |
|
|
reg av_write_r,av_writeresponserequest_r,av_read_r,av_lock_r,av_chipselect_r,av_debugaccess_r;
|
490 |
|
|
reg [AV_ADDRESS_W-1:0] av_address_r;
|
491 |
|
|
reg [AV_BYTEENABLE_W-1:0] av_byteenable_r;
|
492 |
|
|
reg [AV_BURSTCOUNT_W-1:0] av_burstcount_r;
|
493 |
|
|
reg [AV_DATA_W-1:0] av_writedata_r;
|
494 |
|
|
|
495 |
|
|
always @(posedge clk or posedge reset) begin
|
496 |
|
|
if (reset) begin
|
497 |
|
|
av_waitrequest_r <= '0;
|
498 |
|
|
av_write_r <= '0;
|
499 |
|
|
av_writeresponserequest_r <= '0;
|
500 |
|
|
av_read_r <= '0;
|
501 |
|
|
av_lock_r <= '0;
|
502 |
|
|
av_chipselect_r <= '0;
|
503 |
|
|
av_debugaccess_r <= '0;
|
504 |
|
|
av_address_r <= '0;
|
505 |
|
|
av_byteenable_r <= '0;
|
506 |
|
|
av_burstcount_r <= '0;
|
507 |
|
|
av_writedata_r <= '0;
|
508 |
|
|
|
509 |
|
|
end
|
510 |
|
|
else begin
|
511 |
|
|
av_waitrequest_r <= av_waitrequest;
|
512 |
|
|
av_write_r <= av_write;
|
513 |
|
|
av_writeresponserequest_r <= av_writeresponserequest;
|
514 |
|
|
av_read_r <= av_read;
|
515 |
|
|
av_lock_r <= av_lock;
|
516 |
|
|
av_chipselect_r <= av_chipselect;
|
517 |
|
|
av_debugaccess_r <= av_debugaccess;
|
518 |
|
|
av_address_r <= av_address;
|
519 |
|
|
av_byteenable_r <= av_byteenable;
|
520 |
|
|
av_burstcount_r <= av_burstcount;
|
521 |
|
|
av_writedata_r <= av_writedata;
|
522 |
|
|
|
523 |
|
|
if ( av_waitrequest_r && // When waitrequest is asserted
|
524 |
|
|
( (av_write != av_write_r) || // Checks that : Input controls/data does not change
|
525 |
|
|
(av_writeresponserequest != av_writeresponserequest_r) ||
|
526 |
|
|
(av_read != av_read_r) ||
|
527 |
|
|
(av_lock != av_lock_r) ||
|
528 |
|
|
(av_debugaccess != av_debugaccess_r) ||
|
529 |
|
|
(av_address != av_address_r) ||
|
530 |
|
|
(av_byteenable != av_byteenable_r) ||
|
531 |
|
|
(av_burstcount != av_burstcount_r)
|
532 |
|
|
) &&
|
533 |
|
|
(av_write_r | av_read_r) && // Check only when : previously initiated a write/read
|
534 |
|
|
(!USE_CHIPSELECT | av_chipselect_r) // and chipselect was asserted (or unused)
|
535 |
|
|
)
|
536 |
|
|
$display("%t: %m: Error: Input controls/data changed while av_waitrequest is asserted.\nav_address %x --> %x\nav_byteenable %x --> %x\nav_burstcount %x --> %x\nav_writedata %x --> %x\nav_writeresponserequest %x --> %x\nav_write %x --> %x\nav_read %x --> %x\nav_lock %x --> %x\nav_chipselect %x --> %x\nav_debugaccess %x --> %x ", $time(),
|
537 |
|
|
av_address_r , av_address,
|
538 |
|
|
av_byteenable_r , av_byteenable,
|
539 |
|
|
av_burstcount_r , av_burstcount,
|
540 |
|
|
av_writedata_r , av_writedata,
|
541 |
|
|
av_writeresponserequest_r, av_writeresponserequest,
|
542 |
|
|
av_write_r , av_write,
|
543 |
|
|
av_read_r , av_read,
|
544 |
|
|
av_lock_r , av_lock,
|
545 |
|
|
av_chipselect_r, av_chipselect,
|
546 |
|
|
av_debugaccess_r, av_debugaccess);
|
547 |
|
|
end
|
548 |
|
|
|
549 |
|
|
// end check_1
|
550 |
|
|
|
551 |
|
|
end
|
552 |
|
|
|
553 |
|
|
// synthesis translate_on
|
554 |
|
|
|
555 |
|
|
|
556 |
|
|
endmodule
|