LC3取指模块的定向测试

LC3取指模块的定向测试

这篇文章将对LC3微处理器中的一个模块进行定向测试。
Little Computer 3 是一种教学用的汇编语言。

LC3设计包括6个模块:

  1. fetch 取指
  2. execute 执行
  3. writeback 回写
  4. memAccess 访存
  5. decode 解码
  6. controller 控制器

LC3微控制器取值模块如图:在这里插入图片描述

fetch模块计算从内存中取数的地址:

  1. clock,reset:1位;
  2. br_taken:1位。通知fetch块遇到控制信号,所有npc的值需要从pc+1改变为由指令计算出的地址值taddr(目标地址)。
  3. taddr:16位。为分支或者跳转指令计算得到的目标地址。
  4. state:4位。controller块当前状态。

fetch块有如下输出:

  1. rd:1位。通知内存执行读操作。
  2. pc:16位。程序计数器寄存器的当前值。
  3. npc:16位。值始终为PC+1。

在clock的上升沿,当br_taken为真时,taddr送入PC_reg;当br_taken为假时,PC_reg送入npc;PC_reg复位时为16’h3000。所有信号都在同一个周期内更新。

取值模块的Verilog代码

module fetch(clock,reset,state,pc,npc,rd,
			 taddr,br_taken);
	input clock,reset,br_taken;
	input[15:0] taddr;
	input[3:0] state;
	output[15:0] pc,npc;
	output rd;
	...
endmodule 

取值模块的接口

interface fetch_ifc(input bit clock);
	logic reset,br_taken,rd;
	logic[15:0] taddr;
	cntrl_e state;
	logic[15:0] pc,npc;

	clocking cb @(postedge clock);
		input pc,npc,rd;
		output taddr,state,br_taken,reset;
	endclocking

	modport TEST(clocking cb,output reset);

	modport DUT(input clock,reset,br_taken,taddr,state,
				output pc,npc,rd);

	clocking cbm @(postedge clock);		//用于监控DUT信号
		input pc,npc,rd,taddr,state,br_taken;
	endcloking

	modport MONITOR(clocking cbm);
endinterface

取值模块的定向测试

program automatic test(fetch_ifc.TEST if_t,
					   fetch_ifc.MONITOR if_m);
	initial begin
		cntrl_e cntrl;

		$timeformat(-9,0,"ns",5);
		$monitor("%t:pc=%h npc=%h rd=%h state=%h",
				$realtime,if_m.cbm.pc,if_m.cb.npc,
				if_m.cbm.rd,if_m.cbm.state.name);

		$display("%t: Reset all signals", $realtime);
		if_t.reset <= 1;
		if_t.cb.taddr <= 16'hFFFC;
		if_t.cb.br_taken <= 0;
		if_t.cb.state<= CNTRL_UPDATE_PC;

		repeat(2) @(if_t.cb);
		pc_post_reset: assert (if_t.cb.pc == 16'h3000);

		# # 1 if_t.cb.reset <= 0;		//同步地释放复位信号.
										// #表示的时间的单位的延时,以你`timescale指定的为最小单位。
										//##是systemverilog assertion里面的语法,表示的是时钟周期的延时,他的最小单位为一个clock周期。
		@(if_t.cb);
		$display("\n%t: Test loading of target address", $realtime);
		if_t.cb.state <= CNTRL_UPDATE_PC;
		if_t.cb.br_taken <= 1;

		@(if_t.cb);
		@(if_t.cb);
		pc_br_taken : assert (if_t.cb.pc == 16'hFFFC);

		$display("%t: Did the PC rollover as expected?", $realtime);
		if_t.cb.br_taken <= 0;
		if_t.cb.state<= CNTRL_UPDATE_PC;
		repeat(5) @(if_t.cb);
		pc_rollover: assert (if_t.cb.pc == 16'h0000);

		$display("\n%t: Step through all the controller states", $realtime);
		for(int i = CNTRL_FETCH; i <= CNTRL_COMPUTE_MEM; i++)
			begin
				$cast(cntrl,i);
				if(cntrl == CNTRL_UPDATE_PC)
					continue;
				$display("%t: Try with controller state=%0d %s",$realtime,cntrl,cntrl.name);
				if_t.cb.br_taken <= 0;
				if_t.cb.state<= cntrl;
				repeat(2) @(if_t.cb);
				pc_no_load: assert (if_t.cb.pc == 16'h0001);
			end
		
		$display("\n%t: Tristate on PC output", $realtime);
		if_t.cb.state <= CNTRL_READ_MEM;
		@(if_t.cb);
		pc_z_read_mem: assert(if_t.cb.pc === 16'hzzzz);

		if_t.cb.state <= CNTRL_IND_ADDR_RD;
		@(if_t.cb);
		pc_z_ind_addr_rd: assert(if_t.cb.pc === 16'hzzzz);

		if_t.cb.state <= CNTRL_WRITE_MEM;
		@(if_t.cb);
		pc_z_write_mem: assert(if_t.cb.pc === 16'hzzzz);
	end
endprogram

取指测试平台的顶层模块

//顶层模块例化了取指接口、fetch模块和test。
//也定义了控制器状态枚举类型,这样在test和接口中都可以使用。

'timescale 1ns/1ns
typedef enum{CNTRL_UPDATE_PC=0,
			 CNTRL_FETCH=1,
			 CNTRL_DECODE=2,
			 CNTRL_EXECUTE=3,
			 CNTRL_UPDATE_REGF=4,
			 CNTRL_COMPUTE_PC=5,
			 CNTRL_COMPUTE_MEM=6,
			 CNTRL_READ_MEM=7,
			 CNTRL_IND_ADDR_RD=8,
			 CNTRL_WRITE_MEM=9,
} cntrl_e;

module top;
	bit clock;
	always # 10 clock = ~clock;
	
	fetch_ifc fif(clock);
	test t1(fif,fif);
	fetch f1(clock, fif.reset, fif.state, fif.pc, fif.npc, fif.rd, fif.taddr, fif.br_taken);
endmodule

结论

通过SV的接口来组织各个设计模块和测试平台间的通信,简化了测试平台的代码量,一个接口可以取代很多的信号连接。SV中也引入了程序块来减少待测模块和测试平台之间的竞争状态,在接口中使用时钟块,测试平台可以相对于时钟正确地驱动和采样设计信号。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值