数字系统设计与Verilog HDL复习笔记1

第一章 EDA技术概述

数字器件经历了从SSI,MSI,LSI到VLSI,直到现在的SoC(System on Ship,芯片系统)。
SSI:小规模集成电路
MSI:中规模集成电路
LSI:大规模集成电路
VLSI:超大规模集成电路

PAL:可编程逻辑阵列
GAL:通用阵列逻辑
PCB:印制电路板
FPGA:现场可编程门阵列
CPLD:复杂可编程逻辑器件

CAD:电脑辅助设计
CAE:电脑辅助工程
EDA:电子设计自动化
RTL:寄存器传输级

HDL:硬件描述语言
ASIC:专用集成电路

SoPC:可编程芯片系统
DSP:数字信号处理

1.1 Top-down设计
Top-down设计,即自顶向下的设计。在顶层进行功能方框图的划分和结构设计,避免设计工作的浪费,减小工作量,提高一次成功率。
在设计过程中,需要进行多次仿真和验证,不断修改设计。
1.2 Botton-up设计
Botton-up设计,即自底向上的设计。调用基本单元,逐级向上组合,直到设计出满足需求的系统,效率低,易出错。

1.3 IP核分为硬核、固核和软核。
IP核:用于ASIC或FPGA中的预先设计号的电路功能模块。
软核:用于 Verilog HDL等硬件描述语言描述的功能模块,但是并不涉及用什么具体电路元件实现这些功能。
硬核:提供设计阶段最终产品。
固核:完成了综合的功能块。

1.4 数字设计流程
设计输入->综合->布局布线->仿真->编程配置
综合:将较高级抽象层次的设计描述自动转换成较低层次描述的过程。
硬件综合器和软件编译器的本质区别:硬件描述语言编写的程序代码生成电路网表结构;而软件编译器生成CPU指令/数据代码流。
1.5 布局布线:又称为适配
1.6 编程配置
通常将对基于EEPROM工艺的非易失结构CPLD器件下的下载称为编程,而将基于SRAM工艺结构的FPGA器件的下载称为配置。
1.7常用的EDA工具软件
1)集成的FPGA/CPLD开发工具
Intel(Altera):Max+Plus II,Quartus II, Quartus prime;
Xilinx:ISE,Vivado;
Lattice:ispLEVER,Classic,Diamond。
2)逻辑综合器
Synopsys:FPGA Express、FPGA Compiler 和FPGA Compiler II;
Synplicity:Synpify Pro/Synoplify;
Mentor:Leonardo Spectrum。
……(仿真工具、综合工具)

第二章 FPGA/CPLD器件

2.1PLD器件概述
2.1.1PLD器件分类
1)按集成度分类
简单PLD(SPLD)<—750—>高密度PLD(HDPLD)
简单的可编程逻辑器件(SPLD)

SPLD包括PROM,PLA,PAL,和GAL;
PROM:可编程只读存储器
PLA:可编程逻辑阵列
PAL:可编程阵列逻辑
GAL:通用可编程阵列逻辑

高密度可编程逻辑器件(HDPLD)
HDPLD包括CPLD,FPGA;

2)按编程特点分类

按编程次数来分:

一次编程器件(OTP)
可多次编程器件

OTP类器件的特点是:只允许器件编程一次,不能修改;而可多次编程器件则允许多次编程,适合在科研开发中使用。

按照不同的编程元件和编程工艺划分

采用熔丝(Fuse)_编程元件的器件。
采用反熔丝(Antifuse)编程元件的器件
采用紫外线擦除、电编程方式的器件
EEPROM型
闪速存储器(Flash)型
采用静态存储器(SRAM)的结构器件

前5类编程工艺结构的器件称为非易失类器件,最后一类为易失类器件。
3)按结构特点分类

基于乘法项结构的PLD器件
基于查找表结构的PLD器件

2.2低密度PLD的原理与结构
1)PROM
缺点利用率低,固定的与阵列,可编程(或阵列)的门阵列;
2)PLA
利用率高,节省芯片面积,缺点软件开发难度大,算法复杂。
可编程的与阵列,或阵列(可编程)
3)PAL
与阵列可变现,或阵列固定
4)GAL
2.3CPLD
CPLD是与或阵列结构。
2.4FPGA的原理与结构
FPGA是查找表结构

CPLD和FPGA的异同之处
CPLD是与或阵列结构(宏单元),是一种可编程逻辑器件,它可以在制造完成后由用户根据自己的需要定义其逻辑功能。
FPGA是查找表结构,解决了定制电路的不足,又克服原有可编程器件门电路有限的缺点。

2.5边界扫描测试技术
VLSI:超大规模集成电路
JTAG:联合测试行动小组
BST:边界扫描测试
2.6FPGA/CPLD的编程与配置
ISP:在系统可编程

第三章 Verilog设计初步

verilog模板:

module <顶层模块名>(<输入输出端口列表>);
input 输入端口列表;				//输入端口声明
ouput 输出端口列表;			//输出端口声明
/*定义数据,信号的类型,函数声明,用关键字定义*/
wire 信号名;
reg 信号名;
//逻辑功能定义
assign <结果信号名>=<表达式>;
//用always块描述逻辑功能
always @(<敏感信号表达式>)
begin 
//过程赋值
//if-else,case语句
end
endmodule

表决器函数:

module voter(pass,vote);
input [6:0]vote;
output pass;
reg[2:0] sum;integer i;reg pass;
always @(vote)
begin sum=0;
for(i=0;i<=6;i=i+1)
if(vote[i])sum=sum+1;
if(sum[2])pass=1;
else pass=0;
end
endmodule

用for语句实现两个8位乘法器

module  mult_for(a,b,outcome);
parameter size=8;
input [size-1:0] a,b;
output reg [2*size-1:0] outcome;
integer i;
always @(a or b)
	begin 
	outcome<=0;
		for(i=1;i<=2*size;i=i+1)
			outcome<=outcome+(a<<(i-1));
	end
endmodule

用repeat实现两个8位二进制数的乘法。

module mult_repeat 
							#(parameter size=8)
							(input [size-1:0] a,b,output reg [2*size-1:0] result);
		reg [2*size-1:0] temp_a;reg [size-1:0]temp_b;
		always @ (a or b)
			begin
				result =0;temp_a=a;temp_b=b;
				repeat(size)
				begin
					if (temp_b[1])
						result=result+temp_a;
						temp_a=temp_a<<1;
						temp_b=temp_b>>1;
				end
		end
endmodule

加法器:

module adder(cin,a,b,sum,cout);
input cin;
input [7:0] a,b;
output [7:0] sum;
ouput cout;
assign {cout,sum}=a+b+cin;
endmodule

一位加法器:

module add(a,b,cin,sum,cout);
input a,b,cin;
output sum,cout;
always @*
	begin
	{cout,sum}=a+b+cin;
	end
endmodule

always也能用于组合电路!

always过程语句通常带有触发条件,触发写在敏感信号表达式中,只有当触发条件满足时,其后的语句才能被执行。

谈到电路,就得谈谈reg和wire变量的区别了?
wire是常用的net型数据变量,net型数据相当于硬件电路中的各种物理连接,简单说wire相当于导线,常用语组合电路中。而reg型变量属于variable型变量,必须放在过程语句中,通过过程赋值语句赋值,常见于寄存器,时序电路中。

第四章语言要素

读懂程序就行了,要什么自行车

  1. 空白符,程序修饰,尽量漂亮
  2. 注释,不多说和C一样//和/* */
  3. 标识符,有点点不同,可以存在$,C中我没见过哎
  4. 关键字,你所见到的
  5. 运算符,数学中的,C中的

常量

·整数 +/-< size>’< base>< value>
·实数
·字符串

4.1
·二进制(b/B)
·八进制(o/O)
·十进制(d/D)
·十六进制(h/H)
例子:8‘b11000101,八位宽二进制
在进制和数值之间允许出现空格,但’和进制之间,和数值间不能出现空格。

4.2数值取值
·0:低电平、逻辑0或逻辑非
·1:高电平、逻辑1或“真”
·z/Z:高阻态
·x/X:未知态
4.3 参数 parameter

第五章Verilog语句语法

要什么语法,能用就行
case语句描述4选1数据选择器

module  mux4_1(out,in0,in1,in2,in3,sel);
input in0,in1,in2,in3;
input [1:0] sel;
ouput reg out;
always @ (in0 or in1 or in2 or in3 or sel)
	case(sel)
	2'b00:out=in0;
	2'b01:out=in1;
	2'b10:out=in2;
	2'b11:out=in3;
	default:out=2'bx;
	endcase
end
endmodule

BCD码-7段码管译码器

module decode7(D,a,b,c,d,e,f,g);
input [3:0] D;
output reg a,b,c,d,e,f,g;
always @*
	begin
		case(D)
		4'd0:{a,b,c,d,e,f,g}=7'b1111_110;
		4'd1:{a,b,c,d,e,f,g}=7'b0110_000;
		4'd2:{a,b,c,d,e,f,g}=7'b1101_101;
		4'd3:{a,b,c,d,e,f,g}=7'b1111_001;
		4'd4:{a,b,c,d,e,f,g}=7'b0110_011;
		4'd5:{a,b,c,d,e,f,g}=7'b0110_011;
		4'd6:{a,b,c,d,e,f,g}=7'b1011_111;
		4'd7:{a,b,c,d,e,f,g}=7'b1110_000;
		4'd8:{a,b,c,d,e,f,g}=7'b1111_111;
		4'd9:{a,b,c,d,e,f,g}=7'b1111_110;
		default:{a,b,c,d,e,f,g}=7'b1111_110;
		endcase
	end
endmodule

用for语句实现两个8位数相乘

module mult_for(a ,b,outcome);
input [7:0]a,b;
output reg[15:0] outcome;
integer i;
always @(a or b)
 	begin outcome <=0;
 	for(i=1;i<=8;i=i+1)
 	if(b[i]) outcome <=outcome+(a<<(i-1));
	end
 endmodule

用repeat 实现两个8位二进制数的乘法

module mult_repeat
								#(parameter size = 8)
								(input [size:1] a,b;
								output reg[2*size:1] result);
	reg [2*size:] temp_a;reg[size:1] temp_b;
	always @)(a or b)
	begin
	result=0; temp_a=a;temp_b=b;temp_b=b;
	always(size)
		begin
			if(temp_b[1])
				result=result+temp_a;
				temp_a=temp_a<<1;
				temp_b=temp_b>>1;
		end
	end
	endmodule

我们习惯用for循环来实现两个数相乘,for似乎也更好理解。当b上的数为1,则a左移一位。

投票表决器

module voter7(input [6:0] vote,output reg pass);
reg [2:0] sum; integer i;
always @ (vote)
	begin sum=0;
		for(i=0;i<=6;i=i+1)
			if(vote[i]) sum=sum+1;
				if(sum[2]) pass=1;
				else pass=0;
	end
endmodule
发布了19 篇原创文章 · 获赞 2 · 访问量 1098

猜你喜欢

转载自blog.csdn.net/qq_42692319/article/details/102764759