Advertisement
Guest User

Untitled

a guest
Nov 7th, 2014
261
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VeriLog 13.16 KB | None | 0 0
  1. //-----------------------------------------------------------------
  2. // v422to444_v2mult_24t.v - 422 to 444 Format Converter
  3. //               Virtex-II Video Demo Board
  4. //
  5. //
  6. //
  7. //
  8. //                  Author: Gregg C. Hawkes
  9. //                  Senior Staff Applications Engineer
  10. //
  11. //                  Video Applications
  12. //                  Advanced Products Division
  13. //                  Xilinx, Inc.
  14. //
  15. //                  Copyright (c) 1999 Xilinx, Inc.
  16. //                  All rights reserved
  17. //
  18. //                  Date:   Aug. 6, 2001
  19. //                  For:    Video Demo Board
  20. //
  21. //                  RESTRICTED RIGHTS LEGEND
  22. //
  23. //      This software has not been published by the author, and  
  24. //      has been disclosed to others for the purpose of enhancing  
  25. //      and promoting design productivity in Xilinx products.
  26. //
  27. //      Therefore use, duplication or disclosure, now and in the  
  28. //      future should give consideration to the productivity  
  29. //      enhancements afforded the user of this code by the author's  
  30. //      efforts.  Thank you for using our products !
  31. //
  32. // Disclaimer:  THESE DESIGNS ARE PROVIDED "AS IS" WITH NO WARRANTY  
  33. //              WHATSOEVER AND XILINX SPECIFICALLY DISCLAIMS ANY  
  34. //              IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
  35. //              A PARTICULAR PURPOSE, OR AGAINST INFRINGEMENT.
  36. //
  37. //
  38. //  
  39. // Revision:
  40. //          Aug. 6, 2001     Creation
  41. //
  42. //
  43. // Other modules instanced in this design:
  44. //
  45. //          none
  46. /*
  47.  
  48. BRIEF DESCRIPTION
  49.  
  50. The process of 4:2:2 to 4:4:4 is simply creating the missing Cr and Cb
  51. components. This version accomplishes this task by merely duplicating
  52. the Cr and Cb information.
  53.  
  54. DETAILED DESCRIPTION
  55.  
  56. The video standard ITU-R BT.601 was introduced as the need for
  57. transporting digital component video between countries and standards
  58. increased. The analog component R'G'B' can be sampled in a very regular
  59. way and converted from 4:4:4 to the digital 4:2:2 format, essentially
  60. cutting in half the number of different components, Cr and Cb.  
  61.  
  62. The digital data is efficiently stored or transmitted to a destination
  63. that reverses the process, i.e. converts back to 4:4:4 format, and
  64. produces analog YUV or R'G'B' for display.
  65.  
  66.  
  67. 422 TO 444 CONVERSION
  68. ---------------------
  69.  
  70.  
  71. Bob Turney, Xilinx Labs supplied me with this one to try.
  72.  
  73.  
  74.   -   4  = 18'h3FFFC
  75.       6  = 18'h00006
  76.   -  12  = 18'h3FFF4
  77.      20  = 18'h00014
  78.   -  32  = 18'h3FFE0
  79.      48  = 18'h00030
  80.   -  70  = 18'h3FFBA
  81.     104  = 18'h00068
  82.   - 152  = 18'h3FF68
  83.     236  = 18'h000EC
  84.   - 420  = 18'h3FE5C
  85.    1300  = 18'h00514
  86.    1300  = 18'h00514
  87.   - 420  = 18'h3FE5C
  88.     236  = 18'h000EC
  89.   - 152  = 18'h3FF68
  90.     104  = 18'h00068
  91.   -  70  = 18'h3FFBA
  92.      48  = 18'h00030
  93.   -  32  = 18'h3FFE0
  94.      20  = 18'h00014
  95.   -  12  = 18'h3FFF4
  96.       6  = 18'h00006
  97.   -   4  = 18'h3FFFC
  98.  
  99.  
  100.        CrCb[i] = (
  101.              -    4*(CrCb[1]+CrCb[24])
  102.              +    6*(CrCb[2]+CrCb[23])
  103.              -   12*(CrCb[3]+CrCb[22])
  104.              +   20*(CrCb[4]+CrCb[21])
  105.              -   32*(CrCb[5]+CrCb[20])
  106.              +   48*(CrCb[6]+CrCb[19])
  107.              -   70*(CrCb[7]+CrCb[18])
  108.              +  104*(CrCb[8]+CrCb[17])
  109.              -  152*(CrCb[9]+CrCb[16])
  110.              +  236*(CrCb[10]+CrCb[15])
  111.              -  420*(CrCb[11]+CrCb[14])
  112.              + 1300*(CrCb[12]+CrCb[13]))/2048;  
  113.  
  114.  
  115. Design Information
  116. ------------------
  117. xc2v1000-ff896-6
  118.  
  119. MULT18X18s:  12   30%
  120. Slices      864   16%
  121. FFs       1,224   11%
  122. LUTs        409    3%
  123. IO           49   11%
  124. gates    62,199
  125.  
  126. Minimum period:   12.042ns (Maximum frequency: 83 MHz)
  127. Maximum net delay:   5.124ns
  128.  
  129. Note: Using coregen the V2 Mults can be replaced with parallel, 10 bit
  130. signed integer X 12 bit coefficients for roughly 68 LUTs and 34
  131. Registers each. This alternative would save the high performance V2
  132. Multipliers for other uses or allow the design to directly map to
  133. SPARTAN families.
  134.  
  135. */
  136.  
  137.  
  138. `timescale 1ns / 100ps
  139.  
  140.  
  141.  
  142. module v422to444_v2mult_24t (
  143. rst,             // resets input data register and control
  144. clk,             // video component rate clock, 27Mhz for SDTV
  145.  
  146. Fi,              // Low to High signals start of Field One
  147. Vi,              // High signals Vertical Blanking
  148. Hi,              // High signals Horizontal Blanking
  149.  
  150. Fo,              // Field signal delayed by pipe length
  151. Vo,              // Vertical signal delayed by pipe length
  152. Ho,              // Horizontal signal delayed by pipe length
  153. ceo,             // output data rate is 1/2 the clock rate
  154.  
  155. YCrCb_in,        // video component data, I[8].F[2], twos complement
  156.  
  157. Y_out,           // Y out, I[8].F[2], twos complement, clamped
  158. Cr_out,          // Cr out, I[8].F[2], twos complement, clamped
  159. Cb_out,          // Cb out, I[8].F[2], twos complement, clamped
  160. );
  161.  
  162.  
  163. /*
  164. TAPS must be an even number thereby making the length of the pipe
  165. an even number of FFs. I think 4 is the minimum.
  166. */
  167. parameter TAPS = 24;
  168. parameter FILTER_PIPE_LENGTH = 4;
  169.  
  170. input rst, clk, Hi, Vi, Fi;
  171. input[9:0] YCrCb_in;
  172.  
  173. output [9:0]  Y_out, Cr_out, Cb_out;
  174. output Ho, Vo, Fo, ceo;
  175.  
  176. reg [TAPS+FILTER_PIPE_LENGTH+7:0] H_rg, V_rg, F_rg;
  177. wire Ho, Vo, Fo, ceo, H_rising;
  178.  
  179. reg [1:0] cnt;
  180. wire Y_ld, select_real_CrCb, select_filt_CrCb;
  181.  
  182. reg [9:0] Y_rg, CrCb_rg;
  183.  
  184. // pixel component pipelines
  185. reg [9:0] Y_pipe  [(TAPS/2)+FILTER_PIPE_LENGTH-1:0];
  186. reg [9:0] CrCb_pipe [(TAPS*2)-1:0];
  187.  
  188. // filter components
  189. reg [10:0] CrCb_pre_add [(TAPS/2)-1:0];
  190.  
  191. wire [35:0] P0, P1, P2, P3, P4, P5,
  192.             P6, P7, P8, P9, P10, P11;
  193.  
  194. reg [23:0] CrCb_mult [11:0];     // only use [23:0]
  195. reg [23:0] CrCb_post_add;
  196. reg [9:0] CrCb_corrected, Cb_filt, Cr_filt;
  197.  
  198. reg [9:0] Y_out, Cr_out, Cb_out;
  199.  
  200. integer i;
  201.  
  202.  
  203.  
  204. //-----------------------------------------------------------------------
  205. //
  206. /*
  207. Delay SMPTE control signals F, V, H, by an amount equivalent to the
  208. modules pipe length. The will allow different modules to be swapped out
  209. without changing exterior control. this occurs in most of my modules.
  210. */
  211.  
  212.  
  213. always @ (posedge clk) begin
  214.   if (rst) begin F_rg <= 0; V_rg <= 0; H_rg <= 0; end
  215.   else begin
  216.     F_rg[TAPS+FILTER_PIPE_LENGTH+7:0] <= {F_rg[TAPS+FILTER_PIPE_LENGTH+6:0], Fi};
  217.     V_rg[TAPS+FILTER_PIPE_LENGTH+7:0] <= {V_rg[TAPS+FILTER_PIPE_LENGTH+6:0], Vi};
  218.     H_rg[TAPS+FILTER_PIPE_LENGTH+7:0] <= {H_rg[TAPS+FILTER_PIPE_LENGTH+6:0], Hi};
  219.   end
  220. end
  221.  
  222. assign Ho = H_rg[TAPS+FILTER_PIPE_LENGTH+7];
  223. assign Vo = V_rg[TAPS+FILTER_PIPE_LENGTH+7];
  224. assign Fo = F_rg[TAPS+FILTER_PIPE_LENGTH+7];
  225.  
  226.  
  227.  
  228. //-----------------------------------------------------------------------
  229. //
  230. // Identify Y and CrCb valid
  231. //
  232.  
  233. assign H_rising = ~H_rg[0] & Hi;
  234.  
  235. always @ (posedge clk) begin
  236.   if (rst | H_rising) cnt <= 1;
  237.   else cnt <= cnt+1;
  238. end
  239.  
  240. assign Y_ld = (cnt == 2'b01) | (cnt == 2'b11);
  241. assign ceo = Y_ld;
  242. assign select_real_CrCb = (cnt == 2'b11);
  243. assign select_filt_CrCb = (cnt == 2'b01);
  244.  
  245.  
  246. //-----------------------------------------------------------------------
  247. //
  248. // Separate the Y and CrCb data streams
  249. //
  250. always @ (posedge clk) begin
  251.   if (rst) Y_rg <= 10'h040;
  252.   else if (Y_ld)  Y_rg <= YCrCb_in;
  253.   else Y_rg <= Y_rg;
  254. end
  255.  
  256. always @ (posedge clk) begin
  257.   if (rst) CrCb_rg <= 0;
  258.   else if (~Y_ld) CrCb_rg <= YCrCb_in;
  259.   else CrCb_rg <= CrCb_rg;
  260. end
  261.  
  262.  
  263.  
  264. //-----------------------------------------------------------------------
  265. //
  266. // 10 bit Y, Cr and Cb pipe registers, connected head to tail.  There are  
  267. // 12 Y registers, 48 CrCb registers.
  268. //
  269. always @ (posedge clk) begin
  270.   if (rst) Y_pipe[0] <= 10'h040;
  271.   else if (Y_ld)  Y_pipe[0] <= Y_rg;
  272.   else Y_pipe[0] <= Y_pipe[0];
  273. end
  274.  
  275. always @ (posedge clk) begin
  276.   for (i = 1; i <= (TAPS/2)+FILTER_PIPE_LENGTH-1; i = i+1) begin
  277.     if (rst) Y_pipe[i] <= 10'h040;
  278.     else if (Y_ld) Y_pipe[i] <= Y_pipe[i-1];
  279.     else Y_pipe[i] <= Y_pipe[i];
  280.   end
  281. end
  282.  
  283. always @ (posedge clk) begin
  284.   if (rst) CrCb_pipe[0] <= 0;
  285.   else if (~Y_ld) CrCb_pipe[0] <= CrCb_rg;
  286.   else CrCb_pipe[0] <= CrCb_pipe[0];
  287. end
  288.  
  289. always @ (posedge clk) begin
  290.   for (i = 1; i <= (2*TAPS)-1; i = i+1) begin
  291.     if (rst) CrCb_pipe[i] <= 0;
  292.     else if (~Y_ld) CrCb_pipe[i] <= CrCb_pipe[i-1];
  293.     else CrCb_pipe[i] <= CrCb_pipe[i];
  294.   end
  295. end
  296.  
  297.  
  298.  
  299. //-----------------------------------------------------------------------
  300. //
  301. // Pre multiply adder
  302. //
  303. always @ (posedge clk) begin
  304.   for (i = 0; i <= (TAPS/2)-1; i = i+1) begin
  305.     if (rst) CrCb_pre_add[i] <= 0;
  306.     else if (~Y_ld)  
  307.       CrCb_pre_add[i] <= CrCb_pipe[((2*TAPS)-1)-(2*i)] + CrCb_pipe[(2*i)+1];
  308.     else CrCb_pre_add[i] <= CrCb_pre_add[i];
  309.   end
  310. end
  311.  
  312.  
  313. //-----------------------------------------------------------------------
  314. //
  315. /*
  316. Multipliers
  317. Note: A is 12 bits, B is 10 bits + 10 bits, so make P = 24 bits
  318. maximum positive value = 960 X 1300 = 1248000 or 130b00 hex = 21 bits
  319. maximum negative value = 960 X -420 = -403200 or  9d900 hex = 20 bits
  320. */
  321.  
  322. MULT18X18 U1  (.P(P0),  .A(18'h3FFFC), .B({7'h00, CrCb_pre_add[0]}));
  323. MULT18X18 U2  (.P(P1),  .A(18'h00006), .B({7'h00, CrCb_pre_add[1]}));
  324. MULT18X18 U3  (.P(P2),  .A(18'h3FFF4), .B({7'h00, CrCb_pre_add[2]}));
  325. MULT18X18 U4  (.P(P3),  .A(18'h00014), .B({7'h00, CrCb_pre_add[3]}));
  326. MULT18X18 U5  (.P(P4),  .A(18'h3FFE0), .B({7'h00, CrCb_pre_add[4]}));
  327. MULT18X18 U6  (.P(P5),  .A(18'h00030), .B({7'h00, CrCb_pre_add[5]}));
  328. MULT18X18 U7  (.P(P6),  .A(18'h3FFBA), .B({7'h00, CrCb_pre_add[6]}));
  329. MULT18X18 U8  (.P(P7),  .A(18'h00068), .B({7'h00, CrCb_pre_add[7]}));
  330. MULT18X18 U9  (.P(P8),  .A(18'h3FF68), .B({7'h00, CrCb_pre_add[8]}));
  331. MULT18X18 U10 (.P(P9),  .A(18'h000EC), .B({7'h00, CrCb_pre_add[9]}));
  332. MULT18X18 U11 (.P(P10), .A(18'h3FE5C), .B({7'h00, CrCb_pre_add[10]}));
  333. MULT18X18 U12 (.P(P11), .A(18'h00514), .B({7'h00, CrCb_pre_add[11]}));
  334.  
  335.  
  336.  
  337. //-----------------------------------------------------------------------
  338. //
  339. // Register outputs of multiply
  340. //
  341. always @ (posedge clk) begin
  342.   if (rst) begin
  343.     for (i = 0; i <= 11; i = i+1) CrCb_mult[i] <= 0;
  344.   end
  345.   else if (~Y_ld) begin
  346.     CrCb_mult[0]  <=  P0[23:0];
  347.     CrCb_mult[1]  <=  P1[23:0];
  348.     CrCb_mult[2]  <=  P2[23:0];
  349.     CrCb_mult[3]  <=  P3[23:0];
  350.     CrCb_mult[4]  <=  P4[23:0];
  351.     CrCb_mult[5]  <=  P5[23:0];
  352.     CrCb_mult[6]  <=  P6[23:0];
  353.     CrCb_mult[7]  <=  P7[23:0];
  354.     CrCb_mult[8]  <=  P8[23:0];
  355.     CrCb_mult[9]  <=  P9[23:0];
  356.     CrCb_mult[10] <= P10[23:0];
  357.     CrCb_mult[11] <= P11[23:0];
  358.   end
  359.   else begin
  360.     for (i = 0; i <= 11; i = i+1) CrCb_mult[i] <= CrCb_mult[i];
  361.   end
  362. end
  363.  
  364.  
  365.  
  366. //-----------------------------------------------------------------------
  367. //
  368. // Post multiply adder (this needs to run at 74.25 MHz for HDTV).  This
  369. // is the performance bottle-neck.  It can be easily pipelined.
  370. //
  371. always @ (posedge clk) begin
  372.   if (rst) CrCb_post_add <= 0;
  373.   else if (~Y_ld) CrCb_post_add <=
  374.        CrCb_mult[0] + CrCb_mult[1] + CrCb_mult[2]  + CrCb_mult[3]
  375.     +  CrCb_mult[4] + CrCb_mult[5] + CrCb_mult[6]  + CrCb_mult[7]
  376.     +  CrCb_mult[8] + CrCb_mult[9] + CrCb_mult[10] + CrCb_mult[11];
  377.   else CrCb_post_add <=  CrCb_post_add;
  378. end
  379.  
  380.  
  381.  
  382. //-----------------------------------------------------------------------
  383. //
  384. // Correct overflows and underflows
  385. //
  386. /*
  387. Note 1: Wire shift by 11 bits is equivalent to dividing by 2048 on the
  388. input. This is to account for the non fractional coefficients in the FIR
  389. filter multiplies.
  390.  
  391. Note 2: A new Cr_filt and Cb_filt are available every four clock ticks.
  392. */
  393.  
  394. always @ (posedge clk) begin
  395.   if (rst) CrCb_corrected <= 9'h40;
  396.   else if (~Y_ld & (CrCb_post_add[20:11] > 12'h3AC)) CrCb_corrected <= 12'h3AC;
  397.   else if (~Y_ld & (CrCb_post_add[20:11] < 12'h40 )) CrCb_corrected <= 12'h40;
  398.   else if (~Y_ld) CrCb_corrected <= CrCb_post_add[20:11];
  399.   else CrCb_corrected <= CrCb_corrected;
  400. end
  401.  
  402. always @ (posedge clk) begin
  403.   if (rst) begin Cr_filt <= 0; Cb_filt <= 0; end
  404.   else if (~Y_ld) begin Cr_filt <= CrCb_corrected; Cb_filt <= Cr_filt; end
  405. end
  406.  
  407.  
  408.  
  409. //-----------------------------------------------------------------------
  410. //
  411. // Divide the CrCb stream into separate outgoing components
  412. //
  413. always @ (posedge clk) begin
  414.   if (rst) begin Y_out <= 0; Cr_out <= 0; Cb_out <= 0; end
  415.   else if (select_real_CrCb) begin
  416.     Y_out  <= Y_pipe[(TAPS/2)+FILTER_PIPE_LENGTH-1];
  417.     Cb_out <= CrCb_pipe[(TAPS/2)+FILTER_PIPE_LENGTH];
  418.     Cr_out <= CrCb_pipe[(TAPS/2)+FILTER_PIPE_LENGTH-1];
  419.   end
  420.   else if (select_filt_CrCb) begin
  421.     Y_out  <= Y_pipe[(TAPS/2)+FILTER_PIPE_LENGTH-1];
  422.     Cb_out <= Cb_filt;
  423.     Cr_out <= Cr_filt;
  424.   end
  425.   else begin
  426.     Y_out  <= Y_out;
  427.     Cb_out <= Cb_out;
  428.     Cr_out <= Cr_out;
  429.   end
  430. end
  431.  
  432.  
  433.  
  434. endmodule
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement