UVM Primer ch1 Introduction

        将通过验证一个简单的设计:TinyALU来检查UVM。这样做,可以将精力集中在测试台上,而不会因DUT的复杂性而分心。

      

        上图为TinyALU的框图,ALU在时钟的上升沿工作。当start为1时,TinyALU从A和B总线上读取操作数,从op总线上读取一个操作数,并基于该操作数的结果进行运算。操作可能需要任意数量的周期。

当操作完成时,输出done为1。reset_n信号是有效的低电平同步复位。

TinyALU有五种操作:NOP、ADD、AND、XOR和MULT。用户在请求计算时对三位运算总线上的操作进行编码,其中NOP为空指令。以下是编码:

 以下是TinyALU的波形:

 start信号必须保持高电平,运算符和操作数必须保持稳定,直到TinyALU产生完成信号。done信号仅在一个时钟内保持高电平。NOP操作上没有done信号。在NOP上,升高start信号一个周期后降低。

我们将通过创建TinyALU的常规测试台来开始我们的UVM之旅。然后,每一章都将修改测试台,使其符合UVM。

TinyAlu的rtl代码分为三个部分:tinyalu、single_cycle、three_cycle。

module tinyalu (input [7:0] A,//输入A
		input [7:0] B,//输入B
		input [2:0] op,//opcode对应不同的operation
		input clk,//时钟
		input reset_n,//复位
		input start,//start信号
		output done,//done信号
		output [15:0] result//输出结果);

   wire [15:0] 	result_aax, result_mult;//对应后面single_cycle和three_cycle的输出结果
   wire 		start_single, start_mult;//对应后面single_cycle和three_cycle的start信号

   assign start_single = start & ~op[2];
//single_cycle的start需要总start和op[2]对应的位为0,因为single_cycle对应op的第3位均为0
   assign start_mult   = start & op[2];
//three_cycle的start需要总start和op[2]对应的位为1,因为single_cycle对应op的第3位均为1

   single_cycle and_add_xor (.A, .B, .op, .clk, .reset_n, .start(start_single),
			     .done(done_aax), .result(result_aax));
//模块例化,例化single_cycle的module

   three_cycle mult (.A, .B, .op, .clk, .reset_n, .start(start_mult),
		    .done(done_mult), .result(result_mult));
//模块例化,例化three_cycle的module

   assign done = (op[2]) ? done_mult : done_aax;
//done信号赋值,op最高位为1时,done输出done_mult,op最高位为0时,done输出done_aax,两个信号分别对应three_cycle和single_cycle的done信号

   assign result = (op[2]) ? result_mult :  result_aax;
//原理同done信号

endmodule // tinyalu
module single_cycle(input [7:0] A,
		   input [7:0] B,
		   input [2:0] op,
		   input clk,
		   input reset_n,
		   input start,
		   output logic done,
		   output logic [15:0] result);

  always @(posedge clk)
    if (!reset_n) //复位
      result <= 0;
    else
      case(op) //用case分支语句完成operation的操作
		3'b001 : result <= A + B;    //add
		3'b010 : result <= A & B;    //and
		3'b011 : result <= A ^ B;    //xor
      endcase // case (op)

   always @(posedge clk)
     if (!reset_n)
       done <= 0;    //done信号复位
     else
       done =  ((start == 1'b1) && (op != 3'b000));    
//start信号为1并且operation不是NOP时,done信号输出为高

endmodule : single_cycle
module three_cycle(input [7:0] A,
		   input [7:0] B,
		   input [2:0] op,
		   input clk,
		   input reset_n,
		   input start,
		   output logic done,
		   output logic [15:0] result);

   logic [7:0] 			       a_int, b_int;
   logic [15:0] 		       mult1, mult2;
   logic 			       done1, done2, done3;

   always @(posedge clk)
     if (!reset_n) begin    //复位
	done  <= 0;
	done3 <= 0;
	done2 <= 0;
	done1 <= 0;
	a_int <= 0;
	b_int <= 0;
	mult1 <= 0;
	mult2 <= 0;
	result<= 0;
     end else begin // if (!reset_n)
	a_int  <= A;    //输入
	b_int  <= B;    //输入
	mult1  <= a_int * b_int;    //multiply
	mult2  <= mult1;            //流水线传输 相当于DFF
	result <= mult2;            //流水线传输 相当于DFF
	done3  <= start & !done;    //start信号为1并且done信号为0时done3为1
	done2  <= done3 & !done;    //此处的done3信号相当于start
	done1  <= done2 & !done;
	done   <= done1 & !done;
     end // else: !if(!reset_n)
endmodule : three_cycle

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值