关于一个掷色子的问题(quartus ii)
时间:10-02
整理:3721RD
点击:
本人新手,望大神指教!老师让我们写个掷骰子的程序,想了想可以用fpga来做,我的想法是写一个6进制计数器,然后按KEY7可以开始,然后最后一个数码管快速滚动显示数字1-6,然后再按一下KEY7暂停,就相当于随机在1-6中抽了一个数。我改了一下代码,发现数码管根本就不亮,因为modelsim和signaltap很不熟悉,所以查不出错误,麻烦大家能指正一下,谢谢!浪费你们的时间了!
(1)module dice //顶层模块
(
CLK_50M,RST_N,KEY,
SEG_DATA,SEG_EN
);
input CLK_50M,RST_N;
input KEY;
output [7:0] SEG_DATA;
output [5:0] SEG_EN;
wire key_out;
wire [3:0] seg_data_out;
Dice_Module dice_module_inst
(
.CLK_50M (CLK_50M),
.RST_N (RST_N),
.key_in (key_out),
.seg_data_out (seg_data_out)
);
Key key_inst
(
.CLK_50M (CLK_50M),
.RST_N (RST_N),
.KEY (KEY),
.key_out (key_out)
);
Segled segled_inst
(
.CLK_50M (CLK_50M),
.RST_N (RST_N),
.seg_data_in (seg_data_out),
.SEG_DATA (SEG_DATA),
.SEG_EN (SEG_EN)
);
endmodule
(2)module Dice_Module //主控制模块
(
CLK_50M,RST_N,key_in,
seg_data_out
);
//---------------------------------------------------------------------------
//-- 外部端口声明
//---------------------------------------------------------------------------
input CLK_50M,RST_N; //时钟和复位
input key_in; //开始和暂停按键
output reg [3:0] seg_data_out; //控制信号
//---------------------------------------------------------------------------
//-- 内部端口声明
//---------------------------------------------------------------------------
reg [3:0] time_cnt; //计数器当前状态
reg [3:0] time_cnt_n; //计数器下一个状态
reg stop_reg; //开始和暂停
reg stop_reg_n; //开始暂停的下一个状态
//设置时间为100ms
parameter TIMESET_100MS=25'd5_000_000;
//---------------------------------------------------------------------------
//-- 逻辑功能实现
//---------------------------------------------------------------------------
//时序电路,用来给stop_reg寄存器赋值
always @(posedge CLK_50M,negedge RST_N)
begin
if(!RST_N) //判断复位
stop_reg<=1'h0; //初始化stop_reg值
else
stop_reg<=stop_reg_n;
end
//组合电路,用于控制数字时钟的暂停与开始
always @(*)
begin
if(key_in)
stop_reg_n=~stop_reg; //当按键按下时,改变stop_reg寄存器的状态
else
stop_reg_n=stop_reg; //当按键没有按下时,stop_reg保持原状态不变
end
//时序电路,六位计数器
always @(posedge CLK_50M,negedge RST_N)
begin
if(!RST_N)
time_cnt<=4'h0; //初始化time_cnt值
else
time_cnt<=time_cnt_n; //用来给time_cnt赋值
end
//组合电路,给time_cnt_n赋值
always @(*)
begin
if(time_cnt==TIMESET_100MS)
time_cnt_n=4'h0; //如果到达100ms,定时计数器将会被清零
else if(stop_reg)
time_cnt_n=time_cnt+4'h1; //如果没有暂停,定时计数器将会继续累加
else
time_cnt_n=time_cnt; //否则,定时计数器将会保持不变
end
//组合电路,给seg_data_out赋值
always @(*)
begin
case(time_cnt)
4'd0: seg_data_out=4'd1;
4'd1: seg_data_out=4'd2;
4'd2: seg_data_out=4'd3;
4'd3: seg_data_out=4'd4;
4'd4: seg_data_out=4'd5;
4'd5: seg_data_out=4'd6;
default: seg_data_out=4'd1;
endcase
end
endmodule
(3)module Segled
(
//输入端口
CLK_50M,RST_N,seg_data_in,
//输出端口
SEG_EN,SEG_DATA
);
//---------------------------------------------------------------------------
//-- 外部端口声明
//---------------------------------------------------------------------------
input CLK_50M,RST_N; //时钟和复位
input [3:0] seg_data_in; //主控制模块送来的控制信号
output [7:0] SEG_DATA; //输出数据端
output [5:0] SEG_EN; //数码管使能端
//---------------------------------------------------------------------------
//-- 内部端口声明
//---------------------------------------------------------------------------
reg [7:0] data_out; //数据输出
reg [7:0] data_out_n; //数据输出的下一个状态
//数码管显示的数字
parameter SEG_NUM1 = 8'h86, //数字1
SEG_NUM2 = 8'hdb, //数字2
SEG_NUM3 = 8'hcf, //数字3
SEG_NUM4 = 8'he6, //数字4
SEG_NUM5 = 8'hed, //数字5
SEG_NUM6 = 8'hfd; //数字6
//---------------------------------------------------------------------------
//-- 逻辑功能实现
//---------------------------------------------------------------------------
//时序电路,给数码管数据位赋值
always @(posedge CLK_50M,negedge RST_N)
begin
if(!RST_N)
data_out<=8'h0; //初始化
else
data_out<=data_out_n; //下一个状态
end
//组合电路,给data_out_n赋值
always @(*)
begin
case(seg_data_in)
4'd1: data_out_n=SEG_NUM1;
4'd2: data_out_n=SEG_NUM2;
4'd3: data_out_n=SEG_NUM3;
4'd4: data_out_n=SEG_NUM4;
4'd5: data_out_n=SEG_NUM5;
4'd6: data_out_n=SEG_NUM6;
default: data_out_n=SEG_NUM1;
endcase
end
//将data_out赋给SEG_DATA
assign SEG_DATA=data_out;
//数码管使能端说明
assign SEG_EN=6'b011111; //只有最后一个数码管点亮
endmodule
(4)module Key //按键消抖模块
(
//输入端口
CLK_50M,RST_N,KEY,
//输出端口
key_out
);
//---------------------------------------------------------------------------
//-- 外部端口声明
//---------------------------------------------------------------------------
input CLK_50M,RST_N; //时钟和复位
input KEY; //对应开发板上的按键
output key_out; //消抖完成输出按键
//---------------------------------------------------------------------------
//-- 内部端口声明
//---------------------------------------------------------------------------
reg [24:0] time_cnt; //用来计数按键延迟的定时计数器
reg [24:0] time_cnt_n; //time_cnt的下一个状态
reg key_in_r; //用来接收按键信号的寄存器
reg key_out; //消抖完成输出按键
reg key_out_n; //key_out的下一个状态
wire key_press; //检测按键有没有变化
//设置定时器的时间为20ms
parameter SET_TIME_20MS = 25'd1_000_000;
//---------------------------------------------------------------------------
//-- 逻辑功能实现
//---------------------------------------------------------------------------
//时序电路,用来key_in_r寄存器赋值
always @ (posedge CLK_50M, negedge RST_N)
begin
if(!RST_N) //判断复位
key_in_r <= 1'h0; //初始化key_in_r值
else
key_in_r <= KEY; //将按键的值赋值给key_in_r
end
assign key_press = key_in_r ^ KEY; //检测按键有没有变化
//时序电路,用来给time_cnt寄存器赋值
always @ (posedge CLK_50M, negedge RST_N)
begin
if(!RST_N) //判断复位
time_cnt <= 25'h0; //初始化time_cnt值
else
time_cnt <= time_cnt_n; //用来给time_cnt赋值
end
//组合电路,实现20ms的定时计数器
always @ (*)
begin
if(time_cnt == SET_TIME_20MS || key_press) //判断按键有没有变化、时间有没有到
time_cnt_n = 25'h0; //这个地方意思是当按键刚刚出现变化开始计时,计时20ms
else
time_cnt_n = time_cnt + 1'h1;//如果未到20ms或者按键没有变化,那么定时计数器将会继续累加
end
//时序电路,用来key_out寄存器赋值
always @ (posedge CLK_50M, negedge RST_N)
begin
if(!RST_N) //判断复位
key_out <= 1'h0; //初始化key_out值
else
key_out <= key_out_n; //用来给key_out赋值
end
//组合电路,每20ms接收一次按键的值
always @ (*)
begin
if(time_cnt == SET_TIME_20MS) //判断20ms时间
key_out_n = key_in_r; //如果到达20ms,接收一次按键的值
else
key_out_n = 1'h0; //如果未到20ms,保持原状态不变
end
endmodule
(1)module dice //顶层模块
(
CLK_50M,RST_N,KEY,
SEG_DATA,SEG_EN
);
input CLK_50M,RST_N;
input KEY;
output [7:0] SEG_DATA;
output [5:0] SEG_EN;
wire key_out;
wire [3:0] seg_data_out;
Dice_Module dice_module_inst
(
.CLK_50M (CLK_50M),
.RST_N (RST_N),
.key_in (key_out),
.seg_data_out (seg_data_out)
);
Key key_inst
(
.CLK_50M (CLK_50M),
.RST_N (RST_N),
.KEY (KEY),
.key_out (key_out)
);
Segled segled_inst
(
.CLK_50M (CLK_50M),
.RST_N (RST_N),
.seg_data_in (seg_data_out),
.SEG_DATA (SEG_DATA),
.SEG_EN (SEG_EN)
);
endmodule
(2)module Dice_Module //主控制模块
(
CLK_50M,RST_N,key_in,
seg_data_out
);
//---------------------------------------------------------------------------
//-- 外部端口声明
//---------------------------------------------------------------------------
input CLK_50M,RST_N; //时钟和复位
input key_in; //开始和暂停按键
output reg [3:0] seg_data_out; //控制信号
//---------------------------------------------------------------------------
//-- 内部端口声明
//---------------------------------------------------------------------------
reg [3:0] time_cnt; //计数器当前状态
reg [3:0] time_cnt_n; //计数器下一个状态
reg stop_reg; //开始和暂停
reg stop_reg_n; //开始暂停的下一个状态
//设置时间为100ms
parameter TIMESET_100MS=25'd5_000_000;
//---------------------------------------------------------------------------
//-- 逻辑功能实现
//---------------------------------------------------------------------------
//时序电路,用来给stop_reg寄存器赋值
always @(posedge CLK_50M,negedge RST_N)
begin
if(!RST_N) //判断复位
stop_reg<=1'h0; //初始化stop_reg值
else
stop_reg<=stop_reg_n;
end
//组合电路,用于控制数字时钟的暂停与开始
always @(*)
begin
if(key_in)
stop_reg_n=~stop_reg; //当按键按下时,改变stop_reg寄存器的状态
else
stop_reg_n=stop_reg; //当按键没有按下时,stop_reg保持原状态不变
end
//时序电路,六位计数器
always @(posedge CLK_50M,negedge RST_N)
begin
if(!RST_N)
time_cnt<=4'h0; //初始化time_cnt值
else
time_cnt<=time_cnt_n; //用来给time_cnt赋值
end
//组合电路,给time_cnt_n赋值
always @(*)
begin
if(time_cnt==TIMESET_100MS)
time_cnt_n=4'h0; //如果到达100ms,定时计数器将会被清零
else if(stop_reg)
time_cnt_n=time_cnt+4'h1; //如果没有暂停,定时计数器将会继续累加
else
time_cnt_n=time_cnt; //否则,定时计数器将会保持不变
end
//组合电路,给seg_data_out赋值
always @(*)
begin
case(time_cnt)
4'd0: seg_data_out=4'd1;
4'd1: seg_data_out=4'd2;
4'd2: seg_data_out=4'd3;
4'd3: seg_data_out=4'd4;
4'd4: seg_data_out=4'd5;
4'd5: seg_data_out=4'd6;
default: seg_data_out=4'd1;
endcase
end
endmodule
(3)module Segled
(
//输入端口
CLK_50M,RST_N,seg_data_in,
//输出端口
SEG_EN,SEG_DATA
);
//---------------------------------------------------------------------------
//-- 外部端口声明
//---------------------------------------------------------------------------
input CLK_50M,RST_N; //时钟和复位
input [3:0] seg_data_in; //主控制模块送来的控制信号
output [7:0] SEG_DATA; //输出数据端
output [5:0] SEG_EN; //数码管使能端
//---------------------------------------------------------------------------
//-- 内部端口声明
//---------------------------------------------------------------------------
reg [7:0] data_out; //数据输出
reg [7:0] data_out_n; //数据输出的下一个状态
//数码管显示的数字
parameter SEG_NUM1 = 8'h86, //数字1
SEG_NUM2 = 8'hdb, //数字2
SEG_NUM3 = 8'hcf, //数字3
SEG_NUM4 = 8'he6, //数字4
SEG_NUM5 = 8'hed, //数字5
SEG_NUM6 = 8'hfd; //数字6
//---------------------------------------------------------------------------
//-- 逻辑功能实现
//---------------------------------------------------------------------------
//时序电路,给数码管数据位赋值
always @(posedge CLK_50M,negedge RST_N)
begin
if(!RST_N)
data_out<=8'h0; //初始化
else
data_out<=data_out_n; //下一个状态
end
//组合电路,给data_out_n赋值
always @(*)
begin
case(seg_data_in)
4'd1: data_out_n=SEG_NUM1;
4'd2: data_out_n=SEG_NUM2;
4'd3: data_out_n=SEG_NUM3;
4'd4: data_out_n=SEG_NUM4;
4'd5: data_out_n=SEG_NUM5;
4'd6: data_out_n=SEG_NUM6;
default: data_out_n=SEG_NUM1;
endcase
end
//将data_out赋给SEG_DATA
assign SEG_DATA=data_out;
//数码管使能端说明
assign SEG_EN=6'b011111; //只有最后一个数码管点亮
endmodule
(4)module Key //按键消抖模块
(
//输入端口
CLK_50M,RST_N,KEY,
//输出端口
key_out
);
//---------------------------------------------------------------------------
//-- 外部端口声明
//---------------------------------------------------------------------------
input CLK_50M,RST_N; //时钟和复位
input KEY; //对应开发板上的按键
output key_out; //消抖完成输出按键
//---------------------------------------------------------------------------
//-- 内部端口声明
//---------------------------------------------------------------------------
reg [24:0] time_cnt; //用来计数按键延迟的定时计数器
reg [24:0] time_cnt_n; //time_cnt的下一个状态
reg key_in_r; //用来接收按键信号的寄存器
reg key_out; //消抖完成输出按键
reg key_out_n; //key_out的下一个状态
wire key_press; //检测按键有没有变化
//设置定时器的时间为20ms
parameter SET_TIME_20MS = 25'd1_000_000;
//---------------------------------------------------------------------------
//-- 逻辑功能实现
//---------------------------------------------------------------------------
//时序电路,用来key_in_r寄存器赋值
always @ (posedge CLK_50M, negedge RST_N)
begin
if(!RST_N) //判断复位
key_in_r <= 1'h0; //初始化key_in_r值
else
key_in_r <= KEY; //将按键的值赋值给key_in_r
end
assign key_press = key_in_r ^ KEY; //检测按键有没有变化
//时序电路,用来给time_cnt寄存器赋值
always @ (posedge CLK_50M, negedge RST_N)
begin
if(!RST_N) //判断复位
time_cnt <= 25'h0; //初始化time_cnt值
else
time_cnt <= time_cnt_n; //用来给time_cnt赋值
end
//组合电路,实现20ms的定时计数器
always @ (*)
begin
if(time_cnt == SET_TIME_20MS || key_press) //判断按键有没有变化、时间有没有到
time_cnt_n = 25'h0; //这个地方意思是当按键刚刚出现变化开始计时,计时20ms
else
time_cnt_n = time_cnt + 1'h1;//如果未到20ms或者按键没有变化,那么定时计数器将会继续累加
end
//时序电路,用来key_out寄存器赋值
always @ (posedge CLK_50M, negedge RST_N)
begin
if(!RST_N) //判断复位
key_out <= 1'h0; //初始化key_out值
else
key_out <= key_out_n; //用来给key_out赋值
end
//组合电路,每20ms接收一次按键的值
always @ (*)
begin
if(time_cnt == SET_TIME_20MS) //判断20ms时间
key_out_n = key_in_r; //如果到达20ms,接收一次按键的值
else
key_out_n = 1'h0; //如果未到20ms,保持原状态不变
end
endmodule