comp.sv 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /*
  2. _____
  3. x[0] ==>| A |
  4. x_stb[0] -->| D |
  5. x_ack[0] <--| D |==> y
  6. | E |--> y_stb
  7. x[1] ==>| R |<-- y_ack
  8. x_stb[1] -->| |
  9. x_ack[1] <--|_____|
  10. */
  11. module cadder#(parameter N=32)(clk, rst, x, x_ack, x_stb, y, y_ack, y_stb);
  12. input logic clk;
  13. input logic rst;
  14. input wire [N-1:0] x [1:0];
  15. output logic [N-1:0] y;
  16. output x_ack[1:0];
  17. input x_stb[1:0];
  18. input y_ack;
  19. output y_stb;
  20. wire left_ack, left_stb;
  21. assign x_ack[0] = left_ack;
  22. assign x_ack[1] = left_ack;
  23. assign left_stb = x_stb[0] & x_stb[1];
  24. adder add0 (
  25. .clk(clk),
  26. .rst(rst),
  27. .input_a(x[0]),
  28. .input_b(x[1]),
  29. .input_stb(left_stb),
  30. .input_ack(left_ack),
  31. .output_z(y),
  32. .output_z_ack(y_ack),
  33. .output_z_stb(y_stb)
  34. );
  35. endmodule : cadder
  36. /*
  37. K layers of cascade adder
  38. Example of K=3 adder:
  39. IN | K3 | K2 | K1 | OUT
  40. _
  41. ->| | _
  42. ->|_|-->| |
  43. _ | |--\
  44. ->| |-->|_| | _
  45. ->|_| \->| |
  46. _ | |->
  47. ->| | _ /->|_|
  48. ->|_|-->| | |
  49. _ | |--/
  50. ->| |-->|_|
  51. ->|_|
  52. [inputs]
  53. x size: 2**K
  54. left io size: 2**K
  55. */
  56. module adder_casc#(parameter K,N=32)(clk, rst, x, y, left, right);
  57. input logic clk;
  58. input logic rst;
  59. input wire [N-1:0] x [2**K-1:0];
  60. output logic [N-1:0] y;
  61. abus_io right;
  62. abus_io left[2**K-1:0];
  63. wire [N-1:0] layer_w [2**K-3:0];
  64. wire ack_w [2**K-3:0];
  65. wire stb_w [2**K-3:0];
  66. genvar i,j;
  67. generate
  68. for(i=0; i<K; i++) begin : generate_layers
  69. // First layers
  70. if(i == 0) begin
  71. for(j=0; j<2**(K-1); j++) begin : generate_casc0
  72. cadder a(
  73. .clk(clk),
  74. .rst(rst),
  75. .x(x[j*2+:2]),
  76. .y(layer_w[j]),
  77. .x_ack({left[j*2].ack, left[j*2+1].ack}),
  78. .x_stb({left[j*2].stb, left[j*2+1].stb}),
  79. .y_ack(ack_w[j]),
  80. .y_stb(stb_w[j])
  81. );
  82. end
  83. end
  84. // Last layer
  85. else if((K-i) <= 1) begin
  86. localparam s0 = 2**K-4;
  87. localparam s1 = 2**K-3;
  88. cadder c(
  89. .clk(clk),
  90. .rst(rst),
  91. .x(layer_w[s0+:2]),
  92. .y(y),
  93. .x_ack({ack_w[s0], ack_w[s1]}),
  94. .x_stb({stb_w[s0], stb_w[s1]}),
  95. .y_ack(right.ack),
  96. .y_stb(right.stb)
  97. );
  98. end
  99. // Middle layers
  100. else begin
  101. for(j=0; j<2**(K-i-1); j++) begin : generate_casc1
  102. localparam s = $floor((2.0**(K-1.0) * (2.0**(i-1)-1.0)/2.0**(i-1))+j);
  103. localparam ix = s*2;
  104. localparam iy = s+2**(K-1);
  105. cadder b(
  106. .clk(clk),
  107. .rst(rst),
  108. .x(layer_w[ix+:2]),
  109. .y(layer_w[iy]),
  110. .x_ack(ack_w[ix+:2]),
  111. .x_stb(stb_w[ix+:2]),
  112. .y_ack(ack_w[iy]),
  113. .y_stb(stb_w[iy])
  114. );
  115. end
  116. end
  117. end
  118. endgenerate
  119. endmodule : adder_casc
  120. module adder_casc_tb();
  121. logic clk, rst;
  122. localparam K=4;
  123. logic [31:0] x [2**K-1:0];
  124. logic [31:0] y;
  125. logic ack [2**K-1:0];
  126. logic stb [2**K-1:0];
  127. abus_io input_ios[2**K-1:0]();
  128. abus_io output_io();
  129. genvar k;
  130. generate
  131. for(k=0; k<2**K; k++) begin : io_mapper
  132. assign input_ios[k].stb = stb[k];
  133. assign ack[k] = input_ios[k].ack;
  134. end
  135. endgenerate
  136. adder_casc#(.K(K)) adder_casc0(.clk(clk), .rst(rst), .x(x), .y(y), .left(input_ios), .right(output_io.left));
  137. initial forever #5 clk = ~clk;
  138. initial begin
  139. $display("Testing adder_casc");
  140. clk = 0;
  141. rst = 1;
  142. foreach(stb[i]) stb[i] = 0;
  143. output_io.ack = 0;
  144. #20
  145. rst = 0;
  146. // Initialise with floating point 2**i
  147. foreach(x[i]) x[i] = ('h400 + (i*8)) << 20;
  148. foreach(stb[i]) stb[i] = 1;
  149. fork
  150. foreach(ack[i]) begin
  151. fork
  152. wait(ack[i] == 1);
  153. #20
  154. stb[i] = 0;
  155. join
  156. end
  157. join
  158. #20
  159. wait(output_io.stb == 1);
  160. output_io.ack = 1;
  161. assert(y[0] == 'h47ffff00);
  162. wait(output_io.stb == 0);
  163. output_io.ack = 0;
  164. end
  165. endmodule : adder_casc_tb