Processus d'auto-apprentissage de base du FPGA

Table des matières

1. Installation et crackage des logiciels Quartus II et Modelsim

2. Terminez la simulation de circuit de base

1. Circuit logique combiné

(1) Simulation de base du circuit de porte NOR et simulation de base de l'addition, de la soustraction, de la multiplication et de la division

(2), demi-additionneur et additionneur complet

(3), encodeur et décodeur

(5), sélecteur de données (choisissez l'un des deux)

2. Circuit logique séquentiel

 (1), registres et registres à décalage

(2), compteur (décimal/24/60)

(3), diviseur de fréquence (deux fréquences/dix fréquences)

3. Machine à états


1. Installation et crackage des logiciels Quartus II et Modelsim

(Remarques : si la puce est EP2XXX, alors la programmation correspondante utilise Cyclone II ou la version suivante . Cette version n'est prise en charge que dans Quartus13.0 et versions antérieures, tandis que EP4XXX et versions ultérieures sont applicables à Quartus13.0 et versions ultérieures.)

Lien du package d'installation Quartus13.0 :

http://Lien : https://pan.baidu.com/s/1TvCEyduApTvVlgcFJO9h_g     Code d'extraction : 6666.

Lien du didacticiel d'installation de Quartus13.0 :

https://blog.csdn.net/pang9998/article/details/83447190

Package d'installation Quartus18.0 et liens vers le didacticiel :

https://mp.weixin.qq.com/s/m1sFpNMR79V0Mk81axJ22Q

2. Terminez la simulation de circuit de base

1. Circuit logique combiné

(1) Simulation de base du circuit de porte NOR et simulation de base de l'addition, de la soustraction, de la multiplication et de la division

Schéma de circuit original (l'addition, la soustraction, la multiplication et la division ne sont pas incluses) :

code:

//与门
module door(
	input in1, 
	input in2,
	output out
);
	//连续赋值(逻辑描述)
	assign out = in1 & in2;
	
	//位置调用(结构描述)
//	and (out, in1, in2);
endmodule	

//或门
module door(
	input in1, 
	input in2,
	output out
);
	//连续赋值(逻辑描述)
	assign out = in1 | in2;
	
	//位置调用(结构描述)
//	or (out, in1, in2);
endmodule	

//非门
module door(
	input in, 
	output out
);
	//连续赋值(逻辑描述)
	assign out = ~ in;
	
	//位置调用(结构描述)
//	not (out, in1);
endmodule	

//除此之外还有“nor”异或 “xnor”同或

//加减乘除
module door(
	input in1, 
	input in2,
	output out
);
	assign out = in1 + in2; //1+1=0,1+0=1
	assign out = in1 - in2;	//0-1=1,1-1=0
	assign out = in1 * in2; //0*1=0,1*1=1
	assign out = in1 / in2; //1/1=1,当in1=1,in2=0和in1=0,in2=0时出现1/2
endmodule	

(2), demi-additionneur et additionneur complet

Lien de référence des idées de conception :

https://wuzhikai.blog.csdn.net/article/details/124116237

  • demi-additionneur

Un demi-additionneur est un circuit d'opération d'additionneur qui ajoute deux nombres binaires d'un bit et génère « résultat » et « carry » en conséquence.

Code principal:

//半加器
module add(
	input in1,  //加数1
	input in2,	//加数2
	output sum, //两个数的加和
	output cout //加数和的进位
);
//第一种方式
	assign sum = in1 ^ in2;
	assign cout = in1 & in2;
//第二种方式
	assign {cout, sum} = in1 + in2;
	
endmodule

Code de simulation du banc de test :

`timescale 1ns/1ns
module sim_add();

//输入reg定义
reg in1, in2;
//输出wire定义
wire cout, sum;

//给初始信号
initial begin
	in1<=1'b0;					
	in2<=1'b0;					
end

//↓写成令每10ns,产生一次随机输入
always #10 in1<= {$random} %2;	//每10个时钟周期产生1个随机数
always #10 in2<= {$random} %2;

//创建模块
add adder(
	.in1(in1),
	.in2(in2),
	.sum(sum),	
	.cout(cout)
);
endmodule

Son schéma de circuit de simulation (de gauche à droite le premier et le deuxième) :

 Forme d'onde de simulation ModelSim :

Un additionneur complet est un appareil qui peut ajouter deux données binaires d'un bit et produire un « résultat », un « report » et un « report de bit faible ».

Code principal:

module add(
	input in1,  //加数1
	input in2,	//加数2
	input cin,  //低位向高位的进位
	output sum, //两个数的加和
	output cout //加数和的进位
);
	assign {cout, sum} = in1 + in2 + cin;

endmodule

Code de simulation du banc de test :

`timescale 1ns/1ns
module sim_add();

//输入reg定义
reg in1, in2, cin;
//输出wire定义
wire cout, sum;

//给初始信号
initial begin
	in1<=1'b0;					
	in2<=1'b0;	
	cin<=1'b0;
end

//↓写成令每10ns,产生一次随机输入
always #10 in1<= {$random} %2;	//每10个时钟周期产生1个随机数
always #10 in2<= {$random} %2;
always #10 cin<= {$random} %2;

//创建模块
add adder(
	.in1(in1),
	.in2(in2),
	.cin(cin),
	.sum(sum),	
	.cout(cout)
);
endmodule

Schéma du circuit de simulation :

Forme d'onde de simulation ModelSim :

 

(3), encodeur et décodeur

  • Encodeur

Un encodeur est un appareil qui convertit un signal d'entrée de quelques bits en un code multi-bits spécifique.

8-3 Lien de référence sur la conception du codeur :

https://blog.csdn.net/Ding_ding_fly/article/details/54882615?ops_request_misc=&request_id=&biz_id=102&utm_term=8-3%E7%BC%96%E7%A0%81%E5%99%A8&utm_medium=distribute. pc_search_result.none-task-blog-2~all~sobaiduweb~default-0-54882615.142^v47^pc_rank_34_1,201^v3^control_2&spm=1018.2226.3001.4187

Code principal:

//8-3编码器
module encode_decode(
	input      [7:0]in,  
	output reg [2:0]out 
);
	
always @(*) begin
	case (in)
			8'b00000001: out = 3'b000;
			8'b00000010: out = 3'b001;
			8'b00000100: out = 3'b010;
			8'b00001000: out = 3'b011;
			
			8'b00010000: out = 3'b100;
			8'b00100000: out = 3'b101;
			8'b01000000: out = 3'b110;
			8'b10000000: out = 3'b111;
	endcase
end
endmodule

Code de simulation du banc de test :

`timescale 1ns/1ns
module sim_encode_decode();

//输入reg定义
reg  [7:0]in;
//输出wire定义
wire [2:0]out;

//给初始信号
initial begin
	in[0] = 1;in[1] = 0;in[2] = 0;in[3] = 0;
	in[4] = 0;in[5] = 0;in[6] = 0;in[7] = 0;
	#100;
	in= in << 1;
	#100;
	in= in << 1;
	#100;
	in= in << 1;
end					


//创建模块
encode_decode encode(
	.in(in[7:0]),
	.out(out[2:0])
);
endmodule

Schéma de circuit de simulation (affichage partiel) :

Forme d'onde de simulation ModelSim :

  • Décodeur (y compris décodeur 3-8 et décodeur à tube numérique)

Un décodeur est un appareil qui convertit un signal d'entrée de quelques bits en un code multi-bits spécifique.

Lien de référence de conception :

https://blog.csdn.net/quanqueen/article/details/113094663

>3-8 code principal du décodeur :

//3-8译码器
module encode_decode(
	input      [2:0]in,  
	output reg [7:0]out 
);
	
always @(*) begin
	case (in)
			3'b000: out = 8'b00000001;
			3'b001: out = 8'b00000010;
			3'b010: out = 8'b00000100;
			3'b011: out = 8'b00001000;
			
			3'b100: out = 8'b00010000;
			3'b101: out = 8'b00100000;
			3'b110: out = 8'b01000000;
			3'b111: out = 8'b10000000;
	endcase
end
endmodule

Code de simulation du banc de test :

`timescale 1ns/1ns
module sim_encode_decode();

//输入reg定义
reg  [2:0]in;
//输出wire定义
wire [7:0]out;

//给初始信号
initial in<=3'b0;					

//↓写成令每10ns,产生一次随机输入
always #10 in<= {$random} %2;	

//创建模块
encode_decode decode(
	.in(in[2:0]),
	.out(out[7:0])
);

endmodule

Schéma du circuit de simulation :

Forme d'onde de simulation ModelSim :

Décodeur numérique à tubes :

Le décodeur numérique à tube est une sorte de décodeur pour l'affichage numérique à tube de la porte tournante.

Lien de référence de conception :

https://blog.csdn.net/weixin_63090979/article/details/121106854

>Le code principal du décodeur de tube numérique :

//数码管编码器(共阳极)
module ni_tub_dec(
	input      [3:0]in,  
	output reg [7:0]out 
);
	
always @(*) begin
	case (in)
			4'b0000: out = 8'b1100_0000;
			4'b0001: out = 8'b1111_1001;
			4'b0010: out = 8'b1010_0100;
			4'b0011: out = 8'b1011_0000;
			
			4'b0100: out = 8'b1001_1001;
			4'b0101: out = 8'b1000_0010;
			4'b0110: out = 8'b1100_0000;
			4'b0111: out = 8'b1111_1000;
			4'b1000: out = 8'b1000_0000;
			4'b1001: out = 8'b1001_0000;
	endcase
end
endmodule

Code de simulation du banc de test :

`timescale 1ns/1ns
module sim_ni_tub_dec();

//输入reg定义
reg  [3:0]in;
//输出wire定义
wire [7:0]out;

//给初始信号
initial begin
		in = 4'd0;
		#100;
		in = 4'd1;
		#100;
		in = 4'd2;
		#100;
		in = 4'd3;
		#100;
		in = 4'd4;
		#100;
		in = 4'd5;
		#100;
		in = 4'd6;
		#100;
		in = 4'd7;
		#100;
		in = 4'd8;
		#100;
		in = 4'd9;
		#100;
	$stop;
end					

//创建模块
ni_tub_dec decode(
	.in(in[3:0]),
	.out(out[7:0])
);
endmodule

Schéma du circuit de simulation :

Forme d'onde de simulation ModelSim :

(5), sélecteur de données (choisissez l'un des deux)

Un sélecteur de données est un appareil qui émet un signal correspondant basé sur un bit sélectionné.

Lien de référence de conception :

https://blog.csdn.net/hyhop150/article/details/51222711

Code principal:

//二选一数据选择器
module dat_sel(
	input   in1,
	input   in2,
	input   sel,
	output  out 
);
	
	assign out = sel? in1:in2 ; 
	
endmodule

Code de simulation du banc de test :

`timescale 1ns/1ns
module sim_dat_sel();

//输入reg定义
reg   in1, in2, sel;
//输出wire定义
wire  out;

//给初始信号
initial begin
		in1 <= 0;in2 <= 1;sel <= 0;
		#100
		in1 <= 1;in2 <= 0;sel <= 0;
		#100
		in1 <= 0;in2 <= 1;sel <= 1;
		#100
		in1 <= 1;in2 <= 0;sel <= 1;
		#100
	$stop;
end					

//创建模块
dat_sel selector(
	.in1(in1),
	.in2(in2),
	.sel(sel),
	.out(out)
);
endmodule

Schéma du circuit de simulation :

Forme d'onde de simulation ModelSim :

2. Circuit logique séquentiel

 (1), registres et registres à décalage

  • registre

Un appareil utilisé pour enregistrer des données déclenchées par un front d’horloge.

 Lien de référence de conception d'enregistrement :

https://blog.csdn.net/cjx_csdn/article/details/105203494

Code principal:

//基本寄存器
module rag_srag(
	input   in,
	input   clk,
	output  reg out 
);

	always @(posedge clk) begin
		out = in;
	end
	
endmodule

Code de simulation du banc de test :

//基本寄存器
`timescale 1ns/1ns
module sim_rag_srag();

//输入reg定义
reg   clk, in;
//输出wire定义
wire  out;

//给初始信号
initial begin
		in <= 0;clk <= 1;
		#50
		in <= 1;clk <= 1;
		#50
		in <= 0;clk <= 0;
		#50
		in <= 1;clk <= 0;
		#50
	$stop;
end					

//创建模块
rag_srag rag(
	.in(in),
	.clk(clk),
	.out(out)
);

endmodule

Schéma du circuit de simulation :

Forme d'onde de simulation ModelSim :

  • Registre à décalage

Un registre qui est déclenché par un front d'horloge et décale les données enregistrées vers la gauche et la droite.

Lien de référence de conception :

https://reborn.blog.csdn.net/article/details/80377919

Code principal:

//移位寄存器(右)
module rag_srag(
	input   clk,
	input   [15:0]in,
	output  reg [15:0]out 
);

	always @(posedge clk) begin
		out = {in[0], in[15:1]};
	end
	
endmodule

Code de simulation du banc de test :

//移位寄存器(16位)
`timescale 1ns/1ns
module sim_rag_srag();

//输入reg定义
reg   clk;
reg   [15:0]in;
//输出wire定义
wire  [15:0]out;

always #50 clk = ~clk;

//给初始信号
initial begin
		in =16'b0;clk = 1;
		#50
		in =16'b0000_0000_0000_0001;
		#50
		in =16'b1100_0000_0000_0011;
		#50
		in =16'b0011_0000_0000_1111;
		#50
		in =16'b0011_0000_0011_1111;
		#50
		in =16'b0011_0110_0000_1000;
		#50
	$stop;
end					

//创建模块
rag_srag srag(
	.in(in[15:0]),
	.clk(clk),
	.out(out[15:0])
);

endmodule

Schéma du circuit de simulation :

Forme d'onde de simulation ModelSim :

(2), compteur (décimal/24/60)

Un appareil dont le comptage est déclenché principalement par le signal de front de l'horloge.

Lien de référence de conception :

https://blog.csdn.net/weixin_43758368/article/details/101517017

Code principal:

//计数器(四位十进制)
//无输入,内定一个寄存器进行时钟上升沿计数,最后通过输出反映出来
module counter(
	input   clk,rst,  //时钟,复位
	output  [3:0]out
);
	reg  [3:0]q;
	
	assign out = q;
	
	always @(posedge clk) 
	begin
		if(rst==0)
			q = 0;
		else if(q>=4'd9) 
			q = 0;
		else 
			q = q + 1;
	end
	
endmodule 

//计数器(五位二十四进制)
module counter(
	input   clk,rst,  //时钟,复位
	output  [4:0]out
);
	reg  [4:0]q;
	
	assign out = q;
	
	always @(posedge clk) 
	begin
		if(rst==0)
			q = 0;
		else if(q>=5'd24) 
			q = 0;
		else 
			q = q + 1;
	end
	
endmodule

//计数器(五位二十四进制)
module counter(
	input   clk,rst,  //时钟,复位
	output  [5:0]out
);
	reg  [5:0]q;
	
	assign out = q;
	
	always @(posedge clk) 
	begin
		if(rst==0)
			q = 0;
		else if(q>=6'd60) 
			q = 0;
		else 
			q = q + 1;
	end
	
endmodule

Code de simulation du banc de test :

//计数器(十进制)
`timescale 1ns/1ns
module sim_counter();

//十进制定义
reg   clk, rst;
wire  [3:0]out;

//二十四进制定义
reg   clk, rst;
wire  [4:0]out;

//六十进制定义
reg   clk, rst;
wire  [5:0]out;

always #5 clk <= ~clk;

//给初始信号
initial begin
		clk <= 0;rst <= 0;
		#10;
		rst <= 1;
end					

//十进制模块
counter coun10(
	.rst(rst),
	.clk(clk),
	.out(out[3:0])
);
//二十四进制模块
counter coun24(
	.rst(rst),
	.clk(clk),
	.out(out[4:0])
);
//六十进制模块
counter coun60(
	.rst(rst),
	.clk(clk),
	.out(out[5:0])
);

endmodule

Schéma du circuit de simulation :

(décimal)

(24 hexadécimal)

(sexadécimal)

 Forme d'onde de simulation ModelSim (exemple sexagésimal) :

(3), diviseur de fréquence (deux fréquences/dix fréquences)

Un dispositif utilisé pour générer un signal à basse fréquence d'horloge à partir d'un signal à haute fréquence d'horloge existant.

Lien de référence de conception :

https://blog.csdn.net/supenman_mwg/article/details/7654141

Code principal (fréquence 2/10) :

//二分频
//使用复位仿照时钟由边沿改变输出信号,配合着原本的时钟,这就形成了二分的频率
module fre_div(
	input   clk,rst,  //时钟,复位
	output  out_clk
);

reg  q;
assign out_clk = q;
	
always @(posedge clk, posedge rst) 
	begin
		if(rst==1)
			q = 0;
		else 
			q = ~q;
	end
	
endmodule

//十分频
//需要定义一个计数器,计五个二分频
module fre_div(
	input   clk,rst,  //时钟,复位 
	output  out_clk
);
parameter N = 5;
reg [N-1:0]cnt;  //计数器
reg  q;				
assign out_clk = q;
	
always @(posedge clk, posedge rst) begin
		if(rst==1) begin
			q <= 0;
			cnt <= 0;
		 end
		else begin
			if(cnt>=N-1)begin 
				 q <= ~q;
				 cnt <= 0;
			  end
			else begin 
				 cnt <= cnt + 1;
			  end
		 end
	end
endmodule

Code de simulation du banc de test :

//二分频/十分频
`timescale 1ns/1ns
module sim_fre_div();

reg   clk, rst;
wire  out_clk;

always #20 clk <= ~clk;

//给初始信号
initial begin
		clk=0;rst=1;
      #24 rst =0;
end					

fre_div divider2(
	.rst(rst),
	.clk(clk),
	.out_clk(out_clk)
);

endmodule

Schéma du circuit de simulation :

(fréquence bidirectionnelle)

(très souvent)

Forme d'onde de simulation ModelSim :

(fréquence bidirectionnelle)

(très souvent)

3. Machine à états

Machine à états, le nom complet est machine à états finis , est un circuit séquentiel qui bascule entre des états finis selon certaines règles et peut être considéré comme une combinaison de logique combinatoire et de logique séquentielle.
➢ Machine à états Mealy : la sortie de la logique combinatoire dépend non seulement de l'état actuel, mais aussi de l'état d'entrée.
➢ Machine à états de Moore : la sortie de la logique combinatoire dépend uniquement de l'état actuel.
 

 Lien de référence sur la conception de la machine d'état :

https://wuzhikai.blog.csdn.net/article/details/119421783

Code principal:

/**********<三段式状态机>*************/
//特点:在二段的基础上,再次细分,将输出的状态分离,形成划分明确的状态机
//------"摩尔型"-----//
//三段米勒型写法,同上段与摩尔的关系写法一样
module sta_mac(
	input      clk,   //时钟信号
	input      rst,	//复位信号(低电平有效)
	input      money,	//投币信号(高电平有效)
	output reg cola	//可乐信号(高电平为出可乐)
);
//独热码定义(状态参数)
localparam	Init     = 4'b0001,
				One_cin  = 4'b0010,
				Two_cin  = 4'b0100,
				There_cin= 4'b1000;

reg [3:0] curr_sta;   //现态
reg [3:0] next_sta;   //次态(相当于一个中间传递数据的寄存器)

//***第一段:同步时序"状态转移"
always @(posedge clk, negedge rst) begin
	if(!rst)
		curr_sta <= Init;		  //回到初始
	else
		curr_sta <= next_sta;  //向现态传递次态数据
end

//***第二段:组合逻辑状态"转移条件"
always @(*) begin
		case (curr_sta) // 依据现态情况转移状态
			Init: begin             //初始状态			
				if(money)				
					next_sta <= One_cin;
				else 
					next_sta <= Init;
			end
			One_cin: begin				//一个硬币状态			
				if(money)				
					next_sta <= Two_cin;
				else 
					next_sta <= One_cin;
			end
			Two_cin: begin				//二个硬币状态		
				if(money)
					next_sta <= There_cin;
				else 
					next_sta <= Two_cin;
			end
			There_cin: begin			//三个硬币状态		
				if(money)				
					next_sta <= One_cin;
				else 
					next_sta <= Init;
			end
			default: begin				//其他情况,同初始状态
				if(money)				
					next_sta <= One_cin;
				else 
					next_sta <= Init;
			end
		endcase
end

//***第三段:各个"状态对应的输出情况"
always @(posedge clk, negedge rst) begin
	if(!rst)
		cola <= 1'b0;
	else 
		case (curr_sta)
			Init:      cola <= 1'b0;
			One_cin:   cola <= 1'b0;
			Two_cin:   cola <= 1'b0;
			There_cin: cola <= 1'b1;
			default:   cola <= 1'b0;
		endcase
end
endmodule

Code de simulation du banc de test :

//状态机仿真代码
`timescale 1ns/1ns
module sim_sta_mac();
reg	clk;   		//时钟信号
reg	rst;			//复位信号
reg	money; 		//投币信号
wire	cola;	 		//可乐信号

//建立模块
sta_mac machin_1duan(
	.money(money),
	.rst(rst),
	.clk(clk),
	.cola(cola)
);

//给初始信号
initial begin
	clk = 1'b0;			//初始时钟为0
	rst <= 1'b0;		//初始复位
	money <= 1'b0;				//投币初始化为0
	#5								

	rst <= 1'b1;		//拉高复位,系统进入工作状态
	#25							
	money <= 1'b1;				//拉高投币信号(投币)	
	#40							
	money <= 1'b0;	    		//拉低投币信号(不投币)
	#20							
	money <= 1'b1;	    		//拉高投币信号(投币)
	#80							
	money <= 1'b0;				//拉低投币信号(不投币)	
end					
//给时钟信号
always #10 clk <= ~clk;

//状态名称查看器(看不了)
/*reg [71:0] state_name;
always @(*) begin
	case (machin_1duan.state)
		4'b0001: state_name = "Init";
		4'b0010: state_name = "One_cin";
		4'b0100: state_name = "Two_cin";
		4'b1000: state_name = "There_cin";
		default: state_name = "Init";
	endcase
end*/

endmodule

Diagramme d'état :

Schéma du circuit de simulation :

Forme d'onde de simulation ModelSim :

4. La dernière étape consiste à faire des expériences de simulation sur la carte FPGA

L'expérience de carte avancée peut être recherchée à la station B : Wildfire FPGA

Je suppose que tu aimes

Origine blog.csdn.net/m0_56883893/article/details/126918807
conseillé
Classement