(原創) 如何將parallel轉成serial?如何將serial轉成parallel? (SOC) (Verilog)
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)
當load為1且clk rising edge時,parallel data載入至register當中,當load為0且clk rising edge時,register資料依序往前遞移,在最後一個register將資料送出。
p2s.v / Verilog
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可參考(筆記) 如何將值delay n個clock? (SOC) (Verilog)。
Testbench
p2s_tb.v / Verilog
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)
serial data依序送進shift register,當en為1時,一次將shift register內的資料送進parallel out。
s2p.v / Verilog
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
Testbench
s2p_tb.v / Verilog
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用,與(筆記) 如何將值delay n個clock? (SOC) (Verilog)一樣,只是在此順便提及。
s2s.v / Verilog
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
Testbench
s2s_tb.v/ Verilog
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
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
Testbench
p2p_tb.v / Verilog
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
模擬結果
完整程式碼下載
p2s.7z (parallel in serial out)
s2p.7z (serial in parallel out)
s2s.7z (serial in serial out)
p2p.7z (parallel in parallel out)
See Also
(筆記) 如何將值delay n個clock? (SOC) (Verilog)
Reference
陳慶逸 2008,VHDL數位電路設計實務教本 (使用Quartus II),儒林圖書公司
鄭信源 2007,Verilog硬體描述語言數位電路,儒林圖書公司