Advertisement
Guest User

Untitled

a guest
Feb 23rd, 2014
133
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.95 KB | None | 0 0
  1. `define MEM_MINWIDTH 5
  2. `define MEM_MAXWIDTH 15
  3.  
  4. `define DSP_A_MAXWIDTH 25
  5. `define DSP_B_MAXWIDTH 18
  6.  
  7. module \$mem (RD_CLK, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA);
  8. parameter MEMID = "";
  9. parameter SIZE = 256;
  10. parameter OFFSET = 0;
  11. parameter ABITS = 8;
  12. parameter WIDTH = 8;
  13.  
  14. parameter RD_PORTS = 1;
  15. parameter RD_CLK_ENABLE = 1'b1;
  16. parameter RD_CLK_POLARITY = 1'b1;
  17. parameter RD_TRANSPARENT = 1'b1;
  18.  
  19. parameter WR_PORTS = 1;
  20. parameter WR_CLK_ENABLE = 1'b1;
  21. parameter WR_CLK_POLARITY = 1'b1;
  22.  
  23. input [RD_PORTS-1:0] RD_CLK;
  24. input [RD_PORTS*ABITS-1:0] RD_ADDR;
  25. output reg [RD_PORTS*WIDTH-1:0] RD_DATA;
  26.  
  27. input [WR_PORTS-1:0] WR_CLK, WR_EN;
  28. input [WR_PORTS*ABITS-1:0] WR_ADDR;
  29. input [WR_PORTS*WIDTH-1:0] WR_DATA;
  30.  
  31. wire [1023:0] _TECHMAP_DO_ = "proc; clean";
  32.  
  33. parameter _TECHMAP_CONNMAP_RD_CLK_ = 0;
  34. parameter _TECHMAP_CONNMAP_WR_CLK_ = 0;
  35. parameter _TECHMAP_CONNMAP_RD_ADDR_ = 0;
  36. parameter _TECHMAP_CONNMAP_WR_ADDR_ = 0;
  37. parameter _TECHMAP_CONNMAP_RD_PORTS_ = 0;
  38. parameter _TECHMAP_CONNMAP_WR_PORTS_ = 0;
  39.  
  40.  
  41. reg _TECHMAP_FAIL_;
  42. initial begin
  43. _TECHMAP_FAIL_ <= 0;
  44.  
  45. // only map cells with only one read and one write port
  46. if (RD_PORTS > 2 || WR_PORTS > 2)
  47. _TECHMAP_FAIL_ <= 1;
  48.  
  49. // we expect positive read clock and non-transparent reads
  50. if (RD_TRANSPARENT || !RD_CLK_ENABLE || !RD_CLK_POLARITY)
  51. _TECHMAP_FAIL_ <= 1;
  52.  
  53. // we expect positive write clock
  54. if (!WR_CLK_ENABLE || !WR_CLK_POLARITY)
  55. _TECHMAP_FAIL_ <= 1;
  56.  
  57. // read and write must be in same clock domain
  58. if (_TECHMAP_CONNMAP_RD_CLK_ != _TECHMAP_CONNMAP_WR_CLK_)
  59. _TECHMAP_FAIL_ <= 1;
  60.  
  61. // we don't do small memories or memories with offsets
  62. if (OFFSET != 0 || ABITS < `MEM_MINWIDTH || SIZE < 2**`MEM_MINWIDTH)
  63. _TECHMAP_FAIL_ <= 1;
  64.  
  65. if (_TECHMAP_CONNMAP_RD_ADDR_ != _TECHMAP_CONNMAP_WR_ADDR_)
  66. _TECHMAP_FAIL_ <= 1;
  67. end
  68.  
  69. genvar i;
  70. generate
  71. for (i = 0; i < WIDTH; i=i+1) begin:slice
  72. if (RD_PORTS > 1 || WR_PORTS > 1) begin
  73. \$__mem_Wx1_dp_generator #(
  74. .ABITS(ABITS),
  75. .SIZE(SIZE),
  76. ) bit_slice (
  77. .CLK(RD_CLK),
  78. .RD_ADDR(RD_ADDR),
  79. .RD_DATA(RD_DATA[RD_PORTS*(i+1)-1:RD_PORTS*i]),
  80. .WR_ADDR(WR_ADDR),
  81. .WR_DATA(WR_DATA[WD_PORTS*(i+1)-1:WD_PORTS*i]),
  82. .WR_EN(WR_EN)
  83. );
  84. end
  85. else begin
  86. \$__mem_Wx1_sp_generator #(
  87. .ABITS(ABITS),
  88. .SIZE(SIZE),
  89. ) bit_slice (
  90. .CLK(RD_CLK),
  91. .RD_ADDR(RD_ADDR),
  92. .RD_DATA(RD_DATA[i]),
  93. .WR_ADDR(WR_ADDR),
  94. .WR_DATA(WR_DATA[i]),
  95. .WR_EN(WR_EN)
  96. );
  97. end
  98. end
  99. endgenerate
  100. endmodule
  101.  
  102. module \$__mem_Wx1_dp_generator (CLK, RD_ADDR, RD_DATA, WR_ADDR, WR_DATA, WR_EN);
  103. parameter ABITS = 4;
  104. parameter SIZE = 16;
  105.  
  106. input CLK;
  107. input [1:0] WR_EN, WR_DATA;
  108. input [2*ABITS-1:0] RD_ADDR, WR_ADDR;
  109. output [1:0] RD_DATA;
  110.  
  111. wire [1023:0] _TECHMAP_DO_ = "proc; clean";
  112.  
  113. generate
  114. if (ABITS > `MEM_MAXWIDTH) begin
  115. wire [1:0] high_rd_data, low_rd_data;
  116. if (SIZE > 2**(ABITS-1)) begin
  117. \$__mem_Wx1_dp_generator #(
  118. .ABITS(ABITS-1),
  119. .SIZE(SIZE - 2**(ABITS-1)),
  120. ) part_high (
  121. .CLK(CLK),
  122. .RD_ADDR(RD_ADDR[ABITS-2:0]),
  123. .RD_DATA(high_rd_data),
  124. .WR_ADDR(WR_ADDR[ABITS-2:0]),
  125. .WR_DATA(WR_DATA),
  126. .WR_EN(WR_EN && WR_ADDR[ABITS-1])
  127. );
  128. end else begin
  129. assign high_rd_data = 2'bxx;
  130. end
  131. \$__mem_Wx1_dp_generator #(
  132. .ABITS(ABITS-1),
  133. .SIZE(SIZE > 2**(ABITS-1) ? 2**(ABITS-1) : SIZE),
  134. ) part_low (
  135. .CLK(CLK),
  136. .RD_ADDR(RD_ADDR[ABITS-2:0]),
  137. .RD_DATA(low_rd_data),
  138. .WR_ADDR(WR_ADDR[ABITS-2:0]),
  139. .WR_DATA(WR_DATA),
  140. .WR_EN(WR_EN && !WR_ADDR[ABITS-1])
  141. );
  142. reg delayed_abit;
  143. always @(posedge CLK)
  144. delayed_abit <= RD_ADDR[ABITS-1];
  145. assign RD_DATA = delayed_abit ? high_rd_data : low_rd_data;
  146. end else begin
  147. dual_port_ram _TECHMAP_REPLACE_ (
  148. .clk(CLK),
  149. .addr1({ {{`MEM_MAXWIDTH-ABITS}{1'bx}}, RD_ADDR[ABITS-1:0] }),
  150. .addr1__U({ {{`MEM_MAXWIDTH-ABITS}{1'bx}}, RD_ADDR[ABITS-1:0] }),
  151. .data1(RD_DATA[0]),
  152. .out1(WR_DATA[0]),
  153. .we1({ {8}{WR_EN[0]} }),
  154. .we1__U({ {8}{WR_EN[0]} }),
  155. .addr2({ {{`MEM_MAXWIDTH-ABITS}{1'bx}}, RD_ADDR[2*ABITS-1:ABITS] }),
  156. .addr2__U({ {{`MEM_MAXWIDTH-ABITS}{1'bx}}, RD_ADDR[2*ABITS-1:ABITS] }),
  157. .data2(RD_DATA[1]),
  158. .out2(WR_DATA[1]),
  159. .we2({ {8}{WR_EN[1]} }),
  160. .we2__U({ {8}{WR_EN[1]} })
  161. );
  162. end
  163. endgenerate
  164. endmodule
  165.  
  166. module \$__mem_Wx1_sp_generator (CLK, RD_ADDR, RD_DATA, WR_ADDR, WR_DATA, WR_EN);
  167. parameter ABITS = 4;
  168. parameter SIZE = 16;
  169.  
  170. input CLK, WR_DATA, WR_EN;
  171. input [ABITS-1:0] RD_ADDR, WR_ADDR;
  172. output RD_DATA;
  173.  
  174. wire [1023:0] _TECHMAP_DO_ = "proc; clean";
  175.  
  176. generate
  177. if (ABITS > `MEM_MAXWIDTH) begin
  178. wire high_rd_data, low_rd_data;
  179. if (SIZE > 2**(ABITS-1)) begin
  180. \$__mem_Wx1_sp_generator #(
  181. .ABITS(ABITS-1),
  182. .SIZE(SIZE - 2**(ABITS-1)),
  183. ) part_high (
  184. .CLK(CLK),
  185. .RD_ADDR(RD_ADDR[ABITS-2:0]),
  186. .RD_DATA(high_rd_data),
  187. .WR_ADDR(WR_ADDR[ABITS-2:0]),
  188. .WR_DATA(WR_DATA),
  189. .WR_EN(WR_EN && WR_ADDR[ABITS-1])
  190. );
  191. end else begin
  192. assign high_rd_data = 1'bx;
  193. end
  194. \$__mem_Wx1_sp_generator #(
  195. .ABITS(ABITS-1),
  196. .SIZE(SIZE > 2**(ABITS-1) ? 2**(ABITS-1) : SIZE),
  197. ) part_low (
  198. .CLK(CLK),
  199. .RD_ADDR(RD_ADDR[ABITS-2:0]),
  200. .RD_DATA(low_rd_data),
  201. .WR_ADDR(WR_ADDR[ABITS-2:0]),
  202. .WR_DATA(WR_DATA),
  203. .WR_EN(WR_EN && !WR_ADDR[ABITS-1])
  204. );
  205. reg delayed_abit;
  206. always @(posedge CLK)
  207. delayed_abit <= RD_ADDR[ABITS-1];
  208. assign RD_DATA = delayed_abit ? high_rd_data : low_rd_data;
  209. end else begin
  210. single_port_ram _TECHMAP_REPLACE_ (
  211. .clk(CLK),
  212. .addr({ {{`MEM_MAXWIDTH-ABITS}{1'bx}}, RD_ADDR }),
  213. .addr__U({ {{`MEM_MAXWIDTH-ABITS}{1'bx}}, RD_ADDR }),
  214. .addr__AL({ {{`MEM_MAXWIDTH-ABITS}{1'bx}}, RD_ADDR }),
  215. .addr__AU({ {{`MEM_MAXWIDTH-ABITS}{1'bx}}, RD_ADDR }),
  216. .data(RD_DATA),
  217. .out(WR_DATA),
  218. .we({ {8}{WR_EN} }),
  219. .we__U({ {8}{WR_EN} })
  220. );
  221. end
  222. endgenerate
  223. endmodule
  224.  
  225. module \$mul (A, B, Y);
  226. parameter A_SIGNED = 0;
  227. parameter B_SIGNED = 0;
  228. parameter A_WIDTH = 1;
  229. parameter B_WIDTH = 1;
  230. parameter Y_WIDTH = 1;
  231.  
  232. input [A_WIDTH-1:0] A;
  233. input [B_WIDTH-1:0] B;
  234. output [Y_WIDTH-1:0] Y;
  235.  
  236. wire [1023:0] _TECHMAP_DO_ = "proc; clean";
  237.  
  238. parameter _TECHMAP_CONSTMSK_A_ = A_WIDTH'b0;
  239. parameter _TECHMAP_CONSTMSK_B_ = B_WIDTH'b0;
  240. parameter _TECHMAP_CONSTVAL_A_ = A_WIDTH'bx;
  241. parameter _TECHMAP_CONSTVAL_B_ = B_WIDTH'bx;
  242.  
  243. integer a_width = A_WIDTH;
  244. integer b_width = B_WIDTH;
  245. integer tmp;
  246.  
  247. reg _TECHMAP_FAIL_;
  248. initial begin
  249. _TECHMAP_FAIL_ <= 0;
  250.  
  251. if (A_SIGNED || B_SIGNED)
  252. _TECHMAP_FAIL_ <= 1;
  253.  
  254. //if (A_WIDTH < B_WIDTH)
  255. // _TECHMAP_FAIL_ <= 1;
  256.  
  257. //if (A_WIDTH > `DSP_A_MAXWIDTH || B_WIDTH > `DSP_B_MAXWIDTH)
  258. // _TECHMAP_FAIL_ <= 1;
  259.  
  260. //if (Y_WIDTH > (`DSP_A_MAXWIDTH+`DSP_B_MAXWIDTH))
  261. // _TECHMAP_FAIL_ <= 1;
  262. end
  263.  
  264. localparam A_WIDTH_NEW = (_TECHMAP_CONSTMSK_A_ === {{A_WIDTH}{1'b1}} ? $clog2(_TECHMAP_CONSTVAL_A_) : A_WIDTH );
  265. localparam B_WIDTH_NEW = (_TECHMAP_CONSTMSK_B_ === {{B_WIDTH}{1'b1}} ? $clog2(_TECHMAP_CONSTVAL_B_) : B_WIDTH );
  266. //localparam Y_WIDTH_NEW = (A_WIDTH_NEW+BWIDTH_NEW-1 < Y_WIDTH ? A_WIDTH_NEW+B_WIDTH_NEW-1 : Y_WIDTH );
  267.  
  268. generate
  269. begin
  270. \$__mul_AxB_generator #(
  271. .A_SIGNED(A_SIGNED),
  272. .B_SIGNED(B_SIGNED),
  273. .A_WIDTH(A_WIDTH_NEW),
  274. .B_WIDTH(B_WIDTH_NEW),
  275. .Y_WIDTH(Y_WIDTH)
  276. ) mul_slice (
  277. .A(A[A_WIDTH_NEW-1:0]),
  278. .B(B[B_WIDTH_NEW-1:0]),
  279. .Y(Y[Y_WIDTH-1:0])
  280. );
  281. end
  282. endgenerate
  283. endmodule
  284.  
  285. module \$__mul_AxB_generator (A, B, Y);
  286. parameter A_SIGNED = 0;
  287. parameter B_SIGNED = 0;
  288. parameter A_WIDTH = 1;
  289. parameter B_WIDTH = 1;
  290. parameter Y_WIDTH = 1;
  291.  
  292. input [A_WIDTH-1:0] A;
  293. input [B_WIDTH-1:0] B;
  294. output [Y_WIDTH-1:0] Y;
  295.  
  296. wire [1023:0] _TECHMAP_DO_ = "proc; clean";
  297.  
  298. generate
  299. if (A_WIDTH > `DSP_A_MAXWIDTH) begin
  300. localparam n_floored = A_WIDTH/`DSP_A_MAXWIDTH;
  301. localparam n = n_floored + (n_floored*`DSP_A_MAXWIDTH < A_WIDTH ? 1 : 0);
  302. wire [Y_WIDTH-1:0] partial [n-1:1];
  303. wire [Y_WIDTH-1:0] partial_sum [n-2:0];
  304.  
  305. \$__mul_AxB_generator #(
  306. .A_SIGNED(A_SIGNED),
  307. .B_SIGNED(B_SIGNED),
  308. .A_WIDTH(`DSP_A_MAXWIDTH),
  309. .B_WIDTH(B_WIDTH),
  310. .Y_WIDTH(Y_WIDTH)
  311. ) mul_slice_first (
  312. .A(A[`DSP_A_MAXWIDTH-1:0]),
  313. .B(B),
  314. .Y(partial_sum[0])
  315. );
  316.  
  317. genvar i;
  318. generate
  319. for (i = 1; i < n-1; i=i+1) begin:slice
  320. \$__mul_AxB_generator #(
  321. .A_SIGNED(A_SIGNED),
  322. .B_SIGNED(B_SIGNED),
  323. .A_WIDTH(`DSP_A_MAXWIDTH),
  324. .B_WIDTH(B_WIDTH),
  325. .Y_WIDTH(Y_WIDTH)
  326. ) mul_slice (
  327. .A(A[(i+1)*`DSP_A_MAXWIDTH-1:i*`DSP_A_MAXWIDTH]),
  328. .B(B),
  329. .Y(partial[i])
  330. );
  331. assign partial_sum[i] = partial[i] << i*`DSP_A_MAXWIDTH + partial_sum[i-1];
  332. end
  333. endgenerate
  334.  
  335. \$__mul_AxB_generator #(
  336. .A_SIGNED(A_SIGNED),
  337. .B_SIGNED(B_SIGNED),
  338. .A_WIDTH(A_WIDTH-(n-1)*`DSP_A_MAXWIDTH),
  339. .B_WIDTH(B_WIDTH),
  340. .Y_WIDTH(Y_WIDTH)
  341. ) mul_slice_last (
  342. .A(A[A_WIDTH-1:(n-1)*`DSP_A_MAXWIDTH]),
  343. .B(B),
  344. .Y(partial[n-1])
  345. );
  346. assign Y = partial[n-1] << (n-1)*`DSP_A_MAXWIDTH + partial_sum[n-2];
  347. end
  348. else if (B_WIDTH > `DSP_B_MAXWIDTH) begin
  349. localparam n_floored = B_WIDTH/`DSP_B_MAXWIDTH;
  350. localparam n = n_floored + (n_floored*`DSP_B_MAXWIDTH < B_WIDTH ? 1 : 0);
  351. wire [Y_WIDTH-1:0] partial [n-1:1];
  352. wire [Y_WIDTH-1:0] partial_sum [n-2:0];
  353.  
  354. \$__mul_AxB_generator #(
  355. .A_SIGNED(A_SIGNED),
  356. .B_SIGNED(B_SIGNED),
  357. .A_WIDTH(A_WIDTH),
  358. .B_WIDTH(`DSP_B_MAXWIDTH),
  359. .Y_WIDTH(Y_WIDTH)
  360. ) mul_slice_first (
  361. .A(A),
  362. .B(B[`DSP_B_MAXWIDTH-1:0]),
  363. .Y(partial_sum[0])
  364. );
  365.  
  366. genvar i;
  367. generate
  368. for (i = 1; i < n-1; i=i+1) begin:slice
  369. \$__mul_AxB_generator #(
  370. .A_SIGNED(A_SIGNED),
  371. .B_SIGNED(B_SIGNED),
  372. .A_WIDTH(A_WIDTH),
  373. .B_WIDTH(`DSP_B_MAXWIDTH),
  374. .Y_WIDTH(Y_WIDTH)
  375. ) mul_slice (
  376. .A(A),
  377. .B(B[(i+1)*`DSP_B_MAXWIDTH-1:i*`DSP_B_MAXWIDTH]),
  378. .Y(partial[i])
  379. );
  380. assign partial_sum[i] = partial[i] << i*`DSP_B_MAXWIDTH + partial_sum[i-1];
  381. end
  382. endgenerate
  383.  
  384. \$__mul_AxB_generator #(
  385. .A_SIGNED(A_SIGNED),
  386. .B_SIGNED(B_SIGNED),
  387. .A_WIDTH(A_WIDTH),
  388. .B_WIDTH(B_WIDTH-(n-1)*`DSP_B_MAXWIDTH),
  389. .Y_WIDTH(Y_WIDTH)
  390. ) mul_slice_last (
  391. .A(A),
  392. .B(B[B_WIDTH-1:(n-1)*`DSP_B_MAXWIDTH]),
  393. .Y(partial[n-1])
  394. );
  395. assign Y = partial[n-1] << (n-1)*`DSP_B_MAXWIDTH + partial_sum[n-2];
  396.  
  397. end
  398. else begin
  399. if (`DSP_A_MAXWIDTH+`DSP_B_MAXWIDTH > Y_WIDTH) begin
  400. wire [`DSP_A_MAXWIDTH+`DSP_B_MAXWIDTH-Y_WIDTH-1:0] dummy;
  401. multiply _TECHMAP_REPLACE_ (
  402. .a({ {{`DSP_A_MAXWIDTH-A_WIDTH}{1'bx}}, A }),
  403. .b({ {{`DSP_B_MAXWIDTH-B_WIDTH}{1'bx}}, B }),
  404. .out({ dummy, Y })
  405. );
  406. end
  407. else
  408. multiply _TECHMAP_REPLACE_ (
  409. .a({ {{`DSP_A_MAXWIDTH-A_WIDTH}{1'bx}}, A }),
  410. .b({ {{`DSP_B_MAXWIDTH-B_WIDTH}{1'bx}}, B }),
  411. .out(Y[`DSP_A_MAXWIDTH+`DSP_B_MAXWIDTH-1:0])
  412. );
  413.  
  414. end
  415. endgenerate
  416. endmodule
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement