altera_merlin_slave_agent.sv 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622
  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. // (C) 2001-2011 Altera Corporation. All rights reserved.
  13. // Your use of Altera Corporation's design tools, logic functions and other
  14. // software and tools, and its AMPP partner logic functions, and any output
  15. // files any of the foregoing (including device programming or simulation
  16. // files), and any associated documentation or information are expressly subject
  17. // to the terms and conditions of the Altera Program License Subscription
  18. // Agreement, Altera MegaCore Function License Agreement, or other applicable
  19. // license agreement, including, without limitation, that your use is for the
  20. // sole purpose of programming logic devices manufactured by Altera and sold by
  21. // Altera or its authorized distributors. Please refer to the applicable
  22. // agreement for further details.
  23. // $Id: //acds/rel/19.1std/ip/merlin/altera_merlin_slave_agent/altera_merlin_slave_agent.sv#1 $
  24. // $Revision: #1 $
  25. // $Date: 2018/11/07 $
  26. // $Author: psgswbuild $
  27. `timescale 1 ns / 1 ns
  28. module altera_merlin_slave_agent
  29. #(
  30. // Packet parameters
  31. parameter PKT_BEGIN_BURST = 81,
  32. parameter PKT_DATA_H = 31,
  33. parameter PKT_DATA_L = 0,
  34. parameter PKT_SYMBOL_W = 8,
  35. parameter PKT_BYTEEN_H = 71,
  36. parameter PKT_BYTEEN_L = 68,
  37. parameter PKT_ADDR_H = 63,
  38. parameter PKT_ADDR_L = 32,
  39. parameter PKT_TRANS_LOCK = 87,
  40. parameter PKT_TRANS_COMPRESSED_READ = 67,
  41. parameter PKT_TRANS_POSTED = 66,
  42. parameter PKT_TRANS_WRITE = 65,
  43. parameter PKT_TRANS_READ = 64,
  44. parameter PKT_SRC_ID_H = 74,
  45. parameter PKT_SRC_ID_L = 72,
  46. parameter PKT_DEST_ID_H = 77,
  47. parameter PKT_DEST_ID_L = 75,
  48. parameter PKT_BURSTWRAP_H = 85,
  49. parameter PKT_BURSTWRAP_L = 82,
  50. parameter PKT_BYTE_CNT_H = 81,
  51. parameter PKT_BYTE_CNT_L = 78,
  52. parameter PKT_PROTECTION_H = 86,
  53. parameter PKT_PROTECTION_L = 86,
  54. parameter PKT_RESPONSE_STATUS_H = 89,
  55. parameter PKT_RESPONSE_STATUS_L = 88,
  56. parameter PKT_BURST_SIZE_H = 92,
  57. parameter PKT_BURST_SIZE_L = 90,
  58. parameter PKT_ORI_BURST_SIZE_L = 93,
  59. parameter PKT_ORI_BURST_SIZE_H = 95,
  60. parameter ST_DATA_W = 96,
  61. parameter ST_CHANNEL_W = 32,
  62. // Slave parameters
  63. parameter ADDR_W = PKT_ADDR_H - PKT_ADDR_L + 1,
  64. parameter AVS_DATA_W = PKT_DATA_H - PKT_DATA_L + 1,
  65. parameter AVS_BURSTCOUNT_W = 4,
  66. parameter PKT_SYMBOLS = AVS_DATA_W / PKT_SYMBOL_W,
  67. // Slave agent parameters
  68. parameter PREVENT_FIFO_OVERFLOW = 0,
  69. parameter SUPPRESS_0_BYTEEN_CMD = 1,
  70. parameter USE_READRESPONSE = 0,
  71. parameter USE_WRITERESPONSE = 0,
  72. // Derived slave parameters
  73. parameter AVS_BE_W = PKT_BYTEEN_H - PKT_BYTEEN_L + 1,
  74. parameter BURST_SIZE_W = 3,
  75. // Derived FIFO width
  76. parameter FIFO_DATA_W = ST_DATA_W + 1,
  77. // ECC parameter
  78. parameter ECC_ENABLE = 0
  79. ) (
  80. input clk,
  81. input reset,
  82. // Universal-Avalon anti-slave
  83. output [ADDR_W-1:0] m0_address,
  84. output [AVS_BURSTCOUNT_W-1:0] m0_burstcount,
  85. output [AVS_BE_W-1:0] m0_byteenable,
  86. output m0_read,
  87. input [AVS_DATA_W-1:0] m0_readdata,
  88. input m0_waitrequest,
  89. output m0_write,
  90. output [AVS_DATA_W-1:0] m0_writedata,
  91. input m0_readdatavalid,
  92. output m0_debugaccess,
  93. output m0_lock,
  94. input [1:0] m0_response,
  95. input m0_writeresponsevalid,
  96. // Avalon-ST FIFO interfaces.
  97. // Note: there's no need to include the "data" field here, at least for
  98. // reads, since readdata is filled in from slave info. To keep life
  99. // simple, have a data field, but fill it with 0s.
  100. // Av-st response fifo source interface
  101. output reg [FIFO_DATA_W-1:0] rf_source_data,
  102. output rf_source_valid,
  103. output rf_source_startofpacket,
  104. output rf_source_endofpacket,
  105. input rf_source_ready,
  106. // Av-st response fifo sink interface
  107. input [FIFO_DATA_W-1:0] rf_sink_data,
  108. input rf_sink_valid,
  109. input rf_sink_startofpacket,
  110. input rf_sink_endofpacket,
  111. output rf_sink_ready,
  112. // Av-st readdata fifo src interface, data and response
  113. // extra 2 bits for storing RESPONSE STATUS
  114. output [AVS_DATA_W+1:0] rdata_fifo_src_data,
  115. output rdata_fifo_src_valid,
  116. input rdata_fifo_src_ready,
  117. // Av-st readdata fifo sink interface
  118. input [AVS_DATA_W+1:0] rdata_fifo_sink_data,
  119. input rdata_fifo_sink_valid,
  120. output rdata_fifo_sink_ready,
  121. input rdata_fifo_sink_error,
  122. // Av-st sink command packet interface
  123. output cp_ready,
  124. input cp_valid,
  125. input [ST_DATA_W-1:0] cp_data,
  126. input [ST_CHANNEL_W-1:0] cp_channel,
  127. input cp_startofpacket,
  128. input cp_endofpacket,
  129. // Av-st source response packet interface
  130. input rp_ready,
  131. output reg rp_valid,
  132. output reg [ST_DATA_W-1:0] rp_data,
  133. output rp_startofpacket,
  134. output rp_endofpacket
  135. );
  136. // --------------------------------------------------
  137. // Ceil(log2()) function log2ceil of 4 = 2
  138. // --------------------------------------------------
  139. function integer log2ceil;
  140. input reg[63:0] val;
  141. reg [63:0] i;
  142. begin
  143. i = 1;
  144. log2ceil = 0;
  145. while (i < val) begin
  146. log2ceil = log2ceil + 1;
  147. i = i << 1;
  148. end
  149. end
  150. endfunction
  151. // ------------------------------------------------
  152. // Local Parameters
  153. // ------------------------------------------------
  154. localparam DATA_W = PKT_DATA_H - PKT_DATA_L + 1;
  155. localparam BE_W = PKT_BYTEEN_H - PKT_BYTEEN_L + 1;
  156. localparam MID_W = PKT_SRC_ID_H - PKT_SRC_ID_L + 1;
  157. localparam SID_W = PKT_DEST_ID_H - PKT_DEST_ID_L + 1;
  158. localparam BYTE_CNT_W = PKT_BYTE_CNT_H - PKT_BYTE_CNT_L + 1;
  159. localparam BURSTWRAP_W = PKT_BURSTWRAP_H - PKT_BURSTWRAP_L + 1;
  160. localparam BURSTSIZE_W = PKT_BURST_SIZE_H - PKT_BURST_SIZE_L + 1;
  161. localparam BITS_TO_MASK = log2ceil(PKT_SYMBOLS);
  162. localparam MAX_BURST = 1 << (AVS_BURSTCOUNT_W - 1);
  163. localparam BURSTING = (MAX_BURST > PKT_SYMBOLS);
  164. // ------------------------------------------------
  165. // Signals
  166. // ------------------------------------------------
  167. wire [DATA_W-1:0] cmd_data;
  168. wire [BE_W-1:0] cmd_byteen;
  169. wire [ADDR_W-1:0] cmd_addr;
  170. wire [MID_W-1:0] cmd_mid;
  171. wire [SID_W-1:0] cmd_sid;
  172. wire cmd_read;
  173. wire cmd_write;
  174. wire cmd_compressed;
  175. wire cmd_posted;
  176. wire [BYTE_CNT_W-1:0] cmd_byte_cnt;
  177. wire [BURSTWRAP_W-1:0] cmd_burstwrap;
  178. wire [BURSTSIZE_W-1:0] cmd_burstsize;
  179. wire cmd_debugaccess;
  180. wire suppress_cmd;
  181. wire byteen_asserted;
  182. wire suppress_read;
  183. wire suppress_write;
  184. wire needs_response_synthesis;
  185. wire generate_response;
  186. // Assign command fields
  187. assign cmd_data = cp_data[PKT_DATA_H :PKT_DATA_L ];
  188. assign cmd_byteen = cp_data[PKT_BYTEEN_H:PKT_BYTEEN_L];
  189. assign cmd_addr = cp_data[PKT_ADDR_H :PKT_ADDR_L ];
  190. assign cmd_compressed = cp_data[PKT_TRANS_COMPRESSED_READ];
  191. assign cmd_posted = cp_data[PKT_TRANS_POSTED];
  192. assign cmd_write = cp_data[PKT_TRANS_WRITE];
  193. assign cmd_read = cp_data[PKT_TRANS_READ];
  194. assign cmd_mid = cp_data[PKT_SRC_ID_H :PKT_SRC_ID_L];
  195. assign cmd_sid = cp_data[PKT_DEST_ID_H:PKT_DEST_ID_L];
  196. assign cmd_byte_cnt = cp_data[PKT_BYTE_CNT_H:PKT_BYTE_CNT_L];
  197. assign cmd_burstwrap = cp_data[PKT_BURSTWRAP_H:PKT_BURSTWRAP_L];
  198. assign cmd_burstsize = cp_data[PKT_BURST_SIZE_H:PKT_BURST_SIZE_L];
  199. assign cmd_debugaccess = cp_data[PKT_PROTECTION_L];
  200. // Local "ready_for_command" signal: deasserted when the agent is unable to accept
  201. // another command, e.g. rdv FIFO is full, (local readdata storage is full &&
  202. // ~rp_ready), ...
  203. // Say, this could depend on the type of command, for example, even if the
  204. // rdv FIFO is full, a write request can be accepted. For later.
  205. wire ready_for_command;
  206. wire local_lock = cp_valid & cp_data[PKT_TRANS_LOCK];
  207. wire local_write = cp_valid & cp_data[PKT_TRANS_WRITE];
  208. wire local_read = cp_valid & cp_data[PKT_TRANS_READ];
  209. wire local_compressed_read = cp_valid & cp_data[PKT_TRANS_COMPRESSED_READ];
  210. wire nonposted_write_endofpacket = ~cp_data[PKT_TRANS_POSTED] & local_write & cp_endofpacket;
  211. // num_symbols is PKT_SYMBOLS, appropriately sized.
  212. wire [31:0] int_num_symbols = PKT_SYMBOLS;
  213. wire [BYTE_CNT_W-1:0] num_symbols = int_num_symbols[BYTE_CNT_W-1:0];
  214. generate
  215. if (PREVENT_FIFO_OVERFLOW) begin : prevent_fifo_overflow_block
  216. // ---------------------------------------------------
  217. // Backpressure if the slave says to, or if FIFO overflow may occur.
  218. //
  219. // All commands are backpressured once the FIFO is full
  220. // even if they don't need storage. This breaks a long
  221. // combinatorial path from the master read/write through
  222. // this logic and back to the master via the backpressure
  223. // path.
  224. //
  225. // To avoid a loss of throughput the FIFO will be parameterized
  226. // one slot deeper. The extra slot should never be used in normal
  227. // operation, but should a slave misbehave and accept one more
  228. // read than it should then backpressure will kick in.
  229. //
  230. // An example: assume a slave with MPRT = 2. It can accept a
  231. // command sequence RRWW without backpressuring. If the FIFO is
  232. // only 2 deep, we'd backpressure the writes leading to loss of
  233. // throughput. If the FIFO is 3 deep, we'll only backpressure when
  234. // RRR... which is an illegal condition anyway.
  235. // ---------------------------------------------------
  236. assign ready_for_command = rf_source_ready;
  237. assign cp_ready = (~m0_waitrequest | suppress_cmd) && ready_for_command;
  238. end else begin : no_prevent_fifo_overflow_block
  239. // Do not suppress the command or the slave will
  240. // not be able to waitrequest
  241. assign ready_for_command = 1'b1;
  242. // Backpressure only if the slave says to.
  243. assign cp_ready = ~m0_waitrequest | suppress_cmd;
  244. end
  245. endgenerate
  246. generate if (SUPPRESS_0_BYTEEN_CMD && !BURSTING) begin : suppress_0_byteen_cmd_non_bursting
  247. assign byteen_asserted = |cmd_byteen;
  248. assign suppress_read = ~byteen_asserted;
  249. assign suppress_write = ~byteen_asserted;
  250. assign suppress_cmd = ~byteen_asserted;
  251. end else if (SUPPRESS_0_BYTEEN_CMD && BURSTING) begin: suppress_0_byteen_cmd_bursting
  252. assign byteen_asserted = |cmd_byteen;
  253. assign suppress_read = ~byteen_asserted;
  254. assign suppress_write = 1'b0;
  255. assign suppress_cmd = ~byteen_asserted && cmd_read;
  256. end else begin : no_suppress_0_byteen_cmd
  257. assign suppress_read = 1'b0;
  258. assign suppress_write = 1'b0;
  259. assign suppress_cmd = 1'b0;
  260. end
  261. endgenerate
  262. // -------------------------------------------------------------------
  263. // Extract avalon signals from command packet.
  264. // -------------------------------------------------------------------
  265. // Mask off the lower bits of address.
  266. // The burst adapter before this component will break narrow sized packets
  267. // into sub-bursts of length 1. However, the packet addresses are preserved,
  268. // which means this component may see size-aligned addresses.
  269. //
  270. // Masking ensures that the addresses seen by an Avalon slave are aligned to
  271. // the full data width instead of the size.
  272. //
  273. // Example:
  274. // output from burst adapter (datawidth=4, size=2 bytes):
  275. // subburst1 addr=0, subburst2 addr=2, subburst3 addr=4, subburst4 addr=6
  276. // expected output from slave agent:
  277. // subburst1 addr=0, subburst2 addr=0, subburst3 addr=4, subburst4 addr=4
  278. generate
  279. if (BITS_TO_MASK > 0) begin : mask_address
  280. assign m0_address = { cmd_addr[ADDR_W-1:BITS_TO_MASK], {BITS_TO_MASK{1'b0}} };
  281. end else begin : no_mask_address
  282. assign m0_address = cmd_addr;
  283. end
  284. endgenerate
  285. assign m0_byteenable = cmd_byteen;
  286. assign m0_writedata = cmd_data;
  287. // Note: no Avalon-MM slave in existence accepts uncompressed read bursts -
  288. // this sort of burst exists only in merlin fabric ST packets. What to do
  289. // if we see such a burst? All beats in that burst need to be transmitted
  290. // to the slave so we have enough space-time for byteenable expression.
  291. //
  292. // There can be multiple bursts in a packet, but only one beat per burst
  293. // in <most> cases. The exception is when we've decided not to insert a
  294. // burst adapter for efficiency reasons, in which case this agent is also
  295. // responsible for driving burstcount to 1 on each beat of an uncompressed
  296. // read burst.
  297. assign m0_read = ready_for_command & !suppress_read & (local_compressed_read | local_read);
  298. generate
  299. // AVS_BURSTCOUNT_W and BYTE_CNT_W may not be equal. Assign m0_burstcount
  300. // from a sub-range, or 0-pad, as appropriate.
  301. if (AVS_BURSTCOUNT_W > BYTE_CNT_W) begin : m0_burstcount_zero_pad
  302. wire [AVS_BURSTCOUNT_W - BYTE_CNT_W - 1 : 0] zero_pad = {(AVS_BURSTCOUNT_W - BYTE_CNT_W) {1'b0}};
  303. assign m0_burstcount = (local_read & ~local_compressed_read) ?
  304. {zero_pad, num_symbols} :
  305. {zero_pad, cmd_byte_cnt};
  306. end
  307. else begin : m0_burstcount_no_pad
  308. assign m0_burstcount = (local_read & ~local_compressed_read) ?
  309. num_symbols[AVS_BURSTCOUNT_W-1:0] :
  310. cmd_byte_cnt[AVS_BURSTCOUNT_W-1:0];
  311. end
  312. endgenerate
  313. assign m0_write = ready_for_command & local_write & !suppress_write;
  314. assign m0_lock = ready_for_command & local_lock & (m0_read | m0_write);
  315. assign m0_debugaccess = cmd_debugaccess;
  316. // -------------------------------------------------------------------
  317. // Indirection layer for response packet values. Some may always wire
  318. // directly from the slave translator; others will no doubt emerge from
  319. // various FIFOs.
  320. // What to put in resp_data when a write occured? Answer: it does not
  321. // matter, because only response status is needed for non-posted writes,
  322. // and the packet already has a field for that.
  323. //
  324. // We use the rdata_fifo to store write responses as well. This allows us
  325. // to handle backpressure on the response path, and allows write response
  326. // merging.
  327. assign rdata_fifo_src_valid = m0_readdatavalid | m0_writeresponsevalid;
  328. assign rdata_fifo_src_data = {m0_response, m0_readdata};
  329. // ------------------------------------------------------------------
  330. // Generate a token when read commands are suppressed. The token
  331. // is stored in the response FIFO, and will be used to synthesize
  332. // a read response. The same token is used for non-posted write
  333. // response synthesis.
  334. //
  335. // Note: this token is not generated for suppressed uncompressed read cycles;
  336. // the burst uncompression logic at the read side of the response FIFO
  337. // generates the correct number of responses.
  338. //
  339. // When the slave can return the response, let it do its job. Don't
  340. // synthesize a response in that case, unless we've suppressed the
  341. // the last transfer in a write sub-burst.
  342. // ------------------------------------------------------------------
  343. wire write_end_of_subburst;
  344. assign needs_response_synthesis = ((local_read | local_compressed_read) & suppress_read) ||
  345. (!USE_WRITERESPONSE && nonposted_write_endofpacket) ||
  346. (USE_WRITERESPONSE && write_end_of_subburst && suppress_write);
  347. // Avalon-ST interfaces to external response FIFO.
  348. //
  349. // For efficiency, when synthesizing a write response we only store a non-posted write
  350. // transaction at its endofpacket, even if it was split into multiple sub-bursts.
  351. //
  352. // When not synthesizing write responses, we store each sub-burst in the FIFO.
  353. // Each sub-burst to the slave will return a response, which corresponds to one
  354. // entry in the FIFO. We merge all the sub-burst responses on the final
  355. // sub-burst and send it on the response channel.
  356. wire internal_cp_endofburst;
  357. wire [31:0] minimum_bytecount_wire = PKT_SYMBOLS; // to solve qis warning
  358. wire [AVS_BURSTCOUNT_W-1:0] minimum_bytecount;
  359. assign minimum_bytecount = minimum_bytecount_wire[AVS_BURSTCOUNT_W-1:0];
  360. assign internal_cp_endofburst = (cmd_byte_cnt == minimum_bytecount);
  361. assign write_end_of_subburst = local_write & internal_cp_endofburst;
  362. assign rf_source_valid = (local_read | local_compressed_read | (nonposted_write_endofpacket && !USE_WRITERESPONSE) | (USE_WRITERESPONSE && internal_cp_endofburst && local_write))
  363. & ready_for_command & cp_ready;
  364. assign rf_source_startofpacket = cp_startofpacket;
  365. assign rf_source_endofpacket = cp_endofpacket;
  366. always @* begin
  367. // default: assign every command packet field to the response FIFO...
  368. rf_source_data = {1'b0, cp_data};
  369. // ... and override select fields as needed.
  370. rf_source_data[FIFO_DATA_W-1] = needs_response_synthesis;
  371. rf_source_data[PKT_DATA_H :PKT_DATA_L] = {DATA_W {1'b0}};
  372. rf_source_data[PKT_BYTEEN_H :PKT_BYTEEN_L] = cmd_byteen;
  373. rf_source_data[PKT_ADDR_H :PKT_ADDR_L] = cmd_addr;
  374. rf_source_data[PKT_TRANS_COMPRESSED_READ] = cmd_compressed;
  375. rf_source_data[PKT_TRANS_POSTED] = cmd_posted;
  376. rf_source_data[PKT_TRANS_WRITE] = cmd_write;
  377. rf_source_data[PKT_TRANS_READ] = cmd_read;
  378. rf_source_data[PKT_SRC_ID_H :PKT_SRC_ID_L] = cmd_mid;
  379. rf_source_data[PKT_DEST_ID_H:PKT_DEST_ID_L] = cmd_sid;
  380. rf_source_data[PKT_BYTE_CNT_H:PKT_BYTE_CNT_L] = cmd_byte_cnt;
  381. rf_source_data[PKT_BURSTWRAP_H:PKT_BURSTWRAP_L] = cmd_burstwrap;
  382. rf_source_data[PKT_BURST_SIZE_H:PKT_BURST_SIZE_L] = cmd_burstsize;
  383. rf_source_data[PKT_PROTECTION_H:PKT_PROTECTION_L] = '0;
  384. rf_source_data[PKT_PROTECTION_L] = cmd_debugaccess;
  385. end
  386. wire uncompressor_source_valid;
  387. wire [BURSTSIZE_W-1:0] uncompressor_burstsize;
  388. wire last_write_response;
  389. // last_write_response indicates the last response of the broken-up write burst (sub-bursts).
  390. // At this time, the final merged response is sent, and rp_valid is only asserted
  391. // once for the whole burst.
  392. generate
  393. if (USE_WRITERESPONSE) begin
  394. assign last_write_response = rf_sink_data[PKT_TRANS_WRITE] & rf_sink_endofpacket;
  395. always @* begin
  396. if (rf_sink_data[PKT_TRANS_WRITE] == 1)
  397. rp_valid = (rdata_fifo_sink_valid | generate_response) & last_write_response & !rf_sink_data[PKT_TRANS_POSTED];
  398. else
  399. rp_valid = rdata_fifo_sink_valid | uncompressor_source_valid;
  400. end
  401. end else begin
  402. assign last_write_response = 1'b0;
  403. always @* begin
  404. rp_valid = rdata_fifo_sink_valid | uncompressor_source_valid;
  405. end
  406. end
  407. endgenerate
  408. // ------------------------------------------------------------------
  409. // Response merging
  410. // ------------------------------------------------------------------
  411. reg [1:0] current_response;
  412. reg [1:0] response_merged;
  413. generate
  414. if (USE_WRITERESPONSE) begin : response_merging_all
  415. reg first_write_response;
  416. reg reset_merged_output;
  417. reg [1:0] previous_response_in;
  418. reg [1:0] previous_response;
  419. always_ff @(posedge clk, posedge reset) begin
  420. if (reset) begin
  421. first_write_response <= 1'b1;
  422. end
  423. else begin // Merging work for write response, for read: previous_response_in = current_response
  424. if (rf_sink_valid & (rdata_fifo_sink_valid | generate_response) & rf_sink_data[PKT_TRANS_WRITE]) begin
  425. first_write_response <= 1'b0;
  426. if (rf_sink_endofpacket)
  427. first_write_response <= 1'b1;
  428. end
  429. end
  430. end
  431. always_comb begin
  432. current_response = generate_response ? 2'b00 : rdata_fifo_sink_data[AVS_DATA_W+1:AVS_DATA_W] | {2{rdata_fifo_sink_error}};
  433. reset_merged_output = first_write_response && (rdata_fifo_sink_valid || generate_response);
  434. previous_response_in = reset_merged_output ? current_response : previous_response;
  435. response_merged = current_response >= previous_response ? current_response: previous_response_in;
  436. end
  437. always_ff @(posedge clk or posedge reset) begin
  438. if (reset) begin
  439. previous_response <= 2'b00;
  440. end
  441. else begin
  442. if (rf_sink_valid & (rdata_fifo_sink_valid || generate_response)) begin
  443. previous_response <= response_merged;
  444. end
  445. end
  446. end
  447. end else begin : response_merging_read_only
  448. always @* begin
  449. current_response = generate_response ? 2'b00: rdata_fifo_sink_data[AVS_DATA_W+1:AVS_DATA_W] |
  450. {2{rdata_fifo_sink_error}};
  451. response_merged = current_response;
  452. end
  453. end
  454. endgenerate
  455. assign generate_response = rf_sink_data[FIFO_DATA_W-1];
  456. wire [BYTE_CNT_W-1:0] rf_sink_byte_cnt = rf_sink_data[PKT_BYTE_CNT_H:PKT_BYTE_CNT_L];
  457. wire rf_sink_compressed = rf_sink_data[PKT_TRANS_COMPRESSED_READ];
  458. wire [BURSTWRAP_W-1:0] rf_sink_burstwrap = rf_sink_data[PKT_BURSTWRAP_H:PKT_BURSTWRAP_L];
  459. wire [BURSTSIZE_W-1:0] rf_sink_burstsize = rf_sink_data[PKT_BURST_SIZE_H:PKT_BURST_SIZE_L];
  460. wire [ADDR_W-1:0] rf_sink_addr = rf_sink_data[PKT_ADDR_H:PKT_ADDR_L];
  461. // a non posted write response is always completed in 1 cycle. Modify the startofpacket signal to 1'b1 instead of taking whatever is in the rf_fifo
  462. wire rf_sink_startofpacket_wire = rf_sink_data[PKT_TRANS_WRITE] ? 1'b1 : rf_sink_startofpacket;
  463. wire [BYTE_CNT_W-1:0] burst_byte_cnt;
  464. wire [BURSTWRAP_W-1:0] rp_burstwrap;
  465. wire [ADDR_W-1:0] rp_address;
  466. wire rp_is_compressed;
  467. wire ready_for_response;
  468. // ------------------------------------------------------------------
  469. // We're typically ready for a response if the network is ready. There
  470. // is one exception:
  471. //
  472. // If the slave issues write responses, we only issue a merged response on
  473. // the final sub-burst. As a result, we only care about response channel
  474. // availability on the final burst when we send out the merged response.
  475. // ------------------------------------------------------------------
  476. assign ready_for_response = (USE_WRITERESPONSE) ?
  477. rp_ready || (rf_sink_data[PKT_TRANS_WRITE] && !last_write_response) || rf_sink_data[PKT_TRANS_POSTED]:
  478. rp_ready;
  479. // ------------------------------------------------------------------
  480. // Backpressure the readdata fifo if we're supposed to synthesize a response.
  481. // This may be a read response (for suppressed reads) or a write response
  482. // (for non-posted writes).
  483. // ------------------------------------------------------------------
  484. assign rdata_fifo_sink_ready = rdata_fifo_sink_valid & ready_for_response & ~(rf_sink_valid & generate_response);
  485. always @* begin
  486. // By default, return all fields...
  487. rp_data = rf_sink_data[ST_DATA_W - 1 : 0];
  488. // ... and override specific fields.
  489. rp_data[PKT_DATA_H :PKT_DATA_L] = rdata_fifo_sink_data[AVS_DATA_W-1:0];
  490. // Assignments directly from the response fifo.
  491. rp_data[PKT_TRANS_POSTED] = rf_sink_data[PKT_TRANS_POSTED];
  492. rp_data[PKT_TRANS_WRITE] = rf_sink_data[PKT_TRANS_WRITE];
  493. rp_data[PKT_SRC_ID_H :PKT_SRC_ID_L] = rf_sink_data[PKT_DEST_ID_H : PKT_DEST_ID_L];
  494. rp_data[PKT_DEST_ID_H:PKT_DEST_ID_L] = rf_sink_data[PKT_SRC_ID_H : PKT_SRC_ID_L];
  495. rp_data[PKT_BYTEEN_H :PKT_BYTEEN_L] = rf_sink_data[PKT_BYTEEN_H : PKT_BYTEEN_L];
  496. rp_data[PKT_PROTECTION_H:PKT_PROTECTION_L] = rf_sink_data[PKT_PROTECTION_H:PKT_PROTECTION_L];
  497. // Burst uncompressor assignments
  498. rp_data[PKT_ADDR_H :PKT_ADDR_L] = rp_address;
  499. rp_data[PKT_BURSTWRAP_H:PKT_BURSTWRAP_L] = rp_burstwrap;
  500. rp_data[PKT_BYTE_CNT_H:PKT_BYTE_CNT_L] = burst_byte_cnt;
  501. rp_data[PKT_TRANS_READ] = rf_sink_data[PKT_TRANS_READ] | rf_sink_data[PKT_TRANS_COMPRESSED_READ];
  502. rp_data[PKT_TRANS_COMPRESSED_READ] = rp_is_compressed;
  503. rp_data[PKT_RESPONSE_STATUS_H:PKT_RESPONSE_STATUS_L] = response_merged;
  504. rp_data[PKT_BURST_SIZE_H:PKT_BURST_SIZE_L] = uncompressor_burstsize;
  505. // bounce the original size back to the master untouched
  506. rp_data[PKT_ORI_BURST_SIZE_H:PKT_ORI_BURST_SIZE_L] = rf_sink_data[PKT_ORI_BURST_SIZE_H:PKT_ORI_BURST_SIZE_L];
  507. end
  508. // ------------------------------------------------------------------
  509. // Note: the burst uncompressor may be asked to generate responses for
  510. // write packets; these are treated the same as single-cycle uncompressed
  511. // reads.
  512. // ------------------------------------------------------------------
  513. altera_merlin_burst_uncompressor #(
  514. .ADDR_W (ADDR_W),
  515. .BURSTWRAP_W (BURSTWRAP_W),
  516. .BYTE_CNT_W (BYTE_CNT_W),
  517. .PKT_SYMBOLS (PKT_SYMBOLS),
  518. .BURST_SIZE_W (BURSTSIZE_W)
  519. ) uncompressor (
  520. .clk (clk),
  521. .reset (reset),
  522. .sink_startofpacket (rf_sink_startofpacket_wire),
  523. .sink_endofpacket (rf_sink_endofpacket),
  524. .sink_valid (rf_sink_valid & (rdata_fifo_sink_valid | generate_response)),
  525. .sink_ready (rf_sink_ready),
  526. .sink_addr (rf_sink_addr),
  527. .sink_burstwrap (rf_sink_burstwrap),
  528. .sink_byte_cnt (rf_sink_byte_cnt),
  529. .sink_is_compressed (rf_sink_compressed),
  530. .sink_burstsize (rf_sink_burstsize),
  531. .source_startofpacket (rp_startofpacket),
  532. .source_endofpacket (rp_endofpacket),
  533. .source_valid (uncompressor_source_valid),
  534. .source_ready (ready_for_response),
  535. .source_addr (rp_address),
  536. .source_burstwrap (rp_burstwrap),
  537. .source_byte_cnt (burst_byte_cnt),
  538. .source_is_compressed (rp_is_compressed),
  539. .source_burstsize (uncompressor_burstsize)
  540. );
  541. //--------------------------------------
  542. // Assertion: In case slave support response. The slave needs return response in order
  543. // Ex: non-posted write followed by a read: write response must complete before read data
  544. //--------------------------------------
  545. // synthesis translate_off
  546. ERROR_write_response_and_read_response_cannot_happen_same_time:
  547. assert property ( @(posedge clk)
  548. disable iff (reset) !(m0_writeresponsevalid && m0_readdatavalid)
  549. );
  550. // synthesis translate_on
  551. endmodule