1 |
32 |
redbear |
// (C) 2001-2017 Intel Corporation. All rights reserved.
|
2 |
|
|
// Your use of Intel Corporation's design tools, logic functions and other
|
3 |
|
|
// software and tools, and its AMPP partner logic functions, and any output
|
4 |
40 |
redbear |
// files from any of the foregoing (including device programming or simulation
|
5 |
32 |
redbear |
// files), and any associated documentation or information are expressly subject
|
6 |
|
|
// to the terms and conditions of the Intel Program License Subscription
|
7 |
40 |
redbear |
// Agreement, Intel FPGA IP License Agreement, or other applicable
|
8 |
32 |
redbear |
// license agreement, including, without limitation, that your use is for the
|
9 |
|
|
// sole purpose of programming logic devices manufactured by Intel and sold by
|
10 |
|
|
// Intel or its authorized distributors. Please refer to the applicable
|
11 |
|
|
// agreement for further details.
|
12 |
|
|
|
13 |
|
|
|
14 |
|
|
|
15 |
40 |
redbear |
// $Id: //acds/rel/17.1std/ip/merlin/altera_merlin_slave_translator/altera_merlin_slave_translator.sv#1 $
|
16 |
32 |
redbear |
// $Revision: #1 $
|
17 |
40 |
redbear |
// $Date: 2017/07/30 $
|
18 |
32 |
redbear |
// $Author: swbranch $
|
19 |
|
|
|
20 |
|
|
// -------------------------------------
|
21 |
|
|
// Merlin Slave Translator
|
22 |
|
|
//
|
23 |
|
|
// Translates Universal Avalon MM Slave
|
24 |
|
|
// to any Avalon MM Slave
|
25 |
|
|
// -------------------------------------
|
26 |
|
|
//
|
27 |
|
|
//Notable Note: 0 AV_READLATENCY is not allowed and will be converted to a 1 cycle readlatency in all cases but one
|
28 |
|
|
//If you declare a slave with fixed read timing requirements, the readlatency of such a slave will be allowed to be zero
|
29 |
|
|
//The key feature here is that no same cycle turnaround data is processed through the fabric.
|
30 |
|
|
|
31 |
|
|
//import avalon_utilities_pkg::*;
|
32 |
|
|
|
33 |
|
|
`timescale 1 ns / 1 ns
|
34 |
|
|
|
35 |
|
|
module altera_merlin_slave_translator #(
|
36 |
|
|
parameter
|
37 |
|
|
//Widths
|
38 |
|
|
AV_ADDRESS_W = 32,
|
39 |
|
|
AV_DATA_W = 32,
|
40 |
|
|
AV_BURSTCOUNT_W = 4,
|
41 |
|
|
AV_BYTEENABLE_W = 4,
|
42 |
|
|
UAV_BYTEENABLE_W = 4,
|
43 |
|
|
|
44 |
|
|
//Read Latency
|
45 |
|
|
AV_READLATENCY = 1,
|
46 |
|
|
|
47 |
|
|
//Timing
|
48 |
|
|
AV_READ_WAIT_CYCLES = 0,
|
49 |
|
|
AV_WRITE_WAIT_CYCLES = 0,
|
50 |
|
|
AV_SETUP_WAIT_CYCLES = 0,
|
51 |
|
|
AV_DATA_HOLD_CYCLES = 0,
|
52 |
|
|
|
53 |
|
|
//Optional Port Declarations
|
54 |
|
|
USE_READDATAVALID = 1,
|
55 |
|
|
USE_WAITREQUEST = 1,
|
56 |
|
|
USE_READRESPONSE = 0,
|
57 |
|
|
USE_WRITERESPONSE = 0,
|
58 |
|
|
|
59 |
|
|
//Variable Addressing
|
60 |
|
|
AV_SYMBOLS_PER_WORD = 4,
|
61 |
|
|
AV_ADDRESS_SYMBOLS = 0,
|
62 |
|
|
AV_BURSTCOUNT_SYMBOLS = 0,
|
63 |
|
|
BITS_PER_WORD = clog2_plusone(AV_SYMBOLS_PER_WORD - 1),
|
64 |
|
|
UAV_ADDRESS_W = 38,
|
65 |
|
|
UAV_BURSTCOUNT_W = 10,
|
66 |
|
|
UAV_DATA_W = 32,
|
67 |
|
|
|
68 |
|
|
AV_CONSTANT_BURST_BEHAVIOR = 0,
|
69 |
|
|
UAV_CONSTANT_BURST_BEHAVIOR = 0,
|
70 |
|
|
CHIPSELECT_THROUGH_READLATENCY = 0,
|
71 |
|
|
|
72 |
|
|
// Tightly-Coupled Options
|
73 |
|
|
USE_UAV_CLKEN = 0,
|
74 |
|
|
AV_REQUIRE_UNALIGNED_ADDRESSES = 0
|
75 |
|
|
) (
|
76 |
|
|
|
77 |
|
|
// -------------------
|
78 |
|
|
// Clock & Reset
|
79 |
|
|
// -------------------
|
80 |
|
|
input wire clk,
|
81 |
|
|
input wire reset,
|
82 |
|
|
|
83 |
|
|
// -------------------
|
84 |
|
|
// Universal Avalon Slave
|
85 |
|
|
// -------------------
|
86 |
|
|
|
87 |
|
|
input wire [UAV_ADDRESS_W - 1 : 0] uav_address,
|
88 |
|
|
input wire [UAV_DATA_W - 1 : 0] uav_writedata,
|
89 |
|
|
input wire uav_write,
|
90 |
|
|
input wire uav_read,
|
91 |
|
|
input wire [UAV_BURSTCOUNT_W - 1 : 0] uav_burstcount,
|
92 |
|
|
input wire [UAV_BYTEENABLE_W - 1 : 0] uav_byteenable,
|
93 |
|
|
input wire uav_lock,
|
94 |
|
|
input wire uav_debugaccess,
|
95 |
|
|
input wire uav_clken,
|
96 |
|
|
|
97 |
|
|
output logic uav_readdatavalid,
|
98 |
|
|
output logic uav_waitrequest,
|
99 |
|
|
output logic [UAV_DATA_W - 1 : 0] uav_readdata,
|
100 |
|
|
output logic [1:0] uav_response,
|
101 |
|
|
// input wire uav_writeresponserequest,
|
102 |
|
|
output logic uav_writeresponsevalid,
|
103 |
|
|
|
104 |
|
|
// -------------------
|
105 |
|
|
// Customizable Avalon Master
|
106 |
|
|
// -------------------
|
107 |
|
|
output logic [AV_ADDRESS_W - 1 : 0] av_address,
|
108 |
|
|
output logic [AV_DATA_W - 1 : 0] av_writedata,
|
109 |
|
|
output logic av_write,
|
110 |
|
|
output logic av_read,
|
111 |
|
|
output logic [AV_BURSTCOUNT_W - 1 : 0] av_burstcount,
|
112 |
|
|
output logic [AV_BYTEENABLE_W - 1 : 0] av_byteenable,
|
113 |
|
|
output logic [AV_BYTEENABLE_W - 1 : 0] av_writebyteenable,
|
114 |
|
|
output logic av_begintransfer,
|
115 |
|
|
output wire av_chipselect,
|
116 |
|
|
output logic av_beginbursttransfer,
|
117 |
|
|
output logic av_lock,
|
118 |
|
|
output wire av_clken,
|
119 |
|
|
output wire av_debugaccess,
|
120 |
|
|
output wire av_outputenable,
|
121 |
|
|
|
122 |
|
|
input logic [AV_DATA_W - 1 : 0] av_readdata,
|
123 |
|
|
input logic av_readdatavalid,
|
124 |
|
|
input logic av_waitrequest,
|
125 |
|
|
|
126 |
|
|
input logic [1:0] av_response,
|
127 |
|
|
// output logic av_writeresponserequest,
|
128 |
|
|
input wire av_writeresponsevalid
|
129 |
|
|
|
130 |
|
|
);
|
131 |
|
|
|
132 |
|
|
function integer clog2_plusone;
|
133 |
|
|
input [31:0] Depth;
|
134 |
|
|
integer i;
|
135 |
|
|
begin
|
136 |
|
|
i = Depth;
|
137 |
|
|
for(clog2_plusone = 0; i > 0; clog2_plusone = clog2_plusone + 1)
|
138 |
|
|
i = i >> 1;
|
139 |
|
|
end
|
140 |
|
|
endfunction
|
141 |
|
|
|
142 |
|
|
function integer max;
|
143 |
|
|
//returns the larger of two passed arguments
|
144 |
|
|
input [31:0] one;
|
145 |
|
|
input [31:0] two;
|
146 |
|
|
if(one > two)
|
147 |
|
|
max=one;
|
148 |
|
|
else
|
149 |
|
|
max=two;
|
150 |
|
|
endfunction // int
|
151 |
|
|
|
152 |
|
|
localparam AV_READ_WAIT_INDEXED = (AV_SETUP_WAIT_CYCLES + AV_READ_WAIT_CYCLES);
|
153 |
|
|
localparam AV_WRITE_WAIT_INDEXED = (AV_SETUP_WAIT_CYCLES + AV_WRITE_WAIT_CYCLES);
|
154 |
|
|
localparam AV_DATA_HOLD_INDEXED = (AV_WRITE_WAIT_INDEXED + AV_DATA_HOLD_CYCLES);
|
155 |
|
|
localparam LOG2_OF_LATENCY_SUM = max(clog2_plusone(AV_READ_WAIT_INDEXED + 1),clog2_plusone(AV_DATA_HOLD_INDEXED + 1));
|
156 |
|
|
localparam BURSTCOUNT_SHIFT_SELECTOR = AV_BURSTCOUNT_SYMBOLS ? 0 : BITS_PER_WORD;
|
157 |
|
|
localparam ADDRESS_SHIFT_SELECTOR = AV_ADDRESS_SYMBOLS ? 0 : BITS_PER_WORD;
|
158 |
|
|
localparam ADDRESS_HIGH = ( UAV_ADDRESS_W > AV_ADDRESS_W + ADDRESS_SHIFT_SELECTOR ) ?
|
159 |
|
|
AV_ADDRESS_W :
|
160 |
|
|
UAV_ADDRESS_W - ADDRESS_SHIFT_SELECTOR;
|
161 |
|
|
localparam BURSTCOUNT_HIGH = ( UAV_BURSTCOUNT_W > AV_BURSTCOUNT_W + BURSTCOUNT_SHIFT_SELECTOR ) ?
|
162 |
|
|
AV_BURSTCOUNT_W :
|
163 |
|
|
UAV_BURSTCOUNT_W - BURSTCOUNT_SHIFT_SELECTOR;
|
164 |
|
|
localparam BYTEENABLE_ADDRESS_BITS = ( clog2_plusone(UAV_BYTEENABLE_W) - 1 ) >= 1 ? clog2_plusone(UAV_BYTEENABLE_W) - 1 : 1;
|
165 |
|
|
|
166 |
|
|
|
167 |
|
|
// Calculate the symbols per word as the power of 2 extended symbols per word
|
168 |
|
|
wire [31 : 0] symbols_per_word_int = 2**(clog2_plusone(AV_SYMBOLS_PER_WORD[UAV_BURSTCOUNT_W : 0] - 1));
|
169 |
|
|
wire [UAV_BURSTCOUNT_W-1 : 0] symbols_per_word = symbols_per_word_int[UAV_BURSTCOUNT_W-1 : 0];
|
170 |
|
|
|
171 |
|
|
// +--------------------------------
|
172 |
|
|
// |Backwards Compatibility Signals
|
173 |
|
|
// +--------------------------------
|
174 |
|
|
assign av_clken = (USE_UAV_CLKEN) ? uav_clken : 1'b1;
|
175 |
|
|
assign av_debugaccess = uav_debugaccess;
|
176 |
|
|
|
177 |
|
|
// +-------------------
|
178 |
|
|
// |Passthru Signals
|
179 |
|
|
// +-------------------
|
180 |
|
|
|
181 |
|
|
reg [1 : 0] av_response_delayed;
|
182 |
|
|
|
183 |
|
|
always @(posedge clk, posedge reset) begin
|
184 |
|
|
if (reset) begin
|
185 |
|
|
av_response_delayed <= 2'b0;
|
186 |
|
|
end else begin
|
187 |
|
|
av_response_delayed <= av_response;
|
188 |
|
|
end
|
189 |
|
|
end
|
190 |
|
|
|
191 |
|
|
always_comb
|
192 |
|
|
begin
|
193 |
|
|
if (!USE_READRESPONSE && !USE_WRITERESPONSE) begin
|
194 |
|
|
uav_response = '0;
|
195 |
|
|
end else begin
|
196 |
|
|
if (AV_READLATENCY != 0 || USE_READDATAVALID) begin
|
197 |
|
|
uav_response = av_response;
|
198 |
|
|
end else begin
|
199 |
|
|
uav_response = av_response_delayed;
|
200 |
|
|
end
|
201 |
|
|
end
|
202 |
|
|
end
|
203 |
|
|
// assign av_writeresponserequest = uav_writeresponserequest;
|
204 |
|
|
assign uav_writeresponsevalid = av_writeresponsevalid;
|
205 |
|
|
|
206 |
|
|
//-------------------------
|
207 |
|
|
//Writedata and Byteenable
|
208 |
|
|
//-------------------------
|
209 |
|
|
|
210 |
|
|
always@* begin
|
211 |
|
|
av_byteenable = '0;
|
212 |
|
|
av_byteenable = uav_byteenable[AV_BYTEENABLE_W - 1 : 0];
|
213 |
|
|
end
|
214 |
|
|
|
215 |
|
|
always@* begin
|
216 |
|
|
av_writedata = '0;
|
217 |
|
|
av_writedata = uav_writedata[AV_DATA_W - 1 : 0];
|
218 |
|
|
end
|
219 |
|
|
|
220 |
|
|
// +-------------------
|
221 |
|
|
// |Calculated Signals
|
222 |
|
|
// +-------------------
|
223 |
|
|
|
224 |
|
|
logic [UAV_ADDRESS_W - 1 : 0 ] real_uav_address;
|
225 |
|
|
|
226 |
|
|
function [BYTEENABLE_ADDRESS_BITS - 1 : 0 ] decode_byteenable;
|
227 |
|
|
input [UAV_BYTEENABLE_W - 1 : 0 ] byteenable;
|
228 |
|
|
|
229 |
|
|
for(int i = 0 ; i < UAV_BYTEENABLE_W; i++ ) begin
|
230 |
|
|
if(byteenable[i] == 1) begin
|
231 |
|
|
return i;
|
232 |
|
|
end
|
233 |
|
|
end
|
234 |
|
|
|
235 |
|
|
return '0;
|
236 |
|
|
|
237 |
|
|
endfunction
|
238 |
|
|
|
239 |
|
|
reg [AV_BURSTCOUNT_W - 1 : 0] burstcount_reg;
|
240 |
|
|
reg [AV_ADDRESS_W - 1 : 0] address_reg;
|
241 |
|
|
always@(posedge clk, posedge reset) begin
|
242 |
|
|
if(reset) begin
|
243 |
|
|
burstcount_reg <= '0;
|
244 |
|
|
address_reg <= '0;
|
245 |
|
|
end else begin
|
246 |
|
|
burstcount_reg <= burstcount_reg;
|
247 |
|
|
address_reg <= address_reg;
|
248 |
|
|
if(av_beginbursttransfer) begin
|
249 |
|
|
burstcount_reg <= uav_burstcount [ BURSTCOUNT_HIGH - 1 + BURSTCOUNT_SHIFT_SELECTOR : BURSTCOUNT_SHIFT_SELECTOR ];
|
250 |
|
|
address_reg <= real_uav_address [ ADDRESS_HIGH - 1 + ADDRESS_SHIFT_SELECTOR : ADDRESS_SHIFT_SELECTOR ];
|
251 |
|
|
end
|
252 |
|
|
end
|
253 |
|
|
end
|
254 |
|
|
|
255 |
|
|
logic [BYTEENABLE_ADDRESS_BITS-1:0] temp_wire;
|
256 |
|
|
|
257 |
|
|
always@* begin
|
258 |
|
|
if( AV_REQUIRE_UNALIGNED_ADDRESSES == 1) begin
|
259 |
|
|
temp_wire = decode_byteenable(uav_byteenable);
|
260 |
|
|
real_uav_address = { uav_address[UAV_ADDRESS_W - 1 : BYTEENABLE_ADDRESS_BITS ], temp_wire[BYTEENABLE_ADDRESS_BITS - 1 : 0 ] };
|
261 |
|
|
end else begin
|
262 |
|
|
real_uav_address = uav_address;
|
263 |
|
|
end
|
264 |
|
|
|
265 |
|
|
av_address = real_uav_address[ADDRESS_HIGH - 1 + ADDRESS_SHIFT_SELECTOR : ADDRESS_SHIFT_SELECTOR ];
|
266 |
|
|
if( AV_CONSTANT_BURST_BEHAVIOR && !UAV_CONSTANT_BURST_BEHAVIOR && ~av_beginbursttransfer )
|
267 |
|
|
av_address = address_reg;
|
268 |
|
|
end
|
269 |
|
|
|
270 |
|
|
always@* begin
|
271 |
|
|
av_burstcount=uav_burstcount[BURSTCOUNT_HIGH - 1 + BURSTCOUNT_SHIFT_SELECTOR : BURSTCOUNT_SHIFT_SELECTOR ];
|
272 |
|
|
if( AV_CONSTANT_BURST_BEHAVIOR && !UAV_CONSTANT_BURST_BEHAVIOR && ~av_beginbursttransfer )
|
273 |
|
|
av_burstcount = burstcount_reg;
|
274 |
|
|
end
|
275 |
|
|
|
276 |
|
|
always@* begin
|
277 |
|
|
av_lock = uav_lock;
|
278 |
|
|
end
|
279 |
|
|
|
280 |
|
|
// -------------------
|
281 |
|
|
// Writebyteenable Assignment
|
282 |
|
|
// -------------------
|
283 |
|
|
always@* begin
|
284 |
|
|
av_writebyteenable = { (AV_BYTEENABLE_W){uav_write} } & uav_byteenable[AV_BYTEENABLE_W - 1 : 0];
|
285 |
|
|
end
|
286 |
|
|
|
287 |
|
|
// -------------------
|
288 |
|
|
// Waitrequest Assignment
|
289 |
|
|
// -------------------
|
290 |
|
|
|
291 |
|
|
reg av_waitrequest_generated;
|
292 |
|
|
reg av_waitrequest_generated_read;
|
293 |
|
|
reg av_waitrequest_generated_write;
|
294 |
|
|
reg waitrequest_reset_override;
|
295 |
|
|
reg [ ( LOG2_OF_LATENCY_SUM ? LOG2_OF_LATENCY_SUM - 1 : 0 ) : 0 ] wait_latency_counter;
|
296 |
|
|
|
297 |
|
|
always@(posedge reset, posedge clk) begin
|
298 |
|
|
if(reset) begin
|
299 |
|
|
wait_latency_counter <= '0;
|
300 |
|
|
waitrequest_reset_override <= 1'h1;
|
301 |
|
|
end else begin
|
302 |
|
|
waitrequest_reset_override <= 1'h0;
|
303 |
|
|
wait_latency_counter <= '0;
|
304 |
|
|
if( ~uav_waitrequest | waitrequest_reset_override )
|
305 |
|
|
wait_latency_counter <= '0;
|
306 |
|
|
else if( uav_read | uav_write )
|
307 |
|
|
wait_latency_counter <= wait_latency_counter + 1'h1;
|
308 |
|
|
end
|
309 |
|
|
end
|
310 |
|
|
|
311 |
|
|
|
312 |
|
|
always @* begin
|
313 |
|
|
|
314 |
|
|
av_read = uav_read;
|
315 |
|
|
av_write = uav_write;
|
316 |
|
|
av_waitrequest_generated = 1'h1;
|
317 |
|
|
av_waitrequest_generated_read = 1'h1;
|
318 |
|
|
av_waitrequest_generated_write = 1'h1;
|
319 |
|
|
|
320 |
|
|
if(LOG2_OF_LATENCY_SUM == 1)
|
321 |
|
|
av_waitrequest_generated = 0;
|
322 |
|
|
|
323 |
|
|
if(LOG2_OF_LATENCY_SUM > 1 && !USE_WAITREQUEST) begin
|
324 |
|
|
av_read = wait_latency_counter >= AV_SETUP_WAIT_CYCLES && uav_read;
|
325 |
|
|
av_write = wait_latency_counter >= AV_SETUP_WAIT_CYCLES && uav_write && wait_latency_counter <= AV_WRITE_WAIT_INDEXED;
|
326 |
|
|
av_waitrequest_generated_read = wait_latency_counter != AV_READ_WAIT_INDEXED;
|
327 |
|
|
av_waitrequest_generated_write = wait_latency_counter != AV_DATA_HOLD_INDEXED;
|
328 |
|
|
|
329 |
|
|
if(uav_write)
|
330 |
|
|
av_waitrequest_generated = av_waitrequest_generated_write;
|
331 |
|
|
else
|
332 |
|
|
av_waitrequest_generated = av_waitrequest_generated_read;
|
333 |
|
|
|
334 |
|
|
end
|
335 |
|
|
|
336 |
|
|
if(USE_WAITREQUEST) begin
|
337 |
|
|
uav_waitrequest = av_waitrequest;
|
338 |
|
|
end else begin
|
339 |
|
|
uav_waitrequest = av_waitrequest_generated | waitrequest_reset_override;
|
340 |
|
|
end
|
341 |
|
|
|
342 |
|
|
end
|
343 |
|
|
|
344 |
|
|
// --------------
|
345 |
|
|
// Readdata Assignment
|
346 |
|
|
// --------------
|
347 |
|
|
|
348 |
|
|
reg[(AV_DATA_W ? AV_DATA_W -1 : 0 ): 0] av_readdata_pre;
|
349 |
|
|
|
350 |
|
|
always@(posedge clk, posedge reset) begin
|
351 |
|
|
if(reset)
|
352 |
|
|
av_readdata_pre <= 'b0;
|
353 |
|
|
else
|
354 |
|
|
av_readdata_pre <= av_readdata;
|
355 |
|
|
end
|
356 |
|
|
|
357 |
|
|
always@* begin
|
358 |
|
|
uav_readdata = {UAV_DATA_W{1'b0}};
|
359 |
|
|
if( AV_READLATENCY != 0 || USE_READDATAVALID ) begin
|
360 |
|
|
uav_readdata[AV_DATA_W-1:0] = av_readdata;
|
361 |
|
|
end else begin
|
362 |
|
|
uav_readdata[AV_DATA_W-1:0] = av_readdata_pre;
|
363 |
|
|
end
|
364 |
|
|
end
|
365 |
|
|
|
366 |
|
|
// -------------------
|
367 |
|
|
// Readdatavalid Assigment
|
368 |
|
|
// -------------------
|
369 |
|
|
reg[(AV_READLATENCY>0 ? AV_READLATENCY-1:0) :0] read_latency_shift_reg;
|
370 |
|
|
reg top_read_latency_shift_reg;
|
371 |
|
|
|
372 |
|
|
always@* begin
|
373 |
|
|
uav_readdatavalid=top_read_latency_shift_reg;
|
374 |
|
|
if(USE_READDATAVALID) begin
|
375 |
|
|
uav_readdatavalid = av_readdatavalid;
|
376 |
|
|
end
|
377 |
|
|
end
|
378 |
|
|
|
379 |
|
|
always@* begin
|
380 |
|
|
top_read_latency_shift_reg = uav_read & ~uav_waitrequest & ~waitrequest_reset_override;
|
381 |
|
|
if(AV_READLATENCY == 1 || AV_READLATENCY == 0 ) begin
|
382 |
|
|
top_read_latency_shift_reg=read_latency_shift_reg;
|
383 |
|
|
end
|
384 |
|
|
if (AV_READLATENCY > 1) begin
|
385 |
|
|
top_read_latency_shift_reg = read_latency_shift_reg[(AV_READLATENCY ? AV_READLATENCY-1 : 0)];
|
386 |
|
|
end
|
387 |
|
|
end
|
388 |
|
|
|
389 |
|
|
always@(posedge reset, posedge clk) begin
|
390 |
|
|
if (reset) begin
|
391 |
|
|
read_latency_shift_reg <= '0;
|
392 |
|
|
end else if (av_clken) begin
|
393 |
|
|
read_latency_shift_reg[0] <= uav_read && ~uav_waitrequest & ~waitrequest_reset_override;
|
394 |
|
|
for (int i=0; i+1 < AV_READLATENCY ; i+=1 ) begin
|
395 |
|
|
read_latency_shift_reg[i+1] <= read_latency_shift_reg[i];
|
396 |
|
|
end
|
397 |
|
|
end
|
398 |
|
|
end
|
399 |
|
|
|
400 |
|
|
// ------------
|
401 |
|
|
// Chipselect and OutputEnable
|
402 |
|
|
// ------------
|
403 |
|
|
reg av_chipselect_pre;
|
404 |
|
|
wire cs_extension;
|
405 |
|
|
reg av_outputenable_pre;
|
406 |
|
|
|
407 |
|
|
assign av_chipselect = (uav_read | uav_write) ? 1'b1 : av_chipselect_pre;
|
408 |
|
|
assign cs_extension = ( (^ read_latency_shift_reg) & ~top_read_latency_shift_reg ) | ((| read_latency_shift_reg) & ~(^ read_latency_shift_reg));
|
409 |
|
|
assign av_outputenable = uav_read ? 1'b1 : av_outputenable_pre;
|
410 |
|
|
|
411 |
|
|
always@(posedge reset, posedge clk) begin
|
412 |
|
|
if(reset)
|
413 |
|
|
av_outputenable_pre <= 1'b0;
|
414 |
|
|
else if( AV_READLATENCY == 0 && AV_READ_WAIT_INDEXED != 0 )
|
415 |
|
|
av_outputenable_pre <= 0;
|
416 |
|
|
else
|
417 |
|
|
av_outputenable_pre <= cs_extension | uav_read;
|
418 |
|
|
end
|
419 |
|
|
|
420 |
|
|
always@(posedge reset, posedge clk) begin
|
421 |
|
|
if(reset) begin
|
422 |
|
|
av_chipselect_pre <= 1'b0;
|
423 |
|
|
end else begin
|
424 |
|
|
av_chipselect_pre <= 1'b0;
|
425 |
|
|
if(AV_READLATENCY != 0 && CHIPSELECT_THROUGH_READLATENCY == 1) begin
|
426 |
|
|
//The AV_READLATENCY term is only here to prevent chipselect from remaining asserted while read and write fall.
|
427 |
|
|
//There is no functional impact as 0 cycle transactions are treated as 1 cycle on the other side of the translator.
|
428 |
|
|
if(uav_read) begin
|
429 |
|
|
av_chipselect_pre <= 1'b1;
|
430 |
|
|
end else if(cs_extension == 1) begin
|
431 |
|
|
av_chipselect_pre <= 1'b1;
|
432 |
|
|
end
|
433 |
|
|
end
|
434 |
|
|
end
|
435 |
|
|
end
|
436 |
|
|
|
437 |
|
|
// -------------------
|
438 |
|
|
// Begintransfer Assigment
|
439 |
|
|
// -------------------
|
440 |
|
|
reg end_begintransfer;
|
441 |
|
|
|
442 |
|
|
always@* begin
|
443 |
|
|
av_begintransfer = ( uav_write | uav_read ) & ~end_begintransfer;
|
444 |
|
|
end
|
445 |
|
|
|
446 |
|
|
always@ ( posedge clk or posedge reset ) begin
|
447 |
|
|
if(reset) begin
|
448 |
|
|
end_begintransfer <= 1'b0;
|
449 |
|
|
end else begin
|
450 |
|
|
if(av_begintransfer == 1 && uav_waitrequest && ~waitrequest_reset_override)
|
451 |
|
|
end_begintransfer <= 1'b1;
|
452 |
|
|
else if(uav_waitrequest)
|
453 |
|
|
end_begintransfer <= end_begintransfer;
|
454 |
|
|
else
|
455 |
|
|
end_begintransfer <= 1'b0;
|
456 |
|
|
end
|
457 |
|
|
end
|
458 |
|
|
|
459 |
|
|
// -------------------
|
460 |
|
|
// Beginbursttransfer Assigment
|
461 |
|
|
// -------------------
|
462 |
|
|
reg end_beginbursttransfer;
|
463 |
|
|
reg in_transfer;
|
464 |
|
|
|
465 |
|
|
always@* begin
|
466 |
|
|
av_beginbursttransfer = uav_read ? av_begintransfer : (av_begintransfer && ~end_beginbursttransfer && ~in_transfer);
|
467 |
|
|
end
|
468 |
|
|
|
469 |
|
|
always@ ( posedge clk or posedge reset ) begin
|
470 |
|
|
if(reset) begin
|
471 |
|
|
end_beginbursttransfer <= 1'b0;
|
472 |
|
|
in_transfer <= 1'b0;
|
473 |
|
|
end else begin
|
474 |
|
|
end_beginbursttransfer <= uav_write & ( uav_burstcount != symbols_per_word );
|
475 |
|
|
if(uav_write && uav_burstcount == symbols_per_word)
|
476 |
|
|
in_transfer <=1'b0;
|
477 |
|
|
else if(uav_write)
|
478 |
|
|
in_transfer <=1'b1;
|
479 |
|
|
end
|
480 |
|
|
end
|
481 |
|
|
|
482 |
|
|
endmodule
|