altera_merlin_slave_translator.sv 16 KB

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