FPGA实现cameralink接口图像传输

[复制链接]
查看714 | 回复0 | 2023-8-23 11:41:49 | 显示全部楼层 |阅读模式

  • 硬件芯片实现cameralink图像传输
  常用的cameralink收发芯片有DS90CR287和288,287发送288吸收。只必要向芯片提供像素时钟和cameralink协议中的28位数据信号就可以实现根本的图像数据传输非常方便。关于cameralink协议的常识详见http://t.csdn.cn/XtFud
                         同样地,吸收方可以直接吸收28位数据还原位图像数据信号。
  发送端代码:
  示例是之前做的16位红外相机上使用cameralink发送吸收模块,使用的是287、288芯片,base模式
  1. /* Document info
  2. document class : RES
  3. module name    : CameraLink_Out
  4. module purpose : video out
  5. version        : V1.0
  6. author         : mayidianzi
  7. */
  8. ///
  9. `timescale 1ns / 1ps
  10. module Clink(
  11.     input I_img_frame,
  12.     input I_img_line,
  13.     input[15:0] I_img_data,
  14.     input  I_img_clk,
  15.     output O_img_clk,
  16.     output[27:0] O_tx_data
  17.     );
  18.    
  19. /  parameter set  \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  20.   internal signal  \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  21. //wire S_data_vld       ;
  22. //wire S_data_vld_1     ;
  23. //wire S_img_clk        ;
  24. //wire S_img_fram       ;
  25. //wire S_img_line       ;
  26. //wire[15:0] S_img_data ;
  27. //reg[2:0] S_count_t    ;
  28. assign O_img_clk = I_img_clk;
  29. //assign S_data_vld = (S_count_t==1) ? 1 : 0;
  30. //assign S_data_vld_1 = S_data_vld & I_img_line;
  31. wire[7:0] S_port_a,S_port_b,S_port_c;
  32. assign  S_port_a = I_img_data[7:0];
  33. assign  S_port_b = I_img_data[15:8];
  34. assign  S_port_c = 8'h0000;
  35. assign  O_tx_data[4:0]   =  S_port_a[4:0];
  36. assign  O_tx_data[5]     =  S_port_a[7];
  37. assign  O_tx_data[6]     =  S_port_a[5];         
  38. assign  O_tx_data[9:7]   =  S_port_b[2:0];
  39. assign  O_tx_data[11:10] =  S_port_b[7:6];
  40. assign  O_tx_data[14:12] =  S_port_b[5:3];         
  41. assign  O_tx_data[15]    =  S_port_c[0];
  42. assign  O_tx_data[17:16] =  S_port_c[7:6];
  43. assign  O_tx_data[22:18] =  S_port_c[5:1];
  44. assign  O_tx_data[23]    =  0;             //spare
  45. assign  O_tx_data[24]    =  I_img_line;    //LVAL,line valid                                 
  46. assign  O_tx_data[25]    =  I_img_frame;    //FVAL,frame valid
  47. assign  O_tx_data[26]    =  1;             //DVAL,data valid
  48. assign  O_tx_data[27]    =  S_port_a[6];
  49.       instance       \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  50. ila_0 ila_0_i(
  51.    .clk(I_img_clk),
  52.    .probe0(I_img_data),
  53.    .probe1(I_img_line),
  54.    .probe2(I_img_frame)
  55.    );
  56.     main programe    \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  57. endmodule
复制代码
吸收端代码
  1. /* Document info
  2. document class : RES
  3. module name    : CameraLink_Out
  4. module purpose : video out
  5. version        : V1.0
  6. author         : mayidianzi
  7. */
  8. ///
  9. `timescale 1ns / 1ps
  10. module Clink_B(
  11.     input[27:0]            I_tx_data,    //
  12.     input                I_reset,
  13.     input                I_img_clk,
  14.     output reg[15:0]    O_img_data, //S_sensor_data
  15.     output reg            O_img_frame, //S_sensor_FS
  16.     output reg            O_img_line //S_sensor_LINE
  17.     );
  18.    
  19. /  parameter set  \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  20.   internal signal  \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  21. //wire S_data_vld       ;
  22. //wire S_data_vld_1     ;
  23. //wire S_img_clk        ;
  24. wire S_img_frame       ;
  25. wire S_img_line       ;
  26. wire[15:0] S_img_data ;
  27. //reg[2:0] S_count_t    ;
  28. //assign S_data_vld = (S_count_t==1) ? 1 : 0;
  29. //assign S_data_vld_1 = S_data_vld & I_img_line;
  30. wire[7:0] S_port_a,S_port_b,S_port_c;
  31. assign  S_img_data[7:0]    =    S_port_a ;
  32. assign  S_img_data[15:8]=    S_port_b ;
  33. assign  S_port_a[4:0]    =     I_tx_data[4:0]    ;
  34. assign  S_port_a[7]        =     I_tx_data[5]      ;
  35. assign  S_port_a[5]          =     I_tx_data[6]      ;        
  36. assign  S_port_b[2:0]    =     I_tx_data[9:7]    ;
  37. assign  S_port_b[7:6]    =     I_tx_data[11:10]  ;
  38. assign  S_port_b[5:3]    =     I_tx_data[14:12]  ;         
  39. assign  S_port_c[0]        =     I_tx_data[15]     ;
  40. assign  S_port_c[7:6]    =     I_tx_data[17:16]  ;
  41. assign  S_port_c[5:1]    =     I_tx_data[22:18]  ;
  42. assign  S_img_line       =     I_tx_data[24]     ; //LVAL,line valid                                 
  43. assign  S_img_frame      =     I_tx_data[25]     ;  //FVAL,frame valid
  44. assign  S_port_a[6]        =     I_tx_data[27]     ;
  45.       instance       \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  46. ila_4 ila_4_i(
  47.    .clk(I_img_clk),
  48.    .probe0(O_img_data),
  49.    .probe1(O_img_line),
  50.    .probe2(O_img_frame),
  51.    .probe3(I_img_clk)
  52.    );
  53.     main programe    \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  54. always@(posedge I_img_clk or posedge I_reset)
  55. begin
  56.     if(I_reset)   
  57.         begin
  58.             O_img_data    <= 0;
  59.             O_img_frame    <= 0;
  60.             O_img_line     <= 0;
  61.         end   
  62.     else
  63.         begin
  64.             O_img_data    <= S_img_data;
  65.             O_img_frame    <= S_img_frame;
  66.             O_img_line     <= S_img_line;
  67.         end
  68. end
  69. endmodule
复制代码

  • FPGA编写cameralink接口模块传输
  如果倒霉用芯片可以用verilog写一个发送吸收模块,按照标定时序将28位数通过4条差分线输出,这里必要留意4条数据线的同步时钟是像素同步时钟的7倍,像素时钟不可太高。硬件布线方面留意全部的差分线要做等长。若吸收端发现吸收数据和采样时钟不同步可通过时钟模块恰当调解同步时钟的相位。以上为调试过程的履历。
  发送端代码:
  同样是以16位红外相机为例,Base模式
  1. `timescale 1ns / 1ps
  2. //
  3. // Company:
  4. // Engineer:
  5. //
  6. // Create Date: 2022/03/22 08:31:08
  7. // Design Name:
  8. // Module Name: Clink
  9. // Project Name:
  10. // Target Devices:
  11. // Tool Versions:
  12. // Description:
  13. //
  14. // Dependencies:
  15. //
  16. // Revision:
  17. // Revision 0.01 - File Created
  18. // Additional Comments:
  19. //
  20. //
  21. module Clink(
  22.   input I_336M_CLK,
  23.   input I_reset,
  24.   input[15:0] I_video_data,
  25.   input I_frame_valid,
  26.   input I_line_valid,
  27.   output reg O_X0,
  28.   output reg O_X1,
  29.   output reg O_X2,
  30.   output reg O_X3,
  31.   output reg O_XCLK
  32.   );
  33.   
  34. //
  35. reg[7:0] S_cnt;
  36. reg[1:0] S_cnt0;
  37. reg[27:0] S_tx_data;
  38. reg S_frame_valid, S_line_valid;
  39. reg[15:0] S_video_data;
  40. wire[7:0] S_port_a,S_port_b,S_port_c;
  41. assign  S_port_a = S_video_data[7:0];
  42. assign  S_port_b = S_video_data[15:8];
  43. assign  S_port_c = 8'h0000;
  44. //
  45. /*ila_0 ila_0_i(
  46.    .clk(I_336M_CLK),
  47.    .probe0(O_XCLK),
  48.    .probe1(S_line_valid),
  49.    .probe2(S_frame_valid),
  50.    .probe3(O_X0),
  51.    .probe4(O_X1),
  52.    .probe5(O_X2),
  53.    .probe6(O_X3),
  54.    .probe7(S_cnt),
  55.    .probe8(S_video_data)
  56.    );*/
  57. //
  58. always @(posedge I_336M_CLK or negedge I_reset)
  59. begin
  60.     if(!I_reset)
  61.         begin
  62.             S_video_data     <= 0;
  63.             S_frame_valid     <= 0;
  64.             S_line_valid     <= 0;
  65.         end
  66.     else
  67.         begin
  68.             S_video_data     <= I_video_data;
  69.             S_frame_valid     <= I_frame_valid;
  70.             S_line_valid    <= I_line_valid;
  71.         end
  72. end
  73. always @(posedge I_336M_CLK or negedge I_reset)
  74. begin
  75.     if(!I_reset)
  76.         S_tx_data <= 0;
  77.     else if(S_cnt == 0 & S_cnt0 == 0)
  78.         begin
  79.             S_tx_data[4:0]   <=  S_port_a[4:0];
  80.             S_tx_data[5]     <=  S_port_a[7];
  81.             S_tx_data[6]     <=  S_port_a[5];         
  82.             S_tx_data[9:7]   <=  S_port_b[2:0];
  83.             S_tx_data[11:10] <=  S_port_b[7:6];
  84.             S_tx_data[14:12] <=  S_port_b[5:3];         
  85.             S_tx_data[15]    <=  S_port_c[0];
  86.             S_tx_data[17:16] <=  S_port_c[7:6];
  87.             S_tx_data[22:18] <=  S_port_c[5:1];
  88.             S_tx_data[23]    <=  0;             //spare
  89.             S_tx_data[24]    <=  S_line_valid;    //LVAL,line valid                                 
  90.             S_tx_data[25]    <=  S_frame_valid;    //FVAL,frame valid
  91.             S_tx_data[26]    <=  1;             //DVAL,data valid
  92.             S_tx_data[27]    <=  S_port_a[6];
  93.         end
  94. end
  95.   
  96. always @(posedge I_336M_CLK or negedge I_reset)
  97. begin
  98.     if(!I_reset)
  99.         begin
  100.             S_cnt0     <= 0;
  101.             S_cnt     <= 0;   
  102.         end
  103.       else
  104.         begin
  105.             if(S_cnt0 == 1 & S_cnt == 6)
  106.                 begin
  107.                     S_cnt0     <= 0;
  108.                     S_cnt     <= 0;            
  109.                 end
  110.             else if(S_cnt0 == 1)
  111.                 begin
  112.                     S_cnt     <= S_cnt + 1;   
  113.                     S_cnt0     <= 0;
  114.                 end
  115.             else
  116.                 S_cnt0 <= S_cnt0 + 1;
  117.         end
  118. end
  119. always @ (posedge I_336M_CLK or negedge I_reset)
  120. begin
  121.       if(!I_reset)
  122.         O_XCLK <= 0;
  123.     else if(S_cnt0 == 1)
  124.         begin
  125.             if(S_cnt == 5)
  126.                 O_XCLK <= 1;
  127.             if(S_cnt == 2)
  128.                 O_XCLK <= 0;
  129.         end
  130. end
  131.   
  132.   
  133. always @ (posedge I_336M_CLK or negedge I_reset)
  134. begin
  135.       if(!I_reset)
  136.         begin
  137.             O_X0 <= 0;
  138.             O_X1 <= 0;
  139.             O_X2 <= 0;
  140.             O_X3 <= 0;
  141.         end
  142.       else if(S_cnt0 == 1)
  143.         begin
  144.             case(S_cnt)
  145.                 8'd0:
  146.                 begin
  147.                     O_X0 <= S_tx_data[7];
  148.                     O_X1 <= S_tx_data[18];
  149.                     O_X2 <= S_tx_data[26];
  150.                     O_X3 <= S_tx_data[23];
  151.                 end
  152.                 8'd1:
  153.                 begin
  154.                     O_X0 <= S_tx_data[6];
  155.                     O_X1 <= S_tx_data[15];
  156.                     O_X2 <= S_tx_data[25];
  157.                     O_X3 <= S_tx_data[17];
  158.                   end
  159.                 8'd2:
  160.                 begin
  161.                     O_X0 <= S_tx_data[4];
  162.                     O_X1 <= S_tx_data[14];
  163.                     O_X2 <= S_tx_data[24];
  164.                     O_X3 <= S_tx_data[16];
  165.                   end
  166.                 8'd3:
  167.                 begin
  168.                     O_X0 <= S_tx_data[3];
  169.                     O_X1 <= S_tx_data[13];
  170.                     O_X2 <= S_tx_data[22];
  171.                     O_X3 <= S_tx_data[11];
  172.                 end
  173.                 8'd4:
  174.                 begin
  175.                     O_X0 <= S_tx_data[2];
  176.                     O_X1 <= S_tx_data[12];
  177.                     O_X2 <= S_tx_data[21];
  178.                     O_X3 <= S_tx_data[10];
  179.                 end
  180.                 8'd5:
  181.                 begin
  182.                     O_X0 <= S_tx_data[1];
  183.                     O_X1 <= S_tx_data[9];
  184.                     O_X2 <= S_tx_data[20];
  185.                     O_X3 <= S_tx_data[5];
  186.                 end
  187.                 8'd6:
  188.                 begin
  189.                     O_X0 <= S_tx_data[0];
  190.                     O_X1 <= S_tx_data[8];
  191.                     O_X2 <= S_tx_data[19];
  192.                     O_X3 <= S_tx_data[27];
  193.                 end
  194.                 default
  195.                 begin
  196.                     O_X0 <= 0;
  197.                     O_X1 <= 0;
  198.                     O_X2 <= 0;
  199.                     O_X3 <= 0;
  200.                 end     
  201.             endcase
  202.         end
  203. end
  204. endmodule
复制代码
担当端
  代码中含有图像数据行帧头校验内容,自行忽略
  1. /* Document info
  2. document class : RES
  3. module name    : CameraLink_Out
  4. module purpose : video out
  5. version        : V1.0
  6. author         : mayidianzi
  7. */
  8. ///
  9. `timescale 1ns / 1ps
  10. module Cameralink_in(
  11.     input I_CLINK_RxCLK,
  12.     input I_CLINK_RxCLKx7,
  13.     input I_CLINK_RxCLKx7_n,
  14.     input I_RESET,
  15.     input I_X0,  
  16.     input I_X1,
  17.     input I_X2,
  18.     input I_X3,
  19.     output O_img_clk,
  20.     output O_img_frame,
  21.     output reg O_img_line,
  22.     output O_img_vblank,
  23.     output O_img_hblank,
  24.     output[15:0] O_img_data
  25.     );
  26.    
  27. /  parameter set  \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  28. reg [27:0] S_Rx_data;
  29. reg [27:0] S_data, S_data_d0;
  30. reg S_RxCLK_d0, S_RxCLK_d1, S_RxCLK_d2;
  31. wire [15:0] S_img_data;
  32. wire S_img_line, S_img_frame;
  33. reg[15:0] S_imgdata_d0, S_imgdata_d1, S_imgdata_d2, S_imgdata_d3, S_cnt;
  34. reg        S_img_frame_d0, S_img_frame_d1, S_img_frame_d2, S_img_frame_d3, S_false;
  35. reg[3:0]    S_state;
  36. parameter    C_idle = 0,
  37.             C_valid = 1;
  38.   internal signal  \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  39. ila_4 ila_4_i(
  40.     .clk (I_CLINK_RxCLK),
  41.     .probe0(O_img_frame),
  42.     .probe1(O_img_line),
  43.     .probe2(S_RxCLK_d1),
  44.     .probe3(S_RxCLK_d2),
  45.     .probe4(O_img_data),
  46.     .probe5(I_X0),
  47.     .probe6(I_X1),
  48.     .probe7(I_X2),
  49.     .probe8(S_false),
  50.     .probe9(S_Rx_data),
  51.     .probe10(S_img_data)
  52.     );
  53.   internal signal  \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  54. assign O_img_vblank = ~O_img_frame;
  55. assign O_img_hblank = O_img_frame & (~O_img_line);
  56. wire[7:0] S_port_a, S_port_b, S_port_c;
  57. assign  S_img_data[7:0] = S_port_a;
  58. assign  S_img_data[15:8] = S_port_b;
  59. assign  S_port_a[4:0] = S_data_d0[4:0];   
  60. assign  S_port_a[7]   = S_data_d0[5];      
  61. assign  S_port_a[5]   = S_data_d0[6];              
  62. assign  S_port_b[2:0] = S_data_d0[9:7];   
  63. assign  S_port_b[7:6] = S_data_d0[11:10];  
  64. assign  S_port_b[5:3] = S_data_d0[14:12];            
  65. //assign  S_port_c[0]   = S_data[15];     
  66. //assign  S_port_c[7:6] = S_data[17:16];  
  67. //assign  S_port_c[5:1] = S_data[22:18];  
  68. assign  S_img_line    = S_data_d0[24];      //LVAL,line valid                                 
  69. assign  S_img_frame   = S_data_d0[25];      //FVAL,frame valid
  70. assign  S_port_a[6]   = S_data_d0[27];   
  71. assign  O_img_frame = S_img_frame_d3;
  72. //assign  O_img_line = S_img_line;
  73. assign  O_img_data = S_imgdata_d3;
  74. //assign  O_img_clk = S_RxCLK_d2;
  75. assign    O_img_clk = I_CLINK_RxCLK;
  76.   internal signal  \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  77. always @(posedge I_CLINK_RxCLKx7 or posedge I_RESET)//
  78. begin
  79.   if(I_RESET)
  80.     begin
  81.       S_RxCLK_d0 <= 0;
  82.       S_RxCLK_d1 <= 0;
  83.       S_RxCLK_d2 <= 0;
  84.     end
  85.   else
  86.    begin
  87.     S_RxCLK_d0 <= I_CLINK_RxCLK;
  88.     S_RxCLK_d1 <= S_RxCLK_d0;
  89.     S_RxCLK_d2 <= S_RxCLK_d1;
  90.    end
  91. end
  92. always @(posedge S_RxCLK_d2 or posedge I_RESET)//
  93. begin
  94.   if(I_RESET)
  95.     S_data <= 0;
  96.   else
  97.     S_data[27:0] <= {S_Rx_data[21:18],S_Rx_data[27],S_Rx_data[17:13],S_Rx_data[26:25],
  98.                      S_Rx_data[12:9],S_Rx_data[24:23],S_Rx_data[8:5],S_Rx_data[22],S_Rx_data[4:0]};
  99. end
  100. always @(posedge I_CLINK_RxCLKx7_n or posedge I_RESET)//
  101. begin
  102.   if(I_RESET)
  103.     S_Rx_data <= 0;
  104.   else
  105.     begin
  106.       S_Rx_data[27:21] <= {S_Rx_data[26:21],I_X3};
  107.       S_Rx_data[20:14] <= {S_Rx_data[19:14],I_X2};
  108.       S_Rx_data[13:7]  <= {S_Rx_data[12:7],I_X1};
  109.       S_Rx_data[6:0]   <= {S_Rx_data[5:0],I_X0};
  110.     end
  111. end
  112. always @(posedge I_CLINK_RxCLK or posedge I_RESET)//
  113. begin
  114.   if(I_RESET)
  115.     S_data_d0 <= 0;
  116.   else
  117.     S_data_d0[27:0] <= S_data;
  118. end
  119. always @(posedge I_CLINK_RxCLK or posedge I_RESET)//
  120. begin
  121.   if(I_RESET)
  122.     begin
  123.         S_imgdata_d0 <= 0;
  124.         S_imgdata_d1 <= 0;
  125.         S_imgdata_d2 <= 0;
  126.         S_imgdata_d3 <= 0;
  127.         S_img_frame_d0 <= 0;
  128.         S_img_frame_d1 <= 0;
  129.         S_img_frame_d2 <= 0;
  130.         S_img_frame_d3 <= 0;
  131.     end
  132.   else
  133.     begin
  134.         S_imgdata_d0 <= S_img_data;
  135.         S_imgdata_d1 <= S_imgdata_d0;
  136.         S_imgdata_d2 <= S_imgdata_d1;
  137.         S_imgdata_d3 <= S_imgdata_d2;
  138.         S_img_frame_d0 <= S_img_frame;
  139.         S_img_frame_d1 <= S_img_frame_d0;
  140.         S_img_frame_d2 <= S_img_frame_d1;
  141.         S_img_frame_d3 <= S_img_frame_d2;
  142.     end
  143. end
  144. always @(posedge I_CLINK_RxCLK or posedge I_RESET)//
  145. begin
  146.   if(I_RESET)
  147.     begin
  148.         S_state <= C_idle;
  149.         S_cnt <= 0;
  150.     end
  151.   else
  152.     begin
  153.         case(S_state)
  154.             C_idle:
  155.                 if(S_imgdata_d0 == 16'haa || S_imgdata_d1 == 16'hbb)
  156.                     begin
  157.                         S_state <= C_valid;
  158.                         S_cnt <= 0;
  159.                     end
  160.                 else
  161.                     S_cnt <= S_cnt + 1;
  162.             C_valid:
  163.                 if(S_cnt >= 645)
  164.                     begin
  165.                         S_cnt <= 0;
  166.                         S_state <= C_idle;
  167.                     end
  168.                 else
  169.                     S_cnt <= S_cnt + 1;
  170.         endcase
  171.     end
  172. end
  173. always @(posedge I_CLINK_RxCLK or posedge I_RESET)//
  174. begin
  175.   if(I_RESET)
  176.     begin
  177.         O_img_line <= 0;
  178.         S_false <= 0;
  179.     end
  180.   else
  181.     begin
  182.         case(S_state)
  183.             C_idle:
  184.                 begin
  185.                     O_img_line <= 0;
  186.                     if(S_cnt > 2500)
  187.                         S_false <= 1;
  188.                 end
  189.             C_valid:
  190.                 O_img_line <= 1;
  191.         endcase
  192.     end
  193. end
  194. endmodule
复制代码
之前的领导头脑不好,天天催,代码写的很随意,将就看吧。
  写的很累,给个关注可以不。

来源:https://blog.csdn.net/weixin_43498765/article/details/129428668
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则