实验一:项目创建、编译和下载
1.使用一个拨码开关控制所有的LED灯亮灭。
实验效果:
bdf图:
引脚对应关系图;
实验二:译码器实验
1.放置2个2-4译码器模块,则总共有2组SW, 每组2个,2组LED,每组4个,每组SW分别控 制其对应的LED组。
bdf图:
实验效果:
引脚配置:
2.参考代码,设计一个3-8译码器,完成类似的拨码开关实验。注意代码中的信号宽度设定。
代码:
module dec_3to8(
IN , // input 1
OUT ); // out data
input [4-1:0] IN;
output [8-1:0] OUT;
reg [8-1:0] OUT;
always @ (IN) begin
case(IN)
3'b000:OUT = 8'b 00000001;
3'b001:OUT = 8'b 00000010;
3'b010:OUT = 8'b 00000100;
3'b011:OUT = 8'b 00001000;
3'b100:OUT = 8'b 00010000;
3'b101:OUT = 8'b 00100000;
3'b110:OUT = 8'b 01000000;
3'b111:OUT = 8'b 10000000;
endcase
end
endmodule
bdf图:
引脚图:
效果图:
3.自行查阅手册中的7段译码器管脚对应关系, 用4个拨码开关控制一个7段译码器的数字,从 0-9-A-F,共16个数字和字母
运行效果图:
代码
module dec_4to16(
IN , // input 1
OUT ); // out data
input [4-1:0] IN;
output [8-1:0] OUT;
reg [8-1:0] OUT;
always @ (IN) begin
case(IN)
4'b0000: OUT = 7'b1000000; //0
4'b0001: OUT = 7'b1111001; //1
4'b0010: OUT = 7'b0100100; //2
4'b0011: OUT = 7'b0110000; //3
4'b0100: OUT = 7'b0011001; //4
4'b0101: OUT = 7'b0010010; //5
4'b0110: OUT = 7'b0000010; //6
4'b0111: OUT = 7'b1111000; //7
4'b1000: OUT = 7'b0000000; //8
4'b1001: OUT = 7'b0010000; //9
4'b1010: OUT = 7'b0001000; //A
4'b1011: OUT = 7'b0000011; //b
4'b1100: OUT = 7'b1000110; //C
4'b1101: OUT = 7'b0100001; //d
4'b1110: OUT = 7'b0000110; //E
4'b1111: OUT = 7'b0001110; //F
endcase
end
endmodule
引脚配置图:
引脚配置图:
实验三:计数器波形仿真和signalTap
• 1、参照代码,设计一个0-17的计数器,当 计数值为17的时候,OV输出1,其他输出0, 注意设定合理的信号位宽。
问题:观察毛刺,为什么会有毛刺?点击图标运行仿真,把波形时域展 宽,可以看到,3和4之间还有5, 而2、3之间没有别的数目。
答:这是因为过渡状态的原因。3到4,二进制代码从011到101到100,而2到3可以直接从010到011。
signaltap的图像:
代码:
module cnt_0to17(
CLK , // clock
CNTVAL, // counter value
OV ); // overflow
input CLK;
output [5-1:0] CNTVAL;
output OV;
reg [5-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_0to9
仿真图像:
2.针对以上计数器,修改输出逻辑,当计 数值为0-8时,OV输出0,9-17时OV输出1
signaltap示意图:
代码:
module cnt_0to17(
CLK , // clock
CNTVAL, // counter value
OV ); // overflow
input CLK;
output [5-1:0] CNTVAL;
output OV;
reg [5-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)
OV = 1'b0;
else
OV = 1'b1;
end
endmodule // module cnt_0to9
仿真图:
3.如果时钟是50MHz,把OV接 到一个LED上,能看见什么现象,为什么?
答:频率太高,看不出灯在闪烁。
实验四:时间基准电路和带使能的多周期计数器
1、参照代码,设计一个0-15的计数器,当 计数值为15的时候,OV输出1,其他输出0, 注意设定合理的信号位宽。
计数器代码:
module cnt_0to15(
EN ,
CLK , // clock
CNTVAL, // counter value
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_0to9
2.把计数器的0-15计数值经过译码,在DE0 的 HEX LED上显示成0-9-A-F的十六 进制数。
bdf文件图:
实验效果图:
3.修改时间基准发生器,设计一个使用2个HEX LED,精度为0.1秒,范围为0-9.9秒的计时秒表。自行设计上面计时器的附加控制功能(清零、暂 停)。
多功能计数器的代码:
module cnt_en_0to9_1(
CLK , // clock
CNTVAL, // counter value
EN ,
CLEAR ,
PAUSE ,
OV ); // overflow
input CLK;
input EN;
input CLEAR;
input PAUSE;
output [4-1:0] CNTVAL;
output OV;
reg [4-1:0] CNTVAL;
//reg [4-1:0] temp;
reg OV;
always @ (posedge CLK or posedge CLEAR) begin
if(CLEAR) begin
CNTVAL<=0;
end
else begin
if(EN) begin // work enable
if(PAUSE) begin
CNTVAL <= CNTVAL ; // hold same value
end
else begin
if(CNTVAL >= 9)
CNTVAL <= 0;
else
CNTVAL <= CNTVAL + 1'b1;
end
end
else begin
CNTVAL <= CNTVAL ; // hold same value
end
end
end
always @ (CNTVAL) begin
if(CNTVAL == 9)
OV = 1'b1;
else
OV = 1'b0;
end
endmodule // module cnt_en_0to9
按下清零按键SW0
按下暂停按键SW1:
实验五:多周期时序逻辑 移位寄存电路
编译下载电路观察现象 • 拨动SW0开关,观察LED的闪烁变换情况
拨动开关后,led灯从led0到led5依次点亮,关闭开关后,从led0到led5依次熄灭。
• 设计新的功能 – 在原有的电路基础上,添加方向选择功能。 – SW0仍然是移位寄存器组的输入 – 使用SW1开关,控制移位寄存的方向 – 从实验现象上应当能够看到,SW1可以控制LED闪烁的 移动方向,以及控制SW0值的对LED组的输入位置(即 从LED组的最左边或是最右边)
代码:
串入并出移位寄存器 /
module shift_reg_SIPO1(
RST , // 异步复位, 高有效
CLK , // 时钟,上升沿有效
EN , // 输入数据串行移位使能
IN , // 输入串行数据
DIR , // FANGXIANG
OUT ); // 并行输出数据
parameter SHLEN = 6;
input RST, CLK, EN;
input IN;
input DIR;
output[SHLEN-1:0] OUT;
reg [SHLEN-1:0] shift_R;
assign OUT[SHLEN-1:0] = shift_R[SHLEN-1:0];
// 时序逻辑 根据输入使能进行串行移位
// shift_R 会被编译为D触发器
always @ (posedge CLK ) begin
if(DIR) begin
if(RST)
shift_R[SHLEN-1:0] <= 0;
else
if(EN) begin // 串行移位的使能有效
shift_R[SHLEN-2:0] <= shift_R[SHLEN-1:1];
shift_R[SHLEN-1] <= IN;
end
else begin // 使能无效保持不动
shift_R[SHLEN-1:0] <= shift_R[SHLEN-1:0];
end
end
else begin
if(RST)
shift_R[SHLEN-1:0] <= 0;
else
if(EN) begin // 串行移位的使能有效
shift_R[SHLEN-1:1] <= shift_R[SHLEN-2:0];
shift_R[0] <= IN;
end
else begin // 使能无效保持不动
shift_R[SHLEN-1:0] <= shift_R[SHLEN-1:0];
end
end
end // always
endmodule//
实验六:计数器、ROM和DDS
1.电路的工作时钟是fsys = 50MHz, 拨动开关,观察丌同频率的 正弦波 – 参考设计中,计数器和ROM 地址 都是 7 比特,连接关系如上图所示 – 根据理论分析和实验结果,回答以下问题 – 请回答,你能得到的正弦波频率和计数器增量值的对应关系是什么? • 设输出正弦波频率为f1,电路系统时钟为 fsys, 计数器步进增量为 CNT • 请给出 f1 和 fsys 以及 CNT 关系的数学表达式 – 请回答,你能得到的最低频率的正弦波是多少?
当增量为1时:
当增量为2时:
当增量为4
由波形可以看出计数增量越大,产生的正弦波波形的频率就越高。
当增量为1时,正弦波的频率为50Mhz/128
表达式的关系为f1=fsys*CNT/128
2.时钟频率保持fsys = 50MHz 丌变, • 修改电路,把计数器的计数值和输入的计数增量信号都改为9比特, 计数值的高7位连接ROM的地址线,低2位悬空。如上图所示。 – 把9比特的计数器增量输入信号连接到9个拨码开关上 – 根据理论分析和实验结果,回答以下问题 – 请回答,你能得到的正弦波频率和计数器增量值的对应关系是什么? • 设输出正弦波频率为f1,电路系统时钟为 fsys, 计数器步进增量为 CNT • 请给出 f1 和 fsys 以及 CNT 关系的数学表达式 – 请回答,在这种连接方式下,你能得到的最低频率的正弦波是多少?
当增量为1时:
当增量为2时:
当增量为3时:
表达式的关系为f1=fsys*CNT/512