.reset(reset), .regWriteData(regWriteData), .regWriteAddr(regWriteAddr), .regWriteEn(regWriteEn), .RsData(RsData), .RtData(RtData), .RsAddr(RsAddr), .RtAddr(RtAddr) ); integer i; initial begin // Initialize Inputs clk = 0; reset = 0; regWriteData = 0; regWriteAddr = 0; regWriteEn = 0; RsAddr = 0; RtAddr = 0; // Wait 100 ns for global reset to finish #100; // Add stimulus here regWriteData=32'h55aaaa55; regWriteEn=1; reset=1; #100; reset=0; end
parameter PERIOD = 20; always begin clk = 1'b0; #(PERIOD/2) clk = 1'b1; #(PERIOD/2); end always begin for(i = 31; i>= 1; i=i-1) begin regWriteAddr = i; RsAddr=i; #PERIOD; end end endmodule
仿真结果如下:
下图可以观察到Reset为高电平状态。Reset高电平状态下输出数据为0,表示Reset有效地工作了。Reset信号无效后,正常输入和输出数据。
第一次for循环的地址范围输出数据在时钟低电平时输出0,高电平输出0x55aaaa55,如下图所示,表明数据正确地在时钟上升沿写入的。之后一直输出的数据与写入的数据相同,表明数据都正确地保存在寄存器组中。
2. 控制器仿真:
控制器仿真需要包含所有case的输入,仿真激励文件修改代码后,如下:
module ctrsim; // Inputs reg [5:0] opCode;
// Outputs wire regDst; wire aluSrc; wire memToReg; wire regWrite; wire memRead; wire memWrite; wire branch; wire [1:0] aluop; wire jmp; // Instantiate the Unit Under Test (UUT) ctr uut ( .opCode(opCode), .regDst(regDst), .aluSrc(aluSrc), .memToReg(memToReg), .regWrite(regWrite), .memRead(memRead), .memWrite(memWrite), .branch(branch), .aluop(aluop), .jmp(jmp) ); initial begin // Initialize Inputs opCode = 0; // Wait 100 ns for global reset to finish #100; opCode=6'b000010;//jump #100; opCode=6'b000000;//R #100; opCode=6'b100011;//lw #100; opCode=6'b101011;//sw #100; opCode=6'b000100; end endmodule
所有case下的仿真波形如图所示,将该波形图与之前的表格对吧发现功能正确。
3. 顶层仿真:
激励代码如下: module topsim;
// Inputs reg clkin; reg reset; // Instantiate the Unit Under Test (UUT) top uut ( .clkin(clkin), .reset(reset) ); initial begin // Initialize Inputs clkin = 0; reset = 0; // Add stimulus here #100; reset = 1; #100; reset = 0; end
parameter PERIOD = 20; always begin clkin = 1'b0; #(PERIOD/2) clkin = 1'b1; #(PERIOD/2); End
endmodule
Top模块仿真波形如下:
首先查看指令执行顺序是否正确,验证跳转指令。 从上图可以看到指令存储器地址a[9:0]从0到8循环,表明指令从第0条顺序执行到第8条之后跳转到第0条信号执行。这是由于在指令存储器中存入了如下代码: main: add $4,$2,$3 #0号指令 lw $4,4($2) #1号指令 sw $2,8($2) #2号指令 sub $2,$4,$3#3号指令 or $2,$4,$3#4号指令 and $2,$4,$3#5号指令 slt $2,$4,$3#6号指令 beq $4,$3,exit #7号指令 j main #8号指令 exit:lw $2,0($3) #9号指令 j main #10号指令 并且将数据存储器的内存空间初始化为0x55555555了。由于1号指令将$4从内存中读出数据为0x55555555,而$3一直为0,执行到7号指令时不相等,从而顺序执行8号j指令的结果。 然后在查看各条指令执行结果,1、3、4、5、6号指令都将修改寄存器的值,因此可以查看寄存器模块的regWriteData为0x55555555,regWriteAddr为04,且RegWriteEnd为1,表示将对4号寄存器写入数据0x55555555,这正是我们想要的结果。