nios2_uc_mm_interconnect_0_rsp_mux.sv 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  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-2014 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_multiplexer/altera_merlin_multiplexer.sv.terp#1 $
  24. // $Revision: #1 $
  25. // $Date: 2018/11/07 $
  26. // $Author: psgswbuild $
  27. // ------------------------------------------
  28. // Merlin Multiplexer
  29. // ------------------------------------------
  30. `timescale 1 ns / 1 ns
  31. // ------------------------------------------
  32. // Generation parameters:
  33. // output_name: nios2_uc_mm_interconnect_0_rsp_mux
  34. // NUM_INPUTS: 4
  35. // ARBITRATION_SHARES: 1 1 1 1
  36. // ARBITRATION_SCHEME "no-arb"
  37. // PIPELINE_ARB: 0
  38. // PKT_TRANS_LOCK: 60 (arbitration locking enabled)
  39. // ST_DATA_W: 94
  40. // ST_CHANNEL_W: 4
  41. // ------------------------------------------
  42. module nios2_uc_mm_interconnect_0_rsp_mux
  43. (
  44. // ----------------------
  45. // Sinks
  46. // ----------------------
  47. input sink0_valid,
  48. input [94-1 : 0] sink0_data,
  49. input [4-1: 0] sink0_channel,
  50. input sink0_startofpacket,
  51. input sink0_endofpacket,
  52. output sink0_ready,
  53. input sink1_valid,
  54. input [94-1 : 0] sink1_data,
  55. input [4-1: 0] sink1_channel,
  56. input sink1_startofpacket,
  57. input sink1_endofpacket,
  58. output sink1_ready,
  59. input sink2_valid,
  60. input [94-1 : 0] sink2_data,
  61. input [4-1: 0] sink2_channel,
  62. input sink2_startofpacket,
  63. input sink2_endofpacket,
  64. output sink2_ready,
  65. input sink3_valid,
  66. input [94-1 : 0] sink3_data,
  67. input [4-1: 0] sink3_channel,
  68. input sink3_startofpacket,
  69. input sink3_endofpacket,
  70. output sink3_ready,
  71. // ----------------------
  72. // Source
  73. // ----------------------
  74. output src_valid,
  75. output [94-1 : 0] src_data,
  76. output [4-1 : 0] src_channel,
  77. output src_startofpacket,
  78. output src_endofpacket,
  79. input src_ready,
  80. // ----------------------
  81. // Clock & Reset
  82. // ----------------------
  83. input clk,
  84. input reset
  85. );
  86. localparam PAYLOAD_W = 94 + 4 + 2;
  87. localparam NUM_INPUTS = 4;
  88. localparam SHARE_COUNTER_W = 1;
  89. localparam PIPELINE_ARB = 0;
  90. localparam ST_DATA_W = 94;
  91. localparam ST_CHANNEL_W = 4;
  92. localparam PKT_TRANS_LOCK = 60;
  93. // ------------------------------------------
  94. // Signals
  95. // ------------------------------------------
  96. wire [NUM_INPUTS - 1 : 0] request;
  97. wire [NUM_INPUTS - 1 : 0] valid;
  98. wire [NUM_INPUTS - 1 : 0] grant;
  99. wire [NUM_INPUTS - 1 : 0] next_grant;
  100. reg [NUM_INPUTS - 1 : 0] saved_grant;
  101. reg [PAYLOAD_W - 1 : 0] src_payload;
  102. wire last_cycle;
  103. reg packet_in_progress;
  104. reg update_grant;
  105. wire [PAYLOAD_W - 1 : 0] sink0_payload;
  106. wire [PAYLOAD_W - 1 : 0] sink1_payload;
  107. wire [PAYLOAD_W - 1 : 0] sink2_payload;
  108. wire [PAYLOAD_W - 1 : 0] sink3_payload;
  109. assign valid[0] = sink0_valid;
  110. assign valid[1] = sink1_valid;
  111. assign valid[2] = sink2_valid;
  112. assign valid[3] = sink3_valid;
  113. // ------------------------------------------
  114. // ------------------------------------------
  115. // Grant Logic & Updates
  116. // ------------------------------------------
  117. // ------------------------------------------
  118. reg [NUM_INPUTS - 1 : 0] lock;
  119. always @* begin
  120. lock[0] = sink0_data[60];
  121. lock[1] = sink1_data[60];
  122. lock[2] = sink2_data[60];
  123. lock[3] = sink3_data[60];
  124. end
  125. assign last_cycle = src_valid & src_ready & src_endofpacket & ~(|(lock & grant));
  126. // ------------------------------------------
  127. // We're working on a packet at any time valid is high, except
  128. // when this is the endofpacket.
  129. // ------------------------------------------
  130. always @(posedge clk or posedge reset) begin
  131. if (reset) begin
  132. packet_in_progress <= 1'b0;
  133. end
  134. else begin
  135. if (last_cycle)
  136. packet_in_progress <= 1'b0;
  137. else if (src_valid)
  138. packet_in_progress <= 1'b1;
  139. end
  140. end
  141. // ------------------------------------------
  142. // Shares
  143. //
  144. // Special case: all-equal shares _should_ be optimized into assigning a
  145. // constant to next_grant_share.
  146. // Special case: all-1's shares _should_ result in the share counter
  147. // being optimized away.
  148. // ------------------------------------------
  149. // Input | arb shares | counter load value
  150. // 0 | 1 | 0
  151. // 1 | 1 | 0
  152. // 2 | 1 | 0
  153. // 3 | 1 | 0
  154. wire [SHARE_COUNTER_W - 1 : 0] share_0 = 1'd0;
  155. wire [SHARE_COUNTER_W - 1 : 0] share_1 = 1'd0;
  156. wire [SHARE_COUNTER_W - 1 : 0] share_2 = 1'd0;
  157. wire [SHARE_COUNTER_W - 1 : 0] share_3 = 1'd0;
  158. // ------------------------------------------
  159. // Choose the share value corresponding to the grant.
  160. // ------------------------------------------
  161. reg [SHARE_COUNTER_W - 1 : 0] next_grant_share;
  162. always @* begin
  163. next_grant_share =
  164. share_0 & { SHARE_COUNTER_W {next_grant[0]} } |
  165. share_1 & { SHARE_COUNTER_W {next_grant[1]} } |
  166. share_2 & { SHARE_COUNTER_W {next_grant[2]} } |
  167. share_3 & { SHARE_COUNTER_W {next_grant[3]} };
  168. end
  169. // ------------------------------------------
  170. // Flag to indicate first packet of an arb sequence.
  171. // ------------------------------------------
  172. wire grant_changed = ~packet_in_progress && ~(|(saved_grant & valid));
  173. reg first_packet_r;
  174. wire first_packet = grant_changed | first_packet_r;
  175. always @(posedge clk or posedge reset) begin
  176. if (reset) begin
  177. first_packet_r <= 1'b0;
  178. end
  179. else begin
  180. if (update_grant)
  181. first_packet_r <= 1'b1;
  182. else if (last_cycle)
  183. first_packet_r <= 1'b0;
  184. else if (grant_changed)
  185. first_packet_r <= 1'b1;
  186. end
  187. end
  188. // ------------------------------------------
  189. // Compute the next share-count value.
  190. // ------------------------------------------
  191. reg [SHARE_COUNTER_W - 1 : 0] p1_share_count;
  192. reg [SHARE_COUNTER_W - 1 : 0] share_count;
  193. reg share_count_zero_flag;
  194. always @* begin
  195. if (first_packet) begin
  196. p1_share_count = next_grant_share;
  197. end
  198. else begin
  199. // Update the counter, but don't decrement below 0.
  200. p1_share_count = share_count_zero_flag ? '0 : share_count - 1'b1;
  201. end
  202. end
  203. // ------------------------------------------
  204. // Update the share counter and share-counter=zero flag.
  205. // ------------------------------------------
  206. always @(posedge clk or posedge reset) begin
  207. if (reset) begin
  208. share_count <= '0;
  209. share_count_zero_flag <= 1'b1;
  210. end
  211. else begin
  212. if (last_cycle) begin
  213. share_count <= p1_share_count;
  214. share_count_zero_flag <= (p1_share_count == '0);
  215. end
  216. end
  217. end
  218. // ------------------------------------------
  219. // For each input, maintain a final_packet signal which goes active for the
  220. // last packet of a full-share packet sequence. Example: if I have 4
  221. // shares and I'm continuously requesting, final_packet is active in the
  222. // 4th packet.
  223. // ------------------------------------------
  224. wire final_packet_0 = 1'b1;
  225. wire final_packet_1 = 1'b1;
  226. wire final_packet_2 = 1'b1;
  227. wire final_packet_3 = 1'b1;
  228. // ------------------------------------------
  229. // Concatenate all final_packet signals (wire or reg) into a handy vector.
  230. // ------------------------------------------
  231. wire [NUM_INPUTS - 1 : 0] final_packet = {
  232. final_packet_3,
  233. final_packet_2,
  234. final_packet_1,
  235. final_packet_0
  236. };
  237. // ------------------------------------------
  238. // ------------------------------------------
  239. wire p1_done = |(final_packet & grant);
  240. // ------------------------------------------
  241. // Flag for the first cycle of packets within an
  242. // arb sequence
  243. // ------------------------------------------
  244. reg first_cycle;
  245. always @(posedge clk, posedge reset) begin
  246. if (reset)
  247. first_cycle <= 0;
  248. else
  249. first_cycle <= last_cycle && ~p1_done;
  250. end
  251. always @* begin
  252. update_grant = 0;
  253. // ------------------------------------------
  254. // No arbitration pipeline, update grant whenever
  255. // the current arb winner has consumed all shares,
  256. // or all requests are low
  257. // ------------------------------------------
  258. update_grant = (last_cycle && p1_done) || (first_cycle && ~(|valid));
  259. update_grant = last_cycle;
  260. end
  261. wire save_grant;
  262. assign save_grant = 1;
  263. assign grant = next_grant;
  264. always @(posedge clk, posedge reset) begin
  265. if (reset)
  266. saved_grant <= '0;
  267. else if (save_grant)
  268. saved_grant <= next_grant;
  269. end
  270. // ------------------------------------------
  271. // ------------------------------------------
  272. // Arbitrator
  273. // ------------------------------------------
  274. // ------------------------------------------
  275. // ------------------------------------------
  276. // Create a request vector that stays high during
  277. // the packet for unpipelined arbitration.
  278. //
  279. // The pipelined arbitration scheme does not require
  280. // request to be held high during the packet.
  281. // ------------------------------------------
  282. assign request = valid;
  283. wire [NUM_INPUTS - 1 : 0] next_grant_from_arb;
  284. altera_merlin_arbitrator
  285. #(
  286. .NUM_REQUESTERS(NUM_INPUTS),
  287. .SCHEME ("no-arb"),
  288. .PIPELINE (0)
  289. ) arb (
  290. .clk (clk),
  291. .reset (reset),
  292. .request (request),
  293. .grant (next_grant_from_arb),
  294. .save_top_priority (src_valid),
  295. .increment_top_priority (update_grant)
  296. );
  297. assign next_grant = next_grant_from_arb;
  298. // ------------------------------------------
  299. // ------------------------------------------
  300. // Mux
  301. //
  302. // Implemented as a sum of products.
  303. // ------------------------------------------
  304. // ------------------------------------------
  305. assign sink0_ready = src_ready && grant[0];
  306. assign sink1_ready = src_ready && grant[1];
  307. assign sink2_ready = src_ready && grant[2];
  308. assign sink3_ready = src_ready && grant[3];
  309. assign src_valid = |(grant & valid);
  310. always @* begin
  311. src_payload =
  312. sink0_payload & {PAYLOAD_W {grant[0]} } |
  313. sink1_payload & {PAYLOAD_W {grant[1]} } |
  314. sink2_payload & {PAYLOAD_W {grant[2]} } |
  315. sink3_payload & {PAYLOAD_W {grant[3]} };
  316. end
  317. // ------------------------------------------
  318. // Mux Payload Mapping
  319. // ------------------------------------------
  320. assign sink0_payload = {sink0_channel,sink0_data,
  321. sink0_startofpacket,sink0_endofpacket};
  322. assign sink1_payload = {sink1_channel,sink1_data,
  323. sink1_startofpacket,sink1_endofpacket};
  324. assign sink2_payload = {sink2_channel,sink2_data,
  325. sink2_startofpacket,sink2_endofpacket};
  326. assign sink3_payload = {sink3_channel,sink3_data,
  327. sink3_startofpacket,sink3_endofpacket};
  328. assign {src_channel,src_data,src_startofpacket,src_endofpacket} = src_payload;
  329. endmodule