(原創) 如何使用參數式模組? (SOC) (Verilog) (C/C++) (template)

Abstract
Verilog一向不在語法上耍花槍,參數式模組的寫法,算是Verilog最奇特的寫法,在C與C++也沒有。

Introduction
使用環境:Quartus II 7.2 SP3 + ModelSim-Altera 6.1g + DE2(Cyclone II EP2C35F672C6)

counter是最基本的循序電路應用,為了更加彈性,我們想讓使用者可以自己指定counter的大小,從什麼數字開始數,數到哪個數字停止,而不是寫死在程式裡。

parameter_counter.v / Verilog

1 /* 
2 (C) OOMusou 2008 http://oomusou.cnblogs.com
3 
4 Filename    : parameter_counter.v
5 Compiler    : Quartus II 7.2 SP3 + ModelSim 6.1g
6 Description : demo how to use parameter
7 Release     : 07/09/2008 1.0
8 */
9 module parameter_counter (
10   clk,
11   rst_n,
12   cnt,
13 );
14 
15 parameter size  = 16;
16 parameter start = 0;
17 parameter stop  = 100;
18 
19 input clk;
20 input rst_n;
21 output reg [size-1 : 0] cnt;
22 
23 always@(posedge clk or negedge rst_n) begin
24   if (!rst_n)
25     cnt <= start;
26   else if (cnt == stop)
27     cnt <= start;
28   else
29     cnt <= cnt + 1;
30 end
31 
32 endmodule


15行

parameter size  = 16;
parameter start
= 0;
parameter stop 
= 100;


parameter宣告,即為Verilog的參數式寫法,之後接的是預設值,如此一來,counter的大小,從什麼數字開始數,數到哪個數字停止都不在是寫死在程式裡。

parameter_counter_tb.v / Verilog

1 /* 
2 (C) OOMusou 2008 http://oomusou.cnblogs.com
3 
4 Filename    : parameter_counter_tb.v
5 Compiler    : Quartus II 7.2 SP3 + ModelSim 6.1g
6 Description : demo how to use parameter in testbench
7 Release     : 07/09/2008 1.0
8 */
9 `timescale 1ns/10ps
10 `include "parameter_counter.v"
11 
12 module parameter_counter_tb;
13 
14 reg clk;
15 reg rst_n;
16 wire [7:0] cnt;
17 
18 // parameter_counter u0 (.clk(clk), .rst_n(rst_n), .cnt(cnt));
19 
20 parameter_counter # (.size(8),.start(3),.stop(9))
21 u0 (.clk(clk), .rst_n(rst_n), .cnt(cnt));
22 
23 /*
24 parameter_counter u0 (
25   .clk(clk),
26   .rst_n(rst_n),
27   .cnt(cnt)
28 );
29 
30 defparam u0.size = 8;
31 defparam u0.start = 3;
32 defparam u0.stop = 9;
33 */
34 parameter clkper = 100;
35 initial clk = 1'b0;
36 always #(clkper / 2) clk = ~clk;
37 
38 initial begin
39   rst_n = 1'b0;
40   #1;
41   rst_n = 1'b1;
42 end
43 
44 endmodule


要讓testbench調用module時,能動態的調整參數,有幾種寫法:

18行

parameter_counter u0 (.clk(clk), .rst_n(rst_n), .cnt(cnt));


若想使用預設的參數,則寫法並沒有兩樣。

20行

parameter_counter # (.size(8),.start(3),.stop(9))
u0 (.clk(clk), .rst_n(rst_n), .cnt(cnt));


若要傳入參數,這是第一種寫法,加上#,再用()傳入參數。

24行

parameter_counter u0 (
  .clk(clk),
  .rst_n(rst_n),
  .cnt(cnt)
);

defparam u0.size
= 8;
defparam u0.start
= 3;
defparam u0.stop
= 9;


這是第二種傳入參數的寫法,靠defparam將參數傳進去。

或許你會問,什麼時會用到這種寫法呢?
1.想讓自己的module更具彈性時。
2.使用megafunction時。

10行

`include "parameter_counter.v"


若搭配的是自己寫的module,就一定要加上include,若使用megafunction,就可省略include。

所以這參數式模組的寫法在實務上都看的到,是C/C++所沒有的語法,所以特別提出來。

執行結果

parameter00

C++的Nontype Template Parameter在Verilog重出江湖
看到以下的寫法時,你是否想起了C++的Nontype Template Parameter?

parameter_counter # (.size(8),.start(3),.stop(9))
u0 (.clk(clk), .rst_n(rst_n), .cnt(cnt));


我趕緊用C++也寫了一次同樣功能的counter

template_nontype_template_parameter_verilog.cpp / C++

1 /* 
2 (C) OOMusou 2008 http://oomusou.cnblogs.com
3 
4 Filename    : template_nontype_template_parameter_verilog.cpp
5 Compiler    : Visual C++ 8.0
6 Description : Demo how to use nontype template paramter
7 Release     : 07/09/2008 1.0
8 */
9 
10 #include <iostream>
11 
12 using namespace std;
13 
14 template<int start = 0, int stop = 100>
15 class parameter_counter {
16 private:
17   int cnt;
18 
19 public:
20   parameter_counter() : cnt(0) {}
21   void count();
22 };
23 
24 template<int start, int stop>
25 void parameter_counter<start, stop>::count() {
26   while(1) {
27     if (cnt == stop)
28       cnt = start;
29     else
30       cnt++;
31        
32     cout << cnt << endl;
33   }
34 }
35 
36 int main() {
37   parameter_counter<3, 9> u0;
38   //parameter_counter<> u0;
39   u0.count();
40 }


執行結果

3
4
5
6
7
8
9
3
4
5
6
7


由與軟體不需要clk與非同步的reset機制,這兩個都加以省略,原來的size也因為改用int代替,最後的nontype template paramter只剩下start與stop。

template<int start = 0, int stop = 100>
class parameter_counter {
private:
 
int cnt;

public:
  parameter_counter() : cnt(
0) {}
 
void count();
};


37行

parameter_counter<3, 9> u0;
//parameter_counter<> u0;


為C++傳入參數的方式,若C++要使用預設參數,仍需要<>表示。重點來了,讓我們再看一次Verilog語法:

parameter_counter # (.size(8),.start(3),.stop(9))
u0 (.clk(clk), .rst_n(rst_n), .cnt(cnt));


C++和Verilog的語法幾乎一樣!!也就是說,Verilog也支援泛型,但僅限於Nontype Template Parameter,Verilog雖然不像C++那樣的強大,但最少觀念是一樣的。

See Also
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)

posted on 2008-07-09 22:50  真 OO无双  阅读(55220)  评论(1编辑  收藏  举报

导航