ModelSIM的简单使用方法
https://blog.csdn.net/qq_53156932/article/details/117157324
作业一:
例4.8
下面列出的Add. full _unit_ delay 和Add_ half. unit_ delay 中的基本门描述中,均标记有一个时间单位延时。延时标记#1插入到每个例化基本门的例化名之前(#表示延迟控制操作符)。从图4.18可以看出,sum和c_out 的仿真过程中延迟的影响是很明显的。而且应该注意到图4. 17所示零延时的仿真结果无法表明c_ out 是在sum之前还是在sum之后形成的。实际上,只要输入变化,二者就会跟着发生变化。
ASIC是通过将标准单元库中的逻辑单元刻蚀在通用硅片晶圆上制造而成的。库单元都是预先设计好的,并且能满足一定的功能要求;而库单元的Verilog模型包含精确的定时信息,使得综合工具能够利用这些信息对设计的性能(速度)进行优化。本书的中心思想是通过工艺独立的行为级电路模块①,并利用标准单元或是现场可编程门阵列(FPGA)来综合门级结构。后者的定时特性分析已被嵌入到FPGA综合工具中;而前者的时间特性也已嵌入到单元模型中,并且通过综合工具把分析电路的定时关系与选择单元库中的部件结合起来,实现某一特定逻辑。电路设计者不要试图用手工方法来创建一个电路的精确门级定时模型,而应该借助综合工具来实现能满足定时约束的设计。
①工艺独立行为模型仅仅描述电路的功能,而不描述传输延时。
module Add_full_unit_delay (output c_out,sum,input a, b,c_in);
wire w1, w2, w3;
Add_half_unit_delay M1(w2,w1,a,b);
Add_half_unit_delay M2(w3,sum,w1,c_in);
or #1 M3(c_out,w2,w3);
endmodule
module Add_half_unit_delay (output c_out,sum,input a,b);
xor #1 M1(sum,a,b);
and #1 M2(c_out,a,b);
endmodule
实验过程视频
例4.8视频
作业二:
实验四
本实验完成一个算术逻辑单元的函数建模和任务建模,该算术逻辑单元所执行的操作参考表11-5,控制信号3位可以执行8种操作。
select 信号 | 函数的输出 |
3 'b000 | a+b |
3 'b001 | a-b |
3 'b010 | a |
3 'b011 | a以补码形式输出 |
3 'b100 | a左移1位 |
3 'b101 | a右移1位 |
3 'b110 | 计算输出a除b的余数 |
3 'b111 | 输出a和b中较大的数 |
先采用函数的方式来完成设计,定义送入计算的a和b数据是4位值,计算的结果也保留4位值,按照如下的方式来声明此函数形式。
function_____my_ ALU;
//实验内容一:按照表11-4完成此函数
//如果有必要,在上方横线位置填写正确的语句
endfunction
若要使用任务来完成这个算术逻辑单元,需使用如下代码:
task______myALU;
//实验内容二:参考函数实现的代码,修改为任务所需代码
//如果上方横线处需要填写语句,请补全
endtask
完成了上述两个代码,可以编写测试平台代码如下:
module s4;
reg [3:0] a,b;
reg [2:0] select;
reg [3:0] result_f, result_t;
integer seed1,seed2;
initial
begin
select=0;
seed1=40;
seed2=9;
end
always
begin
a={$random (seed1)/16};
b={$random (seed2)/16};
#20 select=select+1;
end
//实验内容三:请在此位置添加两行语句,分别调用已定义的任务和函数
//要求在每次a、b、select信号改变时都能运行任务和函数并得到结果
//尽量不要使用本模块中未定义的变量
endmodule
根据给出的功能表,结合函数的基本语法,可以得到如下参考代码,该函数的返回值是4位的,所以在函数声明时一定要声明为[3:0]形式。由于默认的数据类型就是reg型,所以不需要再显示定义为reg型返回值。
function reg [3:0] my_ALU;
input [3:0] a,b;
input [2:0] select;
begin
case(select)
3'b000: my_ALU=a+b;
3'b001: my_ALU=a-b;
3'b010: my_ALU=a;
3'b011: begin
my_ALU={a[3],{~a[2:0]+1}};
end
3'b100: my_ALU=a<<1;
3'b101: my_ALU=a>>1;
3'b110: my_ALU=a%b;
3'b111: begin
if(a>b)
my_ALU=a;
else
my_ALU=b;
end
default: my_ALU=0;
endcase
end
endfunction
case语句和if语句是可以嵌套使用的,虽然一些简单的仿真器对这种语法支持不够,但绝大多数正常版本的仿真器都可以支持此类语法,在case语句中使用if来判断状态的变化情况也是状态机写法中的标准形式。
用任务来完成该功能的参考代码如下:
task myALU;
input [3:0] a,b;
input [2:0] select;
output [3:0]result;
begin
case (select)
3'b000: result=a+b;
3'b001: result=a-b;
3'b010: result=a;
3'b011: begin
result={a[3],{~a[2:0]+1}};
end
3'b100: result=a<<1;
3'b101: result=a>>1;
3'b110: result=a%b;
3'b111: begin
if (a>b)
result=a;
else
result=b;
end
default: result=0;
endcase
end
endtask
该任务代码部分与函数的功能部分基本相同,只是在定义和输入/输出信号的声明上略有区别。完成了上述两个代码,补全测试平台,参考代码如下,注意函数在调用的时候一-定要有一个赋值等式,同时不需要输出信号部分;任务在调用时不能使用赋值等式,只是直接写出任务名并排列好任务所需的输入和输出信号即可。
always @ (a,b, select)
begin
result_f=my_ALU(a,b, select) ;
myALU(a,b, select, result_t) ;
end
实验过程视频
实验四
作业三:
教材93页
通过Verilog代码描述1位BCD加法器。输入X、Y和输出S定义为4位数。中间和值Z定义为5位数,if-else 语句提供了上面所述的判断,因此没有必要采用一个明确定义的Adjust信号。
module bcdaddd(Cin,X,Y,S,Cout);
input Cin;
input [3:0] X,Y;
output reg [3:0]S;
output reg Cout;
reg [4:0]Z;
always @(X,Y,Cin)
begin
Z=X+Y+Cin;
if(Z<10)
{Cout,S}=Z;
else
{Cout,S}=Z+6;
end
endmodule
实验过程视频
教材93页