目次
1. Quartus II および Modelsim ソフトウェアのインストールとクラッキング
(1) 基本的な NOR ゲート回路シミュレーションと基本的な加減乗除シミュレーション
1. Quartus II および Modelsim ソフトウェアのインストールとクラッキング
(注: チップがEP2XXX の場合、対応するプログラミングはCyclone IIまたは次のバージョンを使用します。このバージョンは Quartus13.0 以下でのみサポートされますが、EP4XXX 以降は Quartus13.0 以降に適用されます。)
Quartus13.0 インストールパッケージのリンク:
http://リンク: https://pan.baidu.com/s/1TvCEyduApTvVlgcFJO9h_g 抽出コード: 6666。
Quartus13.0 インストールチュートリアルのリンク:
https://blog.csdn.net/pang9998/article/details/83447190
Quartus18.0 インストール パッケージとチュートリアルのリンク:
https://mp.weixin.qq.com/s/m1sFpNMR79V0Mk81axJ22Q
2. 基本的な回路シミュレーションを完了する
1. 組み合わせ論理回路
(1) 基本的な NOR ゲート回路シミュレーションと基本的な加減乗除シミュレーション
元の回路図 (加算、減算、乗算、除算は含まれていません):
コード:
//与门
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)、半加算器と全加算器
デザインアイデアの参考リンク:
https://wuzhikai.blog.csdn.net/article/details/124116237
- 半加算器
半加算器は、1ビットの2進数を2つ加算し、「結果」と「桁上げ」を出力する加算演算回路です。
メインコード:
//半加器
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
テストベンチのシミュレーション コード:
`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
そのシミュレーション回路図 (左から右に 1 番目と 2 番目):
ModelSim シミュレーション波形:
- 全加算器(リンク)
全加算器は、2つの1ビットバイナリデータを加算し、「結果」、「キャリー」、「下位ビットキャリー」を出力できるデバイスです。
メインコード:
module add(
input in1, //加数1
input in2, //加数2
input cin, //低位向高位的进位
output sum, //两个数的加和
output cout //加数和的进位
);
assign {cout, sum} = in1 + in2 + cin;
endmodule
テストベンチのシミュレーション コード:
`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
シミュレーション回路図:
ModelSim シミュレーション波形:
(3)、エンコーダとデコーダ
- エンコーダ
エンコーダは、数ビットの入力信号を特定のマルチビット コードに変換するデバイスです。
8-3 エンコーダ設計のリファレンスリンク:
メインコード:
//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
テストベンチのシミュレーション コード:
`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
シミュレーション回路図(一部表示):
ModelSim シミュレーション波形:
- デコーダ(3-8デコーダおよびデジタルチューブデコーダを含む)
デコーダは、数ビットの入力信号を特定のマルチビット コードに変換するデバイスです。
設計参照リンク:
https://blog.csdn.net/quanqueen/article/details/113094663
>3-8 デコーダのメインコード:
//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
テストベンチのシミュレーション コード:
`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
シミュレーション回路図:
ModelSim シミュレーション波形:
デジタル真空管デコーダ:
デジタル管デコーダは、回転ドアのデジタル管表示用のデコーダの一種です。
設計参照リンク:
https://blog.csdn.net/weixin_63090979/article/details/121106854
>デジタル真空管デコーダのメインコード:
//数码管编码器(共阳极)
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
テストベンチのシミュレーション コード:
`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
シミュレーション回路図:
ModelSim シミュレーション波形:
(5)、データセレクター(2つのうち1つを選択)
データセレクターは、選択されたビットに基づいて対応する信号を出力するデバイスです。
設計参照リンク:
https://blog.csdn.net/hyhop150/article/details/51222711
メインコード:
//二选一数据选择器
module dat_sel(
input in1,
input in2,
input sel,
output out
);
assign out = sel? in1:in2 ;
endmodule
テストベンチのシミュレーション コード:
`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
シミュレーション回路図:
ModelSim シミュレーション波形:
2. 順序論理回路
(1)、レジスタと シフトレジスタ
- 登録する
クロックエッジによってトリガーされたデータを登録するために使用されるデバイス。
レジスタ設計参照リンク:
https://blog.csdn.net/cjx_csdn/article/details/105203494
メインコード:
//基本寄存器
module rag_srag(
input in,
input clk,
output reg out
);
always @(posedge clk) begin
out = in;
end
endmodule
テストベンチのシミュレーション コード:
//基本寄存器
`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
シミュレーション回路図:
ModelSim シミュレーション波形:
- シフトレジスタ
クロックエッジによってトリガされ、登録されたデータを左右にシフトするレジスタ。
設計参照リンク:
https://reborn.blog.csdn.net/article/details/80377919
メインコード:
//移位寄存器(右)
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
テストベンチのシミュレーション コード:
//移位寄存器(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
シミュレーション回路図:
ModelSim シミュレーション波形:
(2)、カウンタ(10進数/24/60)
主にクロックのエッジ信号によってカウントが開始されるデバイス。
設計参照リンク:
https://blog.csdn.net/weixin_43758368/article/details/101517017
メインコード:
//计数器(四位十进制)
//无输入,内定一个寄存器进行时钟上升沿计数,最后通过输出反映出来
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
テストベンチのシミュレーション コード:
//计数器(十进制)
`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
シミュレーション回路図:
(10進数)
(16進数24)
(16進数)
ModelSim シミュレーション波形 (60 進数の例):
(3)、分周器(2周波/10周波)
既存の高クロック周波数信号から低クロック周波数信号を生成するために使用されるデバイス。
設計参照リンク:
https://blog.csdn.net/supenman_mwg/article/details/7654141
メインコード (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
テストベンチのシミュレーション コード:
//二分频/十分频
`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
シミュレーション回路図:
(双方向周波数)
(よく)
ModelSim シミュレーション波形:
(双方向周波数)
(よく)
3. ステートマシン
ステートマシンは、正式名は有限状態マシンといい、ある規則に従って有限状態を切り替える順序回路であり、組み合わせ論理と順序論理を組み合わせたものと考えることができます。
➢ Mealy ステート マシン: 組み合わせロジックの出力は、現在の状態だけでなく入力状態にも依存します。
➢ ムーア ステート マシン: 組み合わせロジックの出力は現在の状態にのみ依存します。
ステート マシン設計のリファレンス リンク:
https://wuzhikai.blog.csdn.net/article/details/119421783
メインコード:
/**********<三段式状态机>*************/
//特点:在二段的基础上,再次细分,将输出的状态分离,形成划分明确的状态机
//------"摩尔型"-----//
//三段米勒型写法,同上段与摩尔的关系写法一样
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
テストベンチのシミュレーション コード:
//状态机仿真代码
`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
状態図:
シミュレーション回路図:
ModelSim シミュレーション波形:
4. 最後のステップは、FPGA ボード上でシミュレーション実験を行うことです。
高度なボード実験はステーション B で検索できます: Wildfire FPGA