最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

【基于FPGA的圖像處理工程】邊緣檢測工程之sccb傳輸模塊代碼解析

2023-07-29 07:15 作者:明德?lián)P易老師  | 我要投稿

【基于FPGA的圖像處理工程】

? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?—邊緣檢測工程:sccb傳輸模塊代碼解析


本文為明德?lián)P原創(chuàng)文章,轉(zhuǎn)載請注明出處!
Sccb傳輸模塊的功能: 按照sccb傳輸協(xié)議的時序,傳輸上游模塊的攝像頭配置指令。

?一、? ?? ???設(shè)計架構(gòu)

???下圖是官方中給出的SCCB時序圖,雖然是三線的但是我們也可以用來學(xué)習(xí)二線的時序。


?1.? ?協(xié)議開始:在SIO_C高電平期間,SIO_D由高變低,表示傳輸?shù)拈_始。如上圖所示,在開始數(shù)據(jù)傳輸時,SIO_C要先處于高電平,由SIO_D(即本模塊中的 sio_d_w 信號)先保持一段時間高電平并產(chǎn)生下降沿來標(biāo)志傳輸開始,其中SIO_D 變低到 SIO_C 變低,最少 100ns。



2.? ?? ???協(xié)議結(jié)束:在SIO_C高電平期間,SIO_D由高變低,表示數(shù)據(jù)傳輸?shù)耐V?。如上圖所示,在停止數(shù)據(jù)傳輸時,SIO_C也要首先置于高電平,由SIO_D(即本模塊中的sio_d_w信號)產(chǎn)生上升沿并保持一段時間來標(biāo)志傳輸結(jié)束,其中 SIO_C 變高到 SIO_D 變高,最少100ns。


? ?? 3.? ?? ???其他時候 ,SIO_D 只能在 SIO_C=0 時才變化。


? 4.? ?? ???時序圖中的 SIO_D 和 SIO_C,分別是本模塊中的 sio_d_w 和 sio_c 信號。
??5.? ?? ???寫寄存器的過程:a.協(xié)議開始;b.發(fā)送設(shè)備ID編號,等待;c. 發(fā)送要存入的寄存器地址,等待;d.發(fā)送要寫入的數(shù)據(jù);e.協(xié)議結(jié)束。

?6.? ?? ???讀寄存器的時序:a.協(xié)議開始;b.發(fā)送設(shè)備ID編號,等待;c. 發(fā)送要讀取的寄存器地址,等待;d. 協(xié)議結(jié)束;e.協(xié)議開始;f. 發(fā)送設(shè)備ID編號,等待;g. 讀取Byte數(shù)據(jù),NACK=1;h. 協(xié)議結(jié)束。


本模塊計數(shù)器的架構(gòu)圖如下所示


A、Count_sck:時鐘計數(shù)器。使用此計數(shù)器,來對傳輸1位數(shù)據(jù)時鐘進(jìn)行計數(shù)。本模塊時鐘是25M,周期為40ns,而SCCB傳輸1bit本模塊設(shè)定為 120*40ns,所以此計數(shù)器每次要數(shù)120個。
B、Count_bit:位計數(shù)器。使用此計數(shù)器,要對傳輸1個階段的位進(jìn)行計數(shù)。根據(jù)sccb傳輸協(xié)議,讀寄存器時序和寫寄存器時序的位長度都是不一樣的,可以通過變量bit_num來確定。C、Count_duan:階段計數(shù)器。使用此計數(shù)器,對讀或者寫的階段進(jìn)行計數(shù)。根據(jù)sccb傳輸協(xié)議,讀寄存器狀態(tài)需要兩個階段,而寫寄存器狀態(tài)只有一個階段,所以通過變量duan_num來確定。


?二、? ?? ???舉例說明

收到寫使能 wen=1(同一時刻過來了 寫數(shù)據(jù)wdata 和 寄存器地址數(shù)據(jù)sub_addr )時,產(chǎn)生如下波形。

?如上圖所示,收到 wen=1,并且 sub_addr=8’h12 和 wdata=8’h04,這意味著要向地址為8’h12的寄存器寫數(shù)據(jù)8’h04因此各個信號如下變化:
sio_c 和 sio_d_w:波形首先產(chǎn)生了開始位。然后依次發(fā)送 8’h42(固定值)和 x=1,發(fā)送 8’h12(sub_addr)和 x=1,發(fā)送 8’h04(wdata)和 x=1。之后是結(jié)束位,最后是 2 個間隔位(固定發(fā) 11)。 至此整個過程結(jié)束。en_sio_d_w:在收到 wr_en=1 開始,en_sio_d_w 就為 1,直到最后結(jié)束。
收到讀使能ren=1(同一時刻過來了寄存器地址數(shù)據(jù)sub_addr,而wdata不關(guān)心)時,產(chǎn)生如下波形。

如上圖所示,收到ren=1,并且sub_addr=8’h12(注意要展開來看,看rd_en=1時刻) ,這意味著要讀地址為8’h12的寄存器的數(shù)據(jù),因此各個信號如下變化sio_c、sio_d_w、rdata和rdata_vld:波形首先產(chǎn)生了開始位;然后依次發(fā)送8’h42(固定值)和x=1;然后再發(fā)送8’h12(sub_addr)和x=1,然后是結(jié)束位和間隔位。之后又是開始位,發(fā)送8’h43(固定值)和x=1。之后在8個sio_c周期內(nèi),取sio_d_r的值并保存到rdata中(8個值保存后,就可以產(chǎn)生1個時鐘周期的rdata_vld=1脈沖)。最后是結(jié)束位和間隔位(固定發(fā)11)。 至此整個過程結(jié)束。en_sio_d_w:在收到rd_en=1開始,en_sio_d_w就為1,直到讀取數(shù)據(jù)為0,讀取數(shù)據(jù)后為1,整個過程結(jié)束后又為0。

本模塊準(zhǔn)備好指示信號rdy在整個波形產(chǎn)生期間,以及wen=1和ren=1時,均為0(rdy可以組合邏輯產(chǎn)生并輸出)。

? ?? ?
?三、? ?? ???信號意義


? ?四、參考代碼

? 下面展出本模塊的設(shè)計,歡迎進(jìn)一步交流,如果需要源代碼,歡迎與本人聯(lián)系。

  1. module sccb(

  2. ? ? clk? ?? ? ,

  3. ? ? rst_n? ???,

  4. ? ? ren? ?? ? ,

  5. ? ? wen? ?? ? ,

  6. ? ? sub_addr??,

  7. ? ? rdata? ???,

  8. ? ? rdata_vld ,

  9. ? ? wdata? ???,

  10. ? ? rdy? ?? ? ,

  11. ? ? sio_c? ???,

  12. ? ? sio_d_r? ?,

  13. ? ? en_sio_d_w,

  14. ? ? sio_d_w? ?? ?? ?

  15. );


  16. ? ? //參數(shù)定義

  17. ? ? parameter? ?? ?SIO_C??= 120 ;


  18. ? ? //輸入信號定義

  19. ? ? input? ?? ?? ?? ?? ?clk? ?? ?;//25m

  20. ? ? input? ?? ?? ?? ?? ?rst_n? ? ;

  21. ? ? input? ?? ?? ?? ?? ?ren? ?? ?;

  22. ? ? input? ?? ?? ?? ?? ?wen? ?? ?;

  23. ? ? input [7:0]? ?? ?? ?sub_addr ;

  24. ? ? input [7:0]? ?? ?? ?wdata? ? ;


  25. ? ? //輸出信號定義

  26. ? ? output[7:0]? ?? ?? ?rdata? ? ;

  27. ? ? output? ?? ?? ?? ???rdata_vld;

  28. ? ? output? ?? ?? ?? ???sio_c? ? ;//208kHz

  29. ? ? output? ?? ?? ?? ???rdy? ?? ?;


  30. ? ? input? ?? ?? ?? ?? ?sio_d_r? ?;

  31. ? ? output? ?? ?? ?? ???en_sio_d_w;

  32. ? ? output? ?? ?? ?? ???sio_d_w? ?;

  33. ? ? reg? ?? ?? ?? ?? ???en_sio_d_w;

  34. ? ? reg? ?? ?? ?? ?? ???sio_d_w? ?;


  35. ? ? //輸出信號reg定義

  36. ? ? reg [7:0]? ?? ?? ???rdata? ? ;

  37. ? ? reg? ?? ?? ?? ?? ???rdata_vld;

  38. ? ? reg? ?? ?? ?? ?? ???sio_c? ? ;

  39. ? ? reg? ?? ?? ?? ?? ???rdy? ?? ?;


  40. ? ? //中間信號定義

  41. ? ? reg??[7:0]? ?? ?? ? count_sck? ???;

  42. ? ? reg??[4:0]? ?? ?? ? count_bit? ???;

  43. ? ? reg??[1:0]? ?? ?? ? count_duan? ? ;

  44. ? ? reg? ?? ?? ?? ?? ???flag_add? ?? ?;

  45. ? ? reg? ?? ?? ?? ?? ???flag_sel? ?? ???;

  46. ? ? reg??[4:0]? ?? ?? ? bit_num? ?? ? ;

  47. ? ? reg??[1:0]? ?? ?? ? duan_num? ?? ?;

  48. ? ? reg??[29:0]? ?? ?? ?out_data? ?? ?;


  49. ? ? wire? ?? ?? ?? ?? ? add_count_sck ;

  50. ? ? wire? ?? ?? ?? ?? ? end_count_sck ;

  51. ? ? wire? ?? ?? ?? ?? ? add_count_bit ;

  52. ? ? wire? ?? ?? ?? ?? ? end_count_bit ;

  53. ? ? wire? ?? ?? ?? ?? ? add_count_duan;

  54. ? ? wire? ?? ?? ?? ?? ? end_count_duan;

  55. ? ? wire? ?? ?? ?? ?? ? sio_c_h2l? ???;

  56. ? ? wire? ?? ?? ?? ?? ? sio_c_l2h? ???;

  57. ? ? wire? ?? ?? ?? ?? ? out_data_time ;

  58. ? ? wire? ?? ?? ?? ?? ? rdata_time? ? ;

  59. ? ? wire [7:0]? ?? ?? ? rd_com? ?? ???;

  60. ? ?

  61. ? ? always??@(posedge clk or negedge rst_n)begin

  62. ? ?? ???if(rst_n==1'b0)begin

  63. ? ?? ?? ?? ?count_sck <= 0;

  64. ? ?? ???end

  65. ? ?? ???else if(add_count_sck)begin

  66. ? ?? ?? ?? ?if(end_count_sck)begin

  67. ? ?? ?? ?? ?? ? count_sck <= 0;

  68. ? ?? ?? ?? ?end

  69. ? ?? ?? ?? ?else begin

  70. ? ?? ?? ?? ?? ? count_sck <= count_sck + 1;

  71. ? ?? ?? ?? ?end

  72. ? ?? ???end

  73. ? ? end


  74. ? ? assign add_count_sck = flag_add??;

  75. ? ? assign end_count_sck = add_count_sck && count_sck == SIO_C-1;


  76. ? ? always??@(posedge clk or negedge rst_n)begin

  77. ? ?? ???if(rst_n==1'b0)begin

  78. ? ?? ?? ?? ?count_bit <= 0;

  79. ? ?? ???end

  80. ? ?? ???else if(add_count_bit)begin

  81. ? ?? ?? ?? ?if(end_count_bit)begin

  82. ? ?? ?? ?? ?? ? count_bit <= 0;

  83. ? ?? ?? ?? ?end

  84. ? ?? ?? ?? ?else begin

  85. ? ?? ?? ?? ?? ? count_bit <= count_bit + 1;

  86. ? ?? ?? ?? ?end

  87. ? ?? ???end

  88. ? ? end


  89. ? ? assign add_count_bit = end_count_sck;

  90. ? ? assign end_count_bit = add_count_bit && count_bit == bit_num+2-1;


  91. ? ? always??@(posedge clk or negedge rst_n)begin

  92. ? ?? ???if(rst_n==1'b0)begin

  93. ? ?? ?? ?? ?count_duan <= 0;

  94. ? ?? ???end

  95. ? ?? ???else if(add_count_duan)begin

  96. ? ?? ?? ?? ?if(end_count_duan)begin

  97. ? ?? ?? ?? ?? ? count_duan <= 0;

  98. ? ?? ?? ?? ?end

  99. ? ?? ?? ?? ?else begin

  100. ? ?? ?? ?? ?? ? count_duan <= count_duan + 1;

  101. ? ?? ?? ?? ?end

  102. ? ?? ???end

  103. ? ? end


  104. ? ? assign add_count_duan = end_count_bit;

  105. ? ? assign end_count_duan = add_count_duan && count_duan == duan_num-1;


  106. ? ? always??@(posedge clk or negedge rst_n)begin

  107. ? ?? ???if(rst_n==1'b0)begin

  108. ? ?? ?? ?? ?flag_add <= 0;

  109. ? ?? ???end

  110. ? ?? ???else if(ren || wen)begin

  111. ? ?? ?? ?? ?flag_add <= 1;

  112. ? ?? ???end

  113. ? ?? ???else if(end_count_duan)begin

  114. ? ?? ?? ?? ?flag_add <= 0;

  115. ? ?? ???end

  116. ? ? end


  117. ? ? always??@(posedge clk or negedge rst_n)begin

  118. ? ?? ???if(rst_n==1'b0)begin

  119. ? ?? ?? ?? ?flag_sel <= 0;

  120. ? ?? ???end

  121. ? ?? ???else if(wen)begin

  122. ? ?? ?? ?? ?flag_sel <= 0;

  123. ? ?? ???end

  124. ? ?? ???else if(ren)begin

  125. ? ?? ?? ?? ?flag_sel <= 1;

  126. ? ?? ???end

  127. ? ? end


  128. ? ? always??@(*)begin

  129. ? ?? ???if(flag_sel==1)begin

  130. ? ?? ?? ?? ?bit_num = 21;

  131. ? ?? ?? ?? ?duan_num = 2;

  132. ? ?? ???end

  133. ? ?? ???else begin

  134. ? ?? ?? ?? ?bit_num = 30;

  135. ? ?? ?? ?? ?duan_num = 1;

  136. ? ?? ???end

  137. ? ? end


  138. ? ? always??@(posedge clk or negedge rst_n)begin

  139. ? ?? ???if(rst_n==1'b0)begin

  140. ? ?? ?? ?? ?sio_c <= 1;

  141. ? ?? ???end

  142. ? ?? ???else if(sio_c_h2l)begin

  143. ? ?? ?? ?? ?sio_c <= 0;

  144. ? ?? ???end

  145. ? ?? ???else if(sio_c_l2h)begin

  146. ? ?? ?? ?? ?sio_c <= 1;

  147. ? ?? ???end

  148. ? ? end


  149. ? ? assign sio_c_h2l = count_bit >= 0 && count_bit < (bit_num-2) && add_count_sck && count_sck == SIO_C-1;

  150. ? ? assign sio_c_l2h = add_count_sck && count_sck == SIO_C/2-1;



  151. ? ? always @ (*)begin

  152. ? ?? ???if(flag_sel==1)begin

  153. ? ?? ?? ?? ?out_data <= {1'h0,rd_com,1'h1,sub_addr,1'h1,1'h0,1'h1,9'h0};

  154. ? ?? ???end

  155. ? ?? ???else begin

  156. ? ?? ?? ?? ?out_data <= {1'h0,8'h42,1'h1,sub_addr,1'h1,wdata,1'h1,1'h0,1'h1};

  157. ? ?? ???end

  158. ? ? end


  159. ? ? assign rd_com = (flag_sel==1 && count_duan == 0)? 8'h42 : 8'h43;


  160. ? ? always??@(posedge clk or negedge rst_n)begin

  161. ? ?? ???if(rst_n==1'b0)begin

  162. ? ?? ?? ?? ?en_sio_d_w <= 0;

  163. ? ?? ???end

  164. ? ?? ???else if(ren || wen)begin

  165. ? ?? ?? ?? ?en_sio_d_w <= 1;

  166. ? ?? ???end

  167. ? ?? ???else if(end_count_duan)begin

  168. ? ?? ?? ?? ?en_sio_d_w <= 0;

  169. ? ?? ???end

  170. ? ?? ???else if(flag_sel==1 && count_duan == 1 && count_bit == 10 && add_count_sck && count_sck == 1-1)begin

  171. ? ?? ?? ?? ?en_sio_d_w <= 0;

  172. ? ?? ???end

  173. ? ?? ???else if(flag_sel==1 && count_duan == 1 && count_bit == 18 && add_count_sck && count_sck == 1-1)begin

  174. ? ?? ?? ?? ?en_sio_d_w <= 1;

  175. ? ?? ???end

  176. ? ? end



  177. ? ? always??@(posedge clk or negedge rst_n)begin

  178. ? ?? ???if(rst_n==1'b0)begin

  179. ? ?? ?? ?? ?sio_d_w <= 1;

  180. ? ?? ???end

  181. ? ?? ???else if(out_data_time)begin

  182. ? ?? ?? ?? ?sio_d_w <= out_data[30-count_bit-1];

  183. ? ?? ???end

  184. ? ? end


  185. ? ? assign out_data_time = count_bit >= 0 && count_bit < bit_num && add_count_sck && count_sck == SIO_C/4-1;


  186. ? ? always??@(posedge clk or negedge rst_n)begin

  187. ? ?? ???if(rst_n==1'b0)begin

  188. ? ?? ?? ?? ?rdata <= 0;

  189. ? ?? ???end

  190. ? ?? ???else if(rdata_time)begin

  191. ? ?? ?? ?? ?rdata[17-count_bit] <= sio_d_r;

  192. ? ?? ???end

  193. ? ? end


  194. ? ? assign rdata_time = flag_sel==1 && count_duan==1 && count_bit>=10 && count_bit<18 && add_count_sck && count_sck==SIO_C/4*3-1;


  195. ? ? always??@(posedge clk or negedge rst_n)begin

  196. ? ?? ???if(rst_n==1'b0)begin

  197. ? ?? ?? ?? ?rdata_vld <= 0;

  198. ? ?? ???end

  199. ? ?? ???else if(flag_sel==1 && end_count_duan)begin

  200. ? ?? ?? ?? ?rdata_vld <= 1;

  201. ? ?? ???end

  202. ? ?? ???else begin

  203. ? ?? ?? ?? ?rdata_vld <= 0;

  204. ? ?? ???end

  205. ? ? end


  206. ? ? always??@(*)begin

  207. ? ?? ???if(ren || wen || flag_add)begin

  208. ? ?? ?? ?? ?rdy = 0;

  209. ? ?? ???end

  210. ? ?? ???else begin

  211. ? ?? ?? ?? ?rdy = 1;

  212. ? ?? ???end

  213. ? ? end


  214. endmodule



?復(fù)制代碼

明德?lián)P專注FPGA研究,我司正在連載兩本書籍:《基于FPGA至簡設(shè)計法實現(xiàn)的圖像邊緣檢測系統(tǒng)》(http://www.fpgabbs.cn/forum.php?mod=viewthread&tid=691)、《ASIC和FPGA時序約束理論與應(yīng)用》(http://www.fpgabbs.cn/forum.php?mod=viewthread&tid=705),有興趣點擊觀看。


【基于FPGA的圖像處理工程】邊緣檢測工程之sccb傳輸模塊代碼解析的評論 (共 條)

分享到微博請遵守國家法律
渝中区| 武夷山市| 乌恰县| 理塘县| 康乐县| 新竹市| 阿克陶县| 泽库县| 吴旗县| 达孜县| 渝北区| 竹山县| 新密市| 沂南县| 休宁县| 阿巴嘎旗| 泽库县| 惠州市| 都昌县| 兰溪市| 满城县| 新巴尔虎右旗| 靖州| 岑溪市| 罗源县| 五家渠市| 蒲江县| 上虞市| 韶山市| 清水河县| 大同县| 黔西| 濮阳县| 黄骅市| 延庆县| 延安市| 昭平县| 银川市| 鄂尔多斯市| 塔城市| 呼和浩特市|