轉貼自陳碩 的Verilog与C++的类比

1. Verilog中的module对应C++中的class。它们都可以实例化。例如可以写一个FullAdder module,表示全加器这种器件。

(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)module FullAdder(a, b, cin, sum, cout);
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  input a, b, cin;
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  output sum, cout;
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)


然后在执行8-bit补码加减运算的ALU module中实例化8个FullAdder,表示ALU用到了8个FullAdder。

(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)module ALU(a, b, result, cout, is_add);
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  input[
7:0]  a, b;
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  input       is_add;
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  output[
7:0] result;
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  output      cout;
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  wire[
7:0] b_not = ~b;
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  wire[
7:0] b_in = is_add ? b : b_not;
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  wire[
7:0] carry;
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  assign carry[
0= is_add ? 1'b0 : 1'b1;
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  
// module 实例化
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  
// 8-bit ripple adder
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)
  FullAdder fa0(a[0], b_in[0], carry[0], result[0], carry[1]);
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  FullAdder fa1(a[
1], b_in[1], carry[1], result[1], carry[2]);
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  FullAdder fa2(a[
2], b_in[2], carry[2], result[2], carry[3]);
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  FullAdder fa3(a[
3], b_in[3], carry[3], result[3], carry[4]);
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  FullAdder fa4(a[
4], b_in[4], carry[4], result[4], carry[5]);
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  FullAdder fa5(a[
5], b_in[5], carry[5], result[5], carry[6]);
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  FullAdder fa6(a[
6], b_in[6], carry[6], result[6], carry[7]);
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  FullAdder fa7(a[
7], b_in[7], carry[7], result[7], cout);
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)endmodule
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)


对应在C++中先写FullAdder class,然后在ALU class中以FullAdder作为data member。

;


另外一点,moudle声明port的方式,像是从早期C语言的函数定义中学来的:

(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)char* strcpy(dst, src)
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)    
char* dst;
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)    
char* src; 
}


2. Verilog中的模块调用时,指定端口可以使用名称绑定。C++在调用函数时,参数只能按顺序书写。例如memset()的原型是:

(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)void *memset(void *s, int c, size_t n);


如果你想将某个buf清零,应该这么写:

(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)char buf[256];
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)memset(buf, 
0sizeof(buf));


但是如果你不小心写成了:

(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)memset(buf, sizeof(buf), 0);


编译器不会报错,但运行的实际效果是根本没有对buf清零。(记得Richard Stevens的书里提到过这一点。)

在Verilog中,如果要写一个测试ALU的module,那么其中对ALU实例化的指令可以这么写:

(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)module alu_test;
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  reg[
8:0] a_in, b_in;
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  reg     op_in;
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  wire[
7:0] result_out;
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  wire      carry_out;
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  ALU alu0(.a(a_in[
7:0]), .b(b_in[7:0]), .is_add(op_in), .result(result_out), .cout(carry_out));
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  
// (轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)

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


这样就比较容易检查接线错误。

另外,在C++中,如果所有参数类型不同,而且之间没有隐式类型转换,那么可以利用C++的强类型机制在编译期检查出这种调用错误。

3. Verilog中把大括弧{}用作bit的并置,因此语句块要用begin/end标示。Verilog中小括号()和中括号[]的作用与C++中类似,前者用于函数或模块调用,后者用于下标索引。我想如果Verilog把尖括号<>用作bit并置的话,就能把大括号{}解放出来,用作标示语句块,这样写起来更舒服一些。

4. Verilog本质上是测试驱动开发的。对于每个module都应该有对应的test bench(或称test fixture)。比较好的情况是,一个工程师写module,另一个工程师写对应的test bench,这样很容易检查出对电路功能需求理解不一致的地方。因此还可以说Verilog主张结对编程(pair programming)。例如对前面的ALU module的test bench可以写成:

(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)`timescale 1ns / 1ns
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)module alu_test;
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  reg[
8:0] a_in, b_in;
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  reg     op_in;
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  wire[
7:0] result_out;
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  wire      carry_out;
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  ALU alu0(.a(a_in[
7:0]), .b(b_in[7:0]), .is_add(op_in),  .result(result_out), .cout(carry_out));
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  reg[
9:0get, expected;
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  reg     has_error;
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  initial begin
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)    has_error 
= 1'b0;
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)
    op_in = 1'b1; // test addition
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)

(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)       
for (a_in = 9'b0; a_in != 256; a_in = a_in + 1)
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)
           for (b_in = 9'b0; b_in != 256; b_in = b_in + 1) begin
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)
               #1;
endmodule


在C++中,既可以写concrete class,也可以写abstract class。比Verilog和VHDL都方便。

5. Verilog比起VHDL的不足之处在于,它只能定义concrete class,不能定义abstract class。也就是说interface和implementation不能分离。这在设计大型电路时就显得表现力不足。不过这关系不大,因为可以在编译时选择同一模块的不同实现版本,间接实现了接口与实现的分离。

在VHDL中,强制将接口与实现分离。对每个模块,你都得先写接口(定义输入输出信号),即ENTITY;然后至少写一份实现,即ARCHITECTURE。每个ENTITY可以有不止一份实现,例如可以有行为描述的,也有数据流描述的。然后在配置文件中选择该ENTITY到底用哪一份实现。举例来说(选自《VHDL入门·解惑·经典实例·经验总结》一书),分频器模块可以这么写,先定义其接口FreqDevider,然后定义两份实现Behavior和Dataflow:

(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)LIBRARY IEEE;
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)USE IEEE.Std_Logic_1164.All;
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)ENTITY FreqDevider IS
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  PORT
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  ( Clock  : IN  Std_Logic;
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)    Clkout : OUT Std_Logic
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  );
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)END;
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)ARCHITECTURE Behavior OF FreqDevider IS
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  SIGNAL Clk : Std_Logic;
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)BEGIN
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  PROCESS (Clock)
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  BEGIN
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)    IF rising_edge(Clock) THEN
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)      Clk 
<= NOT Clk;
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)    END IF;
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  END PROCESS;
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)  Clkout 
<= Clk;
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)END;
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)ARCHITECTURE Dataflow OF FreqDevider IS
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)
-- signal declarations
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)BEGIN
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)
-- processes
(轉貼) Verilog与C++的类比 (IC Design) (Verilog) (C/C++)END;


6. Verilog和VHDL都有模板的概念,Verilog称为参数(parameter),VHDL称为类属(generic)。不过好像都只能用整数作为模板参数,不能像C++那样用类型作为模板参数。

7. 目前来看,Verilog是硬件描述语言,不是硬件设计语言。在用Verilog设计电路的时候,我们是把脑子中想好的电路用Verilog“描述”出来:哪里是寄存器、哪里是组合逻辑、数据通路是怎样、流水线如何运作等等都要在脑子里有清晰的映象。然后用RTL代码写出来,经过综合器综合出的电路与大脑中的设想相比八九不离十。这就像说C语言是可移植的汇编语言,以前好的C程序员在写代码的时候,能够知道每条语句背后对应的汇编代码是什么。

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

相关文章: