Abstract在實務上常常需要將parallel轉成serial,然後再將serial轉成parallel,本文討論如何實現這些功能。
Introduction使用環境:NC-Verilog 5.4 + Debussy 5.4 v9 + Quartus II 7.2
很多介面都採用serial傳輸,如I2C、LVDS、mini-LVDS…等,在寫入時必須將parallel資料轉成serial,讀出時又得將serial轉成parallel,所以是個常用的電路,其原理就是使用shift register來達成,本文將一一討論parallel轉serial,serial轉parallel,也順便討論parallel轉parallel與serial轉serial。
並進串出 (Parallel In Serial Out)
![p2s04 p2s04](https://images.cnblogs.com/cnblogs_com/oomusou/WindowsLiveWriter/parallelserialserialparallelSOCVerilog_11F66/p2s04_aa843293-4c5d-4bc7-86d6-aaeca192b6c0.gif)
當load為1且clk rising edge時,parallel data載入至register當中,當load為0且clk rising edge時,register資料依序往前遞移,在最後一個register將資料送出。
p2s.v / Verilog
1 /* 2 (C) OOMusou 2009 http://oomusou.cnblogs.com 3 4 Filename : p2s.v 5 Simulator : NC-Verilog 5.4 + Debussy 5.4 v9 6 Synthesizer : Quartus II 7.2 7 Description : parallel in serial out rtl 8 Release : Oct/24/2009 1.0 9 */ 10 11 module p2s ( 12 clk, 13 rst_n, 14 load, 15 pi, 16 so 17 ); 18 19 input clk; 20 input rst_n; 21 input load; 22 input [ 3 : 0 ] pi; 23 output so; 24 25 reg [ 3 : 0 ] r; 26 27 always @( posedge clk or negedge rst_n) 28 if ( ~ rst_n) 29 r <= 4 ' h0; 30 else if (load) 31 r <= pi; 32 else 33 r <= {r, 1 ' b0}; 34 35 assign so = r[ 3 ]; 36 37 endmodule 33行
用Verilog實現shift register有很多種方式,但以33行這種方式最精簡,其他coding style可參考。
Testbenchp2s_tb.v / Verilog
1 /* 2 (C) OOMusou 2009 http://oomusou.cnblogs.com 3 4 Filename : p2s_tb.v 5 Simulator : NC-Verilog 5.4 + Debussy 5.4 v9 6 Description : parallel in serial out testbench 7 Release : Oct/24/2009 1.0 8 */ 9 10 `timescale 1ns / 1ns 11 ` include " p2s.v " 12 13 module p2s_tb; 14 15 reg clk; 16 reg rst_n; 17 reg load; 18 reg [ 3 : 0 ] pi; 19 wire so; 20 21 initial begin 22 load = 1 ' b0; 23 pi = 4 ' h0; 24 # 10 ; 25 load <= 1 ' b1; 26 pi <= 4 ' b1010; 27 # 20 ; 28 load <= 1 ' b0; 29 pi <= 4 ' h0; 30 end 31 32 initial clk = 1 ' b0; 33 always # 10 clk = ~ clk; 34 35 initial begin 36 rst_n = 1 ' b0; 37 # 5 ; 38 rst_n = 1 ' b1; 39 end 40 41 initial begin 42 $fsdbDumpfile( " p2s.fsdb " ); 43 $fsdbDumpvars( 0 , p2s_tb); 44 # 150 ; 45 $finish; 46 end 47 48 p2s p2s_0 ( 49 .clk(clk), 50 .rst_n(rst_n), 51 .load(load), 52 .pi(pi), 53 .so(so) 54 ); 55 56 endmodule 模擬結果
串進並出 (Serial In Parallel Out)
![p2s07 p2s07](https://images.cnblogs.com/cnblogs_com/oomusou/WindowsLiveWriter/parallelserialserialparallelSOCVerilog_11F66/p2s07_0e624458-18b4-4cf7-af1b-6329df4ebd9d.gif)
serial data依序送進shift register,當en為1時,一次將shift register內的資料送進parallel out。
s2p.v / Verilog
1 /* 2 (C) OOMusou 2009 http://oomusou.cnblogs.com 3 4 Filename : s2p.v 5 Simulator : NC-Verilog 5.4 + Debussy 5.4 v9 6 Synthesizer : Quartus II 7.2 7 Description : serial in parallel out rtl 8 Release : Oct/24/2009 1.0 9 */ 10 11 module s2p ( 12 clk, 13 rst_n, 14 en, 15 si, 16 po 17 ); 18 19 input clk; 20 input rst_n; 21 input en; 22 input si; 23 output [ 3 : 0 ] po; 24 25 reg [ 3 : 0 ] r; 26 27 always @( posedge clk or negedge rst_n) 28 if ( ~ rst_n) 29 r <= 8 ' h0; 30 else 31 r <= {r, si}; 32 33 assign po = (en) ? r : 4 ' h0; 34 35 endmodule Testbenchs2p_tb.v / Verilog 1 /* 2 (C) OOMusou 2009 http://oomusou.cnblogs.com 3 4 Filename : p2s_tb.v 5 Simulator : NC-Verilog 5.4 + Debussy 5.4 v9 6 Description : serial in parallel out testbench 7 Release : Oct/24/2009 1.0 8 */ 9 10 `timescale 1ns / 1ns 11 ` include " s2p.v " 12 13 module s2p_tb; 14 15 reg clk; 16 reg rst_n; 17 reg en; 18 reg si; 19 wire [ 3 : 0 ] po; 20 21 initial begin 22 en = 1 ' b0; 23 si = 1 ' b0; 24 # 10 ; 25 // 4'b1010 26 si = 1 ' b1; 27 # 20 ; 28 si = 1 ' b0; 29 # 20 ; 30 si = 1 ' b1; 31 # 20 ; 32 en = 1 ' b1; 33 si = 1 ' b0; 34 # 20 ; 35 en = 1 ' b0; 36 si = 1 ' b0; 37 end 38 39 initial clk = 1 ' b0; 40 always # 10 clk = ~ clk; 41 42 initial begin 43 rst_n = 1 ' b0; 44 # 5 ; 45 rst_n = 1 ' b1; 46 end 47 48 initial begin 49 $fsdbDumpfile( " s2p.fsdb " ); 50 $fsdbDumpvars( 0 , s2p_tb); 51 # 200 ; 52 $finish; 53 end 54 55 s2p s2p_0 ( 56 .clk(clk), 57 .rst_n(rst_n), 58 .en(en), 59 .si(si), 60 .po(po) 61 ); 62 63 endmodule 模擬結果
串進串出 (Serial In Serial Out)基本上串進串出沒有任何實用功能,只能當成delay n個clk用,與一樣,只是在此順便提及。
s2s.v / Verilog
1 /* 2 (C) OOMusou 2009 http://oomusou.cnblogs.com 3 4 Filename : s2p.v 5 Simulator : NC-Verilog 5.4 + Debussy 5.4 v9 6 Synthesizer : Quartus II 7.2 7 Description : serial in serial out rtl 8 Release : Oct/24/2009 1.0 9 */ 10 11 module s2s ( 12 clk, 13 rst_n, 14 si, 15 so 16 ); 17 18 input clk; 19 input rst_n; 20 input si; 21 output so; 22 23 reg [ 3 : 0 ] r; 24 25 always @( posedge clk or negedge rst_n) 26 if ( ~ rst_n) 27 r <= 8 ' h0; 28 else 29 r <= {r, si}; 30 31 assign so = r[ 3 ]; 32 33 endmodule Testbenchs2s_tb.v/ Verilog 1 /* 2 (C) OOMusou 2009 http://oomusou.cnblogs.com 3 4 Filename : s2s_tb.v 5 Simulator : NC-Verilog 5.4 + Debussy 5.4 v9 6 Description : serial in serial out testbench 7 Release : Oct/24/2009 1.0 8 */ 9 10 `timescale 1ns / 1ns 11 ` include " s2s.v " 12 13 module s2s_tb; 14 15 reg clk; 16 reg rst_n; 17 reg si; 18 wire so; 19 20 initial begin 21 si = 1 ' b0; 22 # 10 ; 23 // 4'b1010 24 si = 1 ' b1; 25 # 20 ; 26 si = 1 ' b0; 27 # 20 ; 28 si = 1 ' b0; 29 # 20 ; 30 si = 1 ' b1; 31 end 32 33 initial clk = 1 ' b0; 34 always # 10 clk = ~ clk; 35 36 initial begin 37 rst_n = 1 ' b0; 38 # 5 ; 39 rst_n = 1 ' b1; 40 end 41 42 initial begin 43 $fsdbDumpfile( " s2s.fsdb " ); 44 $fsdbDumpvars( 0 , s2s_tb); 45 # 200 ; 46 $finish; 47 end 48 49 s2s s2s_0 ( 50 .clk(clk), 51 .rst_n(rst_n), 52 .si(si), 53 .so(so) 54 ); 55 56 endmodule 模擬結果
並進並出 (Parallel In Parallel Out)並進並出也沒實用功能,只是順便提及。
p2p.v / Verilog
1 /* 2 (C) OOMusou 2009 http://oomusou.cnblogs.com 3 4 Filename : p2p.v 5 Simulator : NC-Verilog 5.4 + Debussy 5.4 v9 6 Synthesizer : Quartus II 7.2 7 Description : parallel in parallel out rtl 8 Release : Oct/24/2009 1.0 9 */ 10 11 module p2p ( 12 clk, 13 rst_n, 14 pi, 15 po 16 ); 17 18 input clk; 19 input rst_n; 20 input [ 3 : 0 ] pi; 21 output [ 3 : 0 ] po; 22 23 reg [ 3 : 0 ] r; 24 25 always @( posedge clk or negedge rst_n) 26 if ( ~ rst_n) 27 r <= 8 ' h0; 28 else 29 r <= pi; 30 31 assign po = r; 32 33 endmodule Testbenchp2p_tb.v / Verilog 1 /* 2 (C) OOMusou 2009 http://oomusou.cnblogs.com 3 4 Filename : p2p_tb.v 5 Simulator : NC-Verilog 5.4 + Debussy 5.4 v9 6 Description : parallel in parallel out testbench 7 Release : Oct/24/2009 1.0 8 */ 9 10 `timescale 1ns / 1ns 11 ` include " p2p.v " 12 13 module p2p_tb; 14 15 reg clk; 16 reg rst_n; 17 reg [ 3 : 0 ] pi; 18 wire [ 3 : 0 ] po; 19 20 initial begin 21 pi = 4 ' h0; 22 # 10 ; 23 pi <= 4 ' b1010; 24 # 20 ; 25 pi <= 4 ' b1100; 26 # 20 27 pi <= 4 ' h0; 28 end 29 30 initial clk = 1 ' b0; 31 always # 10 clk = ~ clk; 32 33 initial begin 34 rst_n = 1 ' b0; 35 # 5 ; 36 rst_n = 1 ' b1; 37 end 38 39 initial begin 40 $fsdbDumpfile( " p2p.fsdb " ); 41 $fsdbDumpvars( 0 , p2p_tb); 42 # 100 ; 43 $finish; 44 end 45 46 p2p p2p_0 ( 47 .clk(clk), 48 .rst_n(rst_n), 49 .pi(pi), 50 .po(po) 51 ); 52 53 endmodule 模擬結果
完整程式碼下載 (parallel in serial out)
(serial in parallel out)
(serial in serial out)
(parallel in parallel out)
See Also
Reference
陳慶逸 2008,VHDL數位電路設計實務教本 (使用Quartus II),儒林圖書公司
鄭信源 2007,Verilog硬體描述語言數位電路,儒林圖書公司