赞
踩
目录
一、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
电路原件图(加减乘除不在其中):
代码:
- //与门
- 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
设计思路参考链接:
https://wuzhikai.blog.csdn.net/article/details/124116237
半加器是一种将两个一位二进制相加,并对应输出“结果”和“进位”的加法器运算电路。
主代码:
- //半加器
- 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
Testbench仿真代码:
- `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
其仿真电路图(从左到右分别是第一种和第二种):
ModelSim仿真波形:
全加器是一种可以对两个一位二进制数据进行相加,并输出“结果”、“进位”和“低位进位”的一种器件。
主代码:
- module add(
- input in1, //加数1
- input in2, //加数2
- input cin, //低位向高位的进位
- output sum, //两个数的加和
- output cout //加数和的进位
- );
- assign {cout, sum} = in1 + in2 + cin;
-
- endmodule
Testbench仿真代码:
- `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仿真波形:
编码器是一种可以将少位输入信号转换为特定多位编码的器件。
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
Testbench仿真代码:
- `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仿真波形:
译码器是一种可以将少位输入信号转换为特定多位编码的器件。
设计参考链接:
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
Testbench仿真代码:
- `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
Testbench仿真代码:
- `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仿真波形:
数据选择器是一种根据选择位输出的相应信号的器件。
设计参考链接:
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
Testbench仿真代码:
- `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仿真波形:
由时钟边沿触发的一种用于寄存数据的器件。
寄存器设计参考链接:
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
Testbench仿真代码:
- //基本寄存器
- `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
Testbench仿真代码:
- //移位寄存器(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仿真波形:
主要通过时钟的边沿信号触发计数的一种器件。
设计参考链接:
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
Testbench仿真代码:
- //计数器(十进制)
- `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
仿真电路图:
(十进制)
(二十四进制)
(六十进制)
ModelSim仿真波形(例六十进制):
用于通过原有的高时钟频率信号,生成低时钟频率信号的器件。
设计参考链接:
https://blog.csdn.net/supenman_mwg/article/details/7654141
主代码(二分频 / 十分频):
- //二分频
- //使用复位仿照时钟由边沿改变输出信号,配合着原本的时钟,这就形成了二分的频率
- 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
Testbench仿真代码:
- //二分频/十分频
- `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仿真波形:
(二分频)
(十分频)
状态机,全称是有限状态机,是一种在有限个状态之间按一定规律转换的时序电路,可以认为是组合逻辑和时序逻辑的一种组合。
➢ Mealy状态机:组合逻辑的输出不仅取决于当前状态,还取决于输入状态。
➢ Moore状态机:组合逻辑的输出只取决于当前状态。
状态机设计参考链接:
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
Testbench仿真代码:
- //状态机仿真代码
- `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仿真波形:
四、最后一步,也就是上FPGA板做仿真实验
上板实验进阶可以于B站搜索:野火FPGA
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。