想要交流的,关注公众号,后台联系即可
文章目录
FPGA实验一 项目创建、编译和下载
项目名称和顶层设计的名称要一致
通过开发板原理图查找SW开关和LED灯和FPGA的管脚对应关系。
本次实验要求为一个拨码开关同时控制10个LED小灯的亮灭。
首先对BDF文件进行编译,编译通过后,通过菜单Assignments中pin planner设定信号名称和管脚的对应关系。
设定不用的管脚为三态,然后编译下载
打开下载界面后需要先点击Hardware Setup选择FPGA所在的COM口,然后点击Start。
FPGA实验二 译码器组合逻辑
学生实验一
放置2个2-4译码器模块,则总共有2组SW,每组2个,2组LED,每组4个,每组SW分别控制其对应的LED组。
首先编写实验相应的
Verilog代码
,然后生成代码文件对应的
模块
module dec_2to4(
IN ,
OUT);
input [1:0] IN ;
output [3:0] OUT ;
reg [3:0] OUT ;
always @ (IN) begin
case(IN)
2'b00: OUT = 4'b 0001;
2'b01: OUT = 4'b 0010;
2'b10: OUT = 4'b 0100;
2'b11: OUT = 4'b 1000;
endcase
end
endmodule // module dec_2to4;
在BDF文件中可以添加刚才通过.v文件生成的自定义符号模块
按照实验一方法对其进行引脚的匹配
本次实验通过对导线的命名来进行连接,注意区别导线的命名方式
inW[0]、inW[1] 对应 inW[1…0], inW[2]、 inW[3] 对应 inW[3…2]
导线命名方法:导线上右键,properties -> name
线网的选择使用 两个点号” … ”
学生实验二
参照代码,设计一个
3-8译码器
,完成类似的拨码开关实验。(注意代码中的
信号宽度设定
)
module decoder
(
IN,
OUT
);
input [2 : 0] IN;
output [7 : 0] OUT;
reg [7 : 0] OUT;
always @ (IN)
begin
case (IN)
3'b000: OUT = 8'b0000_0001;
3'b001: OUT = 8'b0000_0010;
3'b010: OUT = 8'b0000_0100;
3'b011: OUT = 8'b0000_1000;
3'b100: OUT = 8'b0001_0000;
3'b101: OUT = 8'b0010_0000;
3'b110: OUT = 8'b0100_0000;
3'b111: OUT = 8'b1000_0000;
endcase
end
endmodule
学生实验三
自行查阅手册中的7段译码器管脚对应关系,用4个拨码开关控制一个7段译码器的数字,从0- 9-A-F,共16个数字和字母。
(1)先自定义所需要的逻辑模块,生成自定义模块
module dec_4to16
(
IN,
OUT
);
input [3 : 0] IN;
output [6 : 0] OUT;
reg [6 : 0] OUT;
always @ (IN)
begin
case (IN)//gongyang 0youxiao
4'b0000: OUT = 7'b100_0000;//0
4'b0001: OUT = 7'b111_1001;//1
4'b0010: OUT = 7'b010_0100;//2
4'b0011: OUT = 7'b011_0000;//3
4'b0100: OUT = 7'b001_1001;//4
4'b0101: OUT = 7'b001_0010;//5
4'b0110: OUT = 7'b000_0010;//6
4'b0111: OUT = 7'b111_1000;//7
4'b1000: OUT = 7'b000_0000;//8
4'b1001: OUT = 7'b001_0000;//9
4'b1010: OUT = 7'b000_1000;//A
4'b1011: OUT = 7'b000_0011;//B
4'b1100: OUT = 7'b100_0110;//C
4'b1101: OUT = 7'b010_0001;//D
4'b1110: OUT = 7'b000_0110;//E
4'b1111: OUT = 7'b000_1110;//F
endcase
end
endmodule
(2)对照引脚图配置,配置前记得先编译
FPGA实验三 计数器、波形仿真、SignalTap
SignalTap仿真步骤及其注意事项
(1)例化的子模块的代码原型,即“.v”文件
//cnt_0to9
module cnt_0to9(
CLK , // clock
CNTVAL, // counter value
OV ); // overflow
input CLK;
output [4-1:0] CNTVAL;
output OV;
reg [4-1:0] CNTVAL;
reg OV;
always @ (posedge CLK) begin
if(CNTVAL >= 9)
CNTVAL <= 0;
else
CNTVAL <= CNTVAL + 1'b1;
end
always @ (CNTVAL) begin
if(CNTVAL == 9)
OV = 1'b1;
else
OV = 1'b0;
end
endmodule // module cnt_0to9
(2)生成代码文件对应的
符号模块
,在BDF文件中调用(代码文件中要包含所使用的计数器Verilog代码)
(3)
编译后
,指派时钟管脚PIN_G21或者PIN_B12,由
晶振
提供50MHZ时钟,再
编译
(4)观察RTL视图
(5)新建
SignalTapll
文件,添加到工程中
(6)setup页面添加
采样时钟
,filter项选择design entry(all name)选择CLK50,添加OUT, OV
(7)
编译前先把程序下载到板子
显示结果
学生实验一
module cnt_0to17(
CLK , // clock
CNTVAL, // counter value
OV ); // overflow
input CLK;
output [6-1:0] CNTVAL;
output OV;
reg [6-1:0] CNTVAL;
reg OV;
always @ (posedge CLK) begin
if(CNTVAL >= 17)
CNTVAL <= 0;
else
CNTVAL <= CNTVAL + 1'b1;
end
always @ (CNTVAL) begin
if(CNTVAL == 17)
OV = 1'b1;
else
OV = 1'b0;
end
endmodule
学生实验二
module cnt_0to17_1(
CLK , // clock
CNTVAL, // counter value
OV ); // overflow
input CLK;
output [6-1:0] CNTVAL;
output OV;
reg [6-1:0] CNTVAL;
reg OV;
always @ (posedge CLK) begin
if(CNTVAL >= 17)
CNTVAL <= 0;
else
CNTVAL <= CNTVAL + 1'b1;
end
always @ (CNTVAL) begin
if(CNTVAL >= 9 && CNTVAL <= 17)
OV = 1'b1;
else
OV = 1'b0;
end
endmodule
在实验二的基础上,把OV接到一个LED上
没有观察到明显变化,因为OV输出频率大约为1,388,888Hz,肉眼观察不到变化
FPGA实验四 时间基准电路和带使能的多周期计数器
例题
时间基准电路介绍:定时发出一个窄脉冲的电路
本实验设计目标:
(1)设计时间基准电路和带使能的多周期计数器
(2)时间基准电路生成同步时间基准信号
(3)多周期 计数器对时间基准信号进行计数
本质上是一个两级计数器级联的电路结构
第一级计数器生成时间基准信号
第二级计数器用时间基准信号作为计数使能
符号模块代码
module cnt_sync(
CLK , // clock
CNTVAL, // counter value
OV ); // overflow
input CLK;
output [32-1:0] CNTVAL;
output OV;
parameter MAX_VAL = 25_000_000;
reg [32-1:0] CNTVAL;
reg OV;
always @ (posedge CLK) begin
if(CNTVAL >= MAX_VAL)
CNTVAL <= 0;
else
CNTVAL <= CNTVAL + 1'b1;
end
always @ (CNTVAL) begin
if(CNTVAL == MAX_VAL)
OV = 1'b1;
else
OV = 1'b0;
end
endmodule // module cnt_en_0to9
module cnt_en_0to9(
CLK , // clock
CNTVAL, // counter value
EN ,
OV ); // overflow
input CLK;
input EN;
output [4-1:0] CNTVAL;
output OV;
reg [4-1:0] CNTVAL;
reg OV;
always @ (posedge CLK) begin
if(EN) begin // work enable
if(CNTVAL >= 9)
CNTVAL <= 0;
else
CNTVAL <= CNTVAL + 1'b1;
end
else
CNTVAL <= CNTVAL ; // hold same value
end
always @ (CNTVAL) begin
if(CNTVAL == 9)
OV = 1'b1;
else
OV = 1'b0;
end
endmodule // module cnt_en_0to9
MAX_VAL代表最大计数个数,例如,时钟信号为50,000,000hz,计数器为25,000,000hz,所以每隔0.5秒给一次cnt_en_0to9使能EN,进而进行通过编译器cnt_en_0to9输出0-9
signaltap仿真波形,当val=5时
当val=25,000,000时,默认设置抓取不到out的跳变
使用高级触发方式,
分段触发
,选中segmented模式,8段16样点,选择en_out作为触发事件,采集其附近波形样点
学生实验一
题目:参照代码,把后级计数器范围改为0-15.
添加新的后级计数器
module cnt_en_0to15(
CLK , // clock
CNTVAL, // counter value
EN ,
OV ); // overflow
input CLK;
input EN;
output [5-1:0] CNTVAL;
output OV;
reg [5-1:0] CNTVAL;
reg OV;
always @ (posedge CLK) begin
if(EN) begin // work enable
if(CNTVAL >= 15)
CNTVAL <= 0;
else
CNTVAL <= CNTVAL + 1'b1;
end
else
CNTVAL <= CNTVAL ; // hold same value
end
always @ (CNTVAL) begin
if(CNTVAL == 15)
OV = 1'b1;
else
OV = 1'b0;
end
endmodule // module cnt_en_0to9
学生实验二
题目:把计数器的0-15计数值经过译码,在DE0的HEX LED上显示成0-9-A-F的十六进制数。
添加数码管显示符号模块
module dec_4to16_HEX
(
IN,
OUT
);
input [5-1 : 0] IN;
output [8-1 : 0] OUT;
reg [8-1 : 0] OUT;
always @ (IN)
begin
case (IN)//共阳极数码管 低电平有效
4'b0000: OUT = 8'b1100_0000;//0
4'b0001: OUT = 8'b1111_1001;//1
4'b0010: OUT = 8'b1010_0100;//2
4'b0011: OUT = 8'b1011_0000;//3
4'b0100: OUT = 8'b1001_1001;//4
4'b0101: OUT = 8'b1001_0010;//5
4'b0110: OUT = 8'b1000_0010;//6
4'b0111: OUT = 8'b1111_1000;//7
4'b1000: OUT = 8'b1000_0000;//8
4'b1001: OUT = 8'b1001_0000;//9
4'b1010: OUT = 8'b1000_1000;//A
4'b1011: OUT = 8'b1000_0011;//B
4'b1100: OUT = 8'b1100_0110;//C
4'b1101: OUT = 8'b1010_0001;//D
4'b1110: OUT = 8'b1000_0110;//E
4'b1111: OUT = 8'b1000_1110;//F
endcase
end
endmodule
signaltap仿真波形正确
学生实验三
题目:修改时间基准发生器,设计一个使用2个HEX LED,精度为0.1秒,范围为0-9.9秒的计时秒表。
学生实验四
题目:自行设计上面计时器的附加控制功能(清零、暂停)。
修改新手实验中的多功能计数器代码,生成模块
module duogongnengjishuqi(
RST , // 异步复位, 高有效
CLK , // 时钟,上升沿有效
EN , // 输入的计数使能,高有效
CLR , // 输入的清零信号,高有效
LOAD , // 输入的数据加载使能信号,高有效
DATA , // 输入的加载数据信号
CNTVAL, // 输出的计数值信号
PAUSE ,
OV );// 计数溢出信号,计数值为最大值时该信号为1
input RST , CLK , EN , CLR , LOAD , PAUSE ;
input [3:0] DATA ;
output [3:0] CNTVAL;
output OV;
reg [3:0] CNTVAL, cnt_next;
reg OV;
// 电路编译参数,最大计数值
parameter CNT_MAX_VAL = 9;
// 组合逻辑,生成cnt_next
// 计数使能最优先,清零第二优先,加载第三优先
always @(EN or LOAD or CLR or DATA or CNTVAL) begin
if(EN) begin // 使能有效
if(CLR) begin // 清零有效
cnt_next = 0;
end
else begin // 清零无效
if(LOAD) begin // 加载有效
cnt_next = DATA;
end
else begin // 加载无效,正常计数
// 使能有效,清零和加载都无效,根据当前计数值计算下一值
if(CNTVAL < CNT_MAX_VAL) begin // 未计数到最大值, 下一值加1
cnt_next = CNTVAL + 1'b1;
end
else begin // 计数到最大值,下一计数值为0
cnt_next = 0;
end
end // else LOAD
end // else CLR
end // if EN
else begin // 使能无效,计数值保持不动
cnt_next = CNTVAL;
end // else EN
end
// 时序逻辑 更新下一时钟周期的计数值
// CNTVAL 会被编译为D触发器
always @ (posedge CLK or posedge RST or posedge PAUSE or posedge CLR) begin
if(RST)
CNTVAL <= 0;
else if(PAUSE)
CNTVAL <= CNTVAL;
else if(CLR)
CNTVAL <= 0;
else
CNTVAL <= cnt_next;
end
// 组合逻辑,生成OV
always @ (CNTVAL) begin
if(CNTVAL == CNT_MAX_VAL)
OV = 1;
else
OV = 0;
end
endmodule
因为个位数需要小数点,新建一个带小数点的译码器符号模块
module dec_4to16_HEX1//带小数点
(
IN,
OUT
);
input [4-1 : 0] IN;
output [8-1 : 0] OUT;
reg [8-1 : 0] OUT;
always @ (IN)
begin
case (IN)//共阳极数码管 低电平有效
4'b0000: OUT = 8'b0100_0000;//0
4'b0001: OUT = 8'b0111_1001;//1
4'b0010: OUT = 8'b0010_0100;//2
4'b0011: OUT = 8'b0011_0000;//3
4'b0100: OUT = 8'b0001_1001;//4
4'b0101: OUT = 8'b0001_0010;//5
4'b0110: OUT = 8'b0000_0010;//6
4'b0111: OUT = 8'b0111_1000;//7
4'b1000: OUT = 8'b0000_0000;//8
4'b1001: OUT = 8'b0001_0000;//9
4'b1010: OUT = 8'b0000_1000;//A
4'b1011: OUT = 8'b0000_0011;//B
4'b1100: OUT = 8'b0100_0110;//C
4'b1101: OUT = 8'b0010_0001;//D
4'b1110: OUT = 8'b0000_0110;//E
4'b1111: OUT = 8'b0000_1110;//F
endcase
end
endmodule
可以实现按下SW0键清零,SW1键暂停,小数部分循环0-9一次LED0闪烁一次,个位数循环一次LED1闪烁一次。