nios2_uc_mm_interconnect_0_cmd_mux.sv 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  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_cmd_mux
  34. // NUM_INPUTS: 2
  35. // ARBITRATION_SHARES: 1 1
  36. // ARBITRATION_SCHEME "round-robin"
  37. // PIPELINE_ARB: 1
  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_cmd_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. // ----------------------
  60. // Source
  61. // ----------------------
  62. output src_valid,
  63. output [94-1 : 0] src_data,
  64. output [4-1 : 0] src_channel,
  65. output src_startofpacket,
  66. output src_endofpacket,
  67. input src_ready,
  68. // ----------------------
  69. // Clock & Reset
  70. // ----------------------
  71. input clk,
  72. input reset
  73. );
  74. localparam PAYLOAD_W = 94 + 4 + 2;
  75. localparam NUM_INPUTS = 2;
  76. localparam SHARE_COUNTER_W = 1;
  77. localparam PIPELINE_ARB = 1;
  78. localparam ST_DATA_W = 94;
  79. localparam ST_CHANNEL_W = 4;
  80. localparam PKT_TRANS_LOCK = 60;
  81. // ------------------------------------------
  82. // Signals
  83. // ------------------------------------------
  84. wire [NUM_INPUTS - 1 : 0] request;
  85. wire [NUM_INPUTS - 1 : 0] valid;
  86. wire [NUM_INPUTS - 1 : 0] grant;
  87. wire [NUM_INPUTS - 1 : 0] next_grant;
  88. reg [NUM_INPUTS - 1 : 0] saved_grant;
  89. reg [PAYLOAD_W - 1 : 0] src_payload;
  90. wire last_cycle;
  91. reg packet_in_progress;
  92. reg update_grant;
  93. wire [PAYLOAD_W - 1 : 0] sink0_payload;
  94. wire [PAYLOAD_W - 1 : 0] sink1_payload;
  95. assign valid[0] = sink0_valid;
  96. assign valid[1] = sink1_valid;
  97. wire [NUM_INPUTS - 1 : 0] eop;
  98. assign eop[0] = sink0_endofpacket;
  99. assign eop[1] = sink1_endofpacket;
  100. // ------------------------------------------
  101. // ------------------------------------------
  102. // Grant Logic & Updates
  103. // ------------------------------------------
  104. // ------------------------------------------
  105. reg [NUM_INPUTS - 1 : 0] lock;
  106. always @* begin
  107. lock[0] = sink0_data[60];
  108. lock[1] = sink1_data[60];
  109. end
  110. reg [NUM_INPUTS - 1 : 0] locked = '0;
  111. always @(posedge clk or posedge reset) begin
  112. if (reset) begin
  113. locked <= '0;
  114. end
  115. else begin
  116. locked <= next_grant & lock;
  117. end
  118. end
  119. assign last_cycle = src_valid & src_ready & src_endofpacket & ~(|(lock & grant));
  120. // ------------------------------------------
  121. // We're working on a packet at any time valid is high, except
  122. // when this is the endofpacket.
  123. // ------------------------------------------
  124. always @(posedge clk or posedge reset) begin
  125. if (reset) begin
  126. packet_in_progress <= 1'b0;
  127. end
  128. else begin
  129. if (last_cycle)
  130. packet_in_progress <= 1'b0;
  131. else if (src_valid)
  132. packet_in_progress <= 1'b1;
  133. end
  134. end
  135. // ------------------------------------------
  136. // Shares
  137. //
  138. // Special case: all-equal shares _should_ be optimized into assigning a
  139. // constant to next_grant_share.
  140. // Special case: all-1's shares _should_ result in the share counter
  141. // being optimized away.
  142. // ------------------------------------------
  143. // Input | arb shares | counter load value
  144. // 0 | 1 | 0
  145. // 1 | 1 | 0
  146. wire [SHARE_COUNTER_W - 1 : 0] share_0 = 1'd0;
  147. wire [SHARE_COUNTER_W - 1 : 0] share_1 = 1'd0;
  148. // ------------------------------------------
  149. // Choose the share value corresponding to the grant.
  150. // ------------------------------------------
  151. reg [SHARE_COUNTER_W - 1 : 0] next_grant_share;
  152. always @* begin
  153. next_grant_share =
  154. share_0 & { SHARE_COUNTER_W {next_grant[0]} } |
  155. share_1 & { SHARE_COUNTER_W {next_grant[1]} };
  156. end
  157. // ------------------------------------------
  158. // Flag to indicate first packet of an arb sequence.
  159. // ------------------------------------------
  160. // ------------------------------------------
  161. // Compute the next share-count value.
  162. // ------------------------------------------
  163. reg [SHARE_COUNTER_W - 1 : 0] p1_share_count;
  164. reg [SHARE_COUNTER_W - 1 : 0] share_count;
  165. reg share_count_zero_flag;
  166. always @* begin
  167. // Update the counter, but don't decrement below 0.
  168. p1_share_count = share_count_zero_flag ? '0 : share_count - 1'b1;
  169. end
  170. // ------------------------------------------
  171. // Update the share counter and share-counter=zero flag.
  172. // ------------------------------------------
  173. always @(posedge clk or posedge reset) begin
  174. if (reset) begin
  175. share_count <= '0;
  176. share_count_zero_flag <= 1'b1;
  177. end
  178. else begin
  179. if (update_grant) begin
  180. share_count <= next_grant_share;
  181. share_count_zero_flag <= (next_grant_share == '0);
  182. end
  183. else if (last_cycle) begin
  184. share_count <= p1_share_count;
  185. share_count_zero_flag <= (p1_share_count == '0);
  186. end
  187. end
  188. end
  189. always @* begin
  190. update_grant = 0;
  191. // ------------------------------------------
  192. // The pipeline delays grant by one cycle, so
  193. // we have to calculate the update_grant signal
  194. // one cycle ahead of time.
  195. //
  196. // Possible optimization: omit the first clause
  197. // "if (!packet_in_progress & ~src_valid) ..."
  198. // cost: one idle cycle at the the beginning of each
  199. // grant cycle.
  200. // benefit: save a small amount of logic.
  201. // ------------------------------------------
  202. if (!packet_in_progress & !src_valid)
  203. update_grant = 1;
  204. if (last_cycle && share_count_zero_flag)
  205. update_grant = 1;
  206. end
  207. wire save_grant;
  208. assign save_grant = update_grant;
  209. assign grant = saved_grant;
  210. always @(posedge clk, posedge reset) begin
  211. if (reset)
  212. saved_grant <= '0;
  213. else if (save_grant)
  214. saved_grant <= next_grant;
  215. end
  216. // ------------------------------------------
  217. // ------------------------------------------
  218. // Arbitrator
  219. // ------------------------------------------
  220. // ------------------------------------------
  221. // ------------------------------------------
  222. // Create a request vector that stays high during
  223. // the packet for unpipelined arbitration.
  224. //
  225. // The pipelined arbitration scheme does not require
  226. // request to be held high during the packet.
  227. // ------------------------------------------
  228. reg [NUM_INPUTS - 1 : 0] prev_request;
  229. always @(posedge clk, posedge reset) begin
  230. if (reset)
  231. prev_request <= '0;
  232. else
  233. prev_request <= request & ~(valid & eop);
  234. end
  235. assign request = (PIPELINE_ARB == 1) ? valid | locked :
  236. prev_request | valid | locked;
  237. wire [NUM_INPUTS - 1 : 0] next_grant_from_arb;
  238. altera_merlin_arbitrator
  239. #(
  240. .NUM_REQUESTERS(NUM_INPUTS),
  241. .SCHEME ("round-robin"),
  242. .PIPELINE (1)
  243. ) arb (
  244. .clk (clk),
  245. .reset (reset),
  246. .request (request),
  247. .grant (next_grant_from_arb),
  248. .save_top_priority (src_valid),
  249. .increment_top_priority (update_grant)
  250. );
  251. assign next_grant = next_grant_from_arb;
  252. // ------------------------------------------
  253. // ------------------------------------------
  254. // Mux
  255. //
  256. // Implemented as a sum of products.
  257. // ------------------------------------------
  258. // ------------------------------------------
  259. assign sink0_ready = src_ready && grant[0];
  260. assign sink1_ready = src_ready && grant[1];
  261. assign src_valid = |(grant & valid);
  262. always @* begin
  263. src_payload =
  264. sink0_payload & {PAYLOAD_W {grant[0]} } |
  265. sink1_payload & {PAYLOAD_W {grant[1]} };
  266. end
  267. // ------------------------------------------
  268. // Mux Payload Mapping
  269. // ------------------------------------------
  270. assign sink0_payload = {sink0_channel,sink0_data,
  271. sink0_startofpacket,sink0_endofpacket};
  272. assign sink1_payload = {sink1_channel,sink1_data,
  273. sink1_startofpacket,sink1_endofpacket};
  274. assign {src_channel,src_data,src_startofpacket,src_endofpacket} = src_payload;
  275. endmodule