大家好,又见面了,我是你们的朋友全栈君。
对于初学者,可大致了解Verolog HDL所提供的能力,掌握Verilog HDL语言的核心子集。
1 Verilog HDL语言具有:设计的行为特性、设计的数据流特性、设计的结构组成以及包括响应监控和设计验证方面的时延和波形产生机制。
2 如何描述自顶向下的设计思想:每个模块实现特定的功能,模块间可进行层次的嵌套,因此可以将大型的数字电路设计分割成大小不一的小模块来实现特定的功能,最后通过由顶层模块调用子模块来实现整体功能。
3 三种建模方式
3.1 结构化描述方式
结构化建模方式就是通过对电路结构的描述来建模,即通过对器件的调用并使用线网来连接各器件的描述方式。这里的器件包括Verilog HDL的内置门,也可以是用户的一个设计。
3.2 数据流描述方式
数据流的建模方式就是通过对数据流在设计中的具体行为的描述来建模。最基本的机制是用连续赋值语句。还需要借助用于HDL提供的一些运算符,如按位逻辑运算符。
3.3 行为描述方式
行为方式的建模是指采用对信号行为级的描述方式进行建模,在表示方面,类似数据流的建模方式,但一般把initial模块或always块语句描述的归为行为建模方式。行为建模方式通常借助一些行为级的运算符如+-等。
3 总结
在实际设计中,往往是多种设计模型的混合。一般对于顶层设计,采用结构描述方式(功能器件网表方式连接)对低层模块进行例化;对低层模块,可采用数据流(assign)、行为级(initial, always)或者二者的结合。
4 Verilog数据类型
Verilog语言主要包含两种数据类型:线网类型和寄存器类型。
4.1 线网类型
wire和tri定义
线网类型主要有wire和tri两种。
tri用于定义三态线网。
wire型用于对结构化器件之间的物理连线的建模。如器件管脚,内部器件如与门的输出等。
线网型代表物理连线,不存储逻辑值,必须由器件驱动。通常由assign进行赋值,如assign A=B^C。
当wire型信号没有被驱动时,缺省值为Z高阻态。信号没有定义数据类型时,缺省为wire型。
4.2 寄存器类型
reg用于对存储单元的描述,如D型触发器,ROM等。存储器类型的信号在某种触发机制下分配了一个值,在分配下一个值时保留原值,但reg型变量不一定是存储单元,如always语句中进行描述的必须用reg类型的变量。
附上一些简单的入门级代码以供参考
//3.1 全加器
module adder4(count, sum, ina, inb, cin);
output[3:0]sum;
output count;
input [3:0] ina, inb;
input cin;
assign {count, sum}=ina+inb+cin;
endmodule
//4位计数器
module count4(out, reset, clk);
output [3:0] out;
input reset, clk;
reg[3:0]out;
always@(posedge clk)
begin
if(reset)out<=0;
else out<=out+1;
end
endmodule
//4位全加器的仿真程序
module adder_tp;
reg[3:0]a,b; //测试输入信号定义为reg型
reg cin;
wire[3:0]sum; //测试输出信号定义为wire型
wire cout;
integer i,j;
adder4 adder(sum, cout, a, b, cin); //调用测试对象
always#5 cin=~cin;
initial
begin
a=0; b=0; cin=0;
for(i=1;i<16;i=i+1)
#10 a=i;
end
3.1.1.1 加法器
module addr(a,b,count,sum);
input[2:0]a;
input[2:0]b;
input cin;
output count;
output [2:0]sum;
assign {count, sum}=a+b+cin;
endmodule
//3.1.1.2 比较器
module compare(equal, a, b);
input[1:0]a,b; //declare the input signal;
output equare;
assign equare=(a==b)?1:0;
//if a=b, output 1, otherwise 0;
endmodule
/*三态缓冲器(驱动器,门),输入缓冲器用于将外设送来的数据暂时存放,以便处理器
将其取走;输出缓冲器的作用是用来暂时存放处理器送往外设的数据。
数控缓冲器的作用就是使高速工作的CPU与慢速工作的外设起协调和缓冲作用,实现数据传送的同步。
由于缓冲器用在总线上所以要有三态输出功能。*/
/*三态电路有三种不同的输出值,分别是逻辑0,1和高阻态,高阻态用来将逻辑门同系统的
其他部分加以隔离。*/
//3.1.1.3 三态驱动器
//定义mytri模块
module mytri(din, d_en, d_out);
input din;
input d_en;
output d_out;
assign d_out = d_en ? din:’bz;
endmodule
//调用mytri模块
module trist(din, d_en, d_out);
input din;
input d_en;
output d_out;
mytri u_mytri(din, d_en, d_out); //实例化mytri模块
endmodule
3.3.2.1 数据流描述方式
module FA_flow(A,B,Cin,Sum,Count)
input A,B,Cin;
output Sum, Count;
wire S1,T1,T2,T3;
//各个assign语句是并行执行的,即各语句的执行与语句之间的顺序无关。
//下面的代码说明,在数据流描述方式中,除连续赋值语句之外还需要借助HDL提供的一些逻辑运算符来实现。
assign #2 S1=A^B;
assign #2 Sum=S1^Cin;
assign #2 T3=A&B;
assign #2 T1=A&Cin;
assign #2 T2=B&Cin;
endmodule
3.3.3 行为建模方式
//3.3.3.1 一位全加器的行为建模
module FA_behav1(A,B,Cin,Sum,Cout);
input A,B,Cin;
output Sum, Cout;
reg Sum, Cout;
reg T1,T2,T3;
always@(A or B or Cin)
begin
Sum(A^B)^Cin; //相异为1相同为0
T1=A&Cin;
T2=B&Cin;
T3=A&B;
Cout=(T1|T2)|T3;
end
endmodule
//1只有寄存器类型的信号才可以在always和initial语句中进行赋值,类型定义通过reg语句
实现;
2 always语句是一直重复执行,由敏感表中的变量触发;
3 always语句从0时刻开始;
4 在begin和end之间的语句是顺序执行,输出串行语句。
3.3.3.2一位全加器的行为建模
module FA_behav2(A,B,Cin,Sum,Cout);
input A,B,Cin;
output Sum, Cout;
reg Sum, Cout;
always@(A or B or Cin)
begin
{Count, Sum}=A+B+Cin;
//{Count, Sum}表示对位数的扩展,两个1bit相加,和有2位,低位放在Sum变量中,进位放在Count中;
//相当于位数的拼接,从左到右由高到低
end
endmodule
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/129242.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...