verilog 学习:简单的adder + tb 搭建与错误记录

拙劣的记录自己拙劣的学习过程。

1. 最开始的一版代码

`timescale 1ns/10ps                                                                                                                                                                                                                                       
  2           
  3 module tb();
  4           
  5   reg clk;
  6   reg rstn;
  7           
  8   wire [1:0]a,b;
  9   reg [2:0]sum;
 10           
 11   assign a = 1;
 12   assign b = 0;
 13           
 14   adder myadder(
 15       .a(a),
 16       .b(b),
 17       .sum(sum)
 18   );      
 19           
 20   initial begin
 21     clk = 0;
 22     rstn = 0;
 23           
 24     a = 0;
 25     b = 0;
 26     sum = 0;
 27           
 28     #200; 
 29     rstn = 1;
 30   end     
 31           
 32   wait(!rstn);
 33   forever #50 clk = ~clk;
 34           
 35   always@(posedge clk or negedge rstn)begin
 36     if(!rstn)begin
 37       a = 1'b0;
 38       b = 1'b0;
 39     end   
 40     else sum = a + b;
 41   end     
 42           
 43           
 44   #2000 $finish;
 45           
 46 endmodule 
 47           
 48 //adder design
 49 module adder(a,b,sum);
       
 51   input a, b;
 52   output sum;
 53         
 54   wire [1:0] a;
 55   wire [1:0] b;
 56   wire [2:0] sum;
 57         
 58 assign sum = a + b;
 59         
 60 endmodule

写的相当糟糕,问题也很多,逐个来看:

问题1 adder模块的端口及信号定义

上面的写法module adder(a,b,sum);这里已经定义了a,b,sum为单bit wire类型的数据,但是方向没有定义。
接下来定义了信号的方向,但是在line 54-56重新定义了信号的位宽,这里就可能出现问题。
有效的写法是在模块端口声明时就定义好位宽和方向。

module adder(
  input [1:0] a,
  input [1:0] b,
  output [2:0] sum
);
  assign sum = a + b;
endmodule 

问题2 tb中信号定义混乱

对于a、b、sum信号的混乱定义与使用,会导致很多问题。
a、b、sum在adder模块中都被定义为wire类型,因为 他们是端口信号,在实际的功能中表示输入与输出,代表与外部的连接关系,不储存数据,所以定义为wire是合适的。
而在tb中,定义的a、b、sum则是与adder模块连接的信号,对于输入,需要在不同的情况下赋予不同的值,需要被定义为reg,而输出则是用来观察,可被定义为wire。

问题3 wire、reg信号的赋值

sum作为wire信号,只能通过assign赋值,不能在initial、always中赋值。
a、b不能通过assign赋值。因此在上面代码不仅对于信号的赋值方式使用错误,而且在对于a、b使用了两种赋值方式,感觉自己很离谱了哈哈。

问题4 时钟配置、仿真停相关语句的不规范

应包括在initial块儿内,不然仿真软件如何知道什么时候执行这条语句呢。其次对于initial语句的理解有偏差,人是执行一次,不是执行一下。

问题5 其他的问题

a、b、sum设置的位宽太小,以及一些格式错误

2. 修改后的代码如下:

`timescale 1ns/10ps                                                                                                                                                                                                                                       
  2                   
  3 module tb();      
  4                   
  5   reg clk;        
  6   reg rstn;       
  7                   
  8   reg  [4:0] a,b; 
  9   wire [5:0] sum; 
 10                   
 11  // assign sum = a + b;
 12                   
 13   adder myadder(  
 14       .a(a),      
 15       .b(b),      
 16       .sum(sum)   
 17   );              
 18                   
 19   initial begin   
 20     clk  = 1'b0;  
 21     rstn = 1'b0;  
 22     a    = 5'b00000;
 23     b    = 5'b00000;
 24                   
 25     #200 rstn = 1;
 26                   
 27     wait(rstn);   
 28                   
 29     fork          
 30       forever #50 clk = ~clk;
 31       #2000 $finish;
 32     join          
 33   end             
 34                   
 35                   
 36   always@(posedge clk or negedge rstn)begin
 37     if(!rstn)begin
 38       a <= 5'b00000;
 39       b <= 5'b00000;
 40     end           
 41     else begin    
 42       a <= a + 1'b1;
 43       b <= b + 1'b1;
 44     end           
 45   end             
 46                   
 47 endmodule         
//adder design   
 50 module adder(    
 51         
 52   input  [4:0] a;
 53   input  [4:0] b;
 54   output [5:0] sum
 55 );                                                                                                                                                                                                                                    
 56         
 57 assign sum = a + b;
 58         
 59 endmodule

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值