本帖最后由 littleshrimp 于 2021-12-18 15:52 编辑
功能类似商场那种“按到10秒送金条”活动的计数器, 因为没有按键就用开关替代,建议厂家在板子上放一个按键。功能为开关拨到上边时开始计数,拨到下边时停止计数并显示当前数值。
代码是我自己写的,数码管的段选使用了@怀揣少年梦的数据 ,https://bbs.eeworld.com.cn/thread-1189456-1-1.html。
因为我是FPGA新手,功能可以实现,但不知道设计的是否合理。有FPGA高手发现问题还希望多多指教,工程文件在本文底部。
在添加注释时还发现了一个问题,综合时提示类似”ERROR (EX3863) : Syntax error near '<='("C:\Users\lu\Documents\fpga_project_3\src\top.v":34)“这样的错误,但是代码里我没找到问题。
后来发现只要去掉这条注释就可以正常工作,或者把注释和代码中间空一行也可以正常工作,在我看来这是一个比较奇怪的现象,目前没法解释。感兴趣的网友可以帮忙分析分析。
部分代码:
module top(
input clk, //50MHz时钟输入
input sw, //开关输入
output reg[7:0]seg, //数码管输出
output reg[3:0]sel //数码管位选
);
wire cnt_clk; //计数时钟
wire rfs_clk; //刷新时钟
reg[1:0] bcd_index = 2'b0; //计数位选(0=个位...3=千位)
wire[3:0] bcd_out; //指定位的数值(0~9)
reg[18:0] cnt = 19'b0; //计数
reg [3:0] bcd[0:3]; //要输出的数位数组,[0=个位...3=千位][0~9]
//判断开关状态,决定是否更新计数
always@(posedge clk) begin
if(sw)begin
bcd[bcd_index] = bcd_out;
end
end
//cnt计数
always@(posedge clk) begin
if(cnt == 50_000 - 1)
cnt <= 19'b0;
else
cnt <= cnt + 1'b1;
end
//根据cnt计数更新位选索引
always@(posedge clk) begin
if(cnt == 0)
bcd_index <= bcd_index + 1'b1;
end
//根据位选索引控制对应的数据管位选引脚,低电平为选中
always@(posedge clk) begin
case(bcd_index)
4'd0:sel <= ~4'b0001;
4'd1:sel <= ~4'b0010;
4'd2:sel <= ~4'b0100;
4'd3:sel <= ~4'b1000;
endcase
end
//将bcd值转换成对应的数码管段的控制数据
always@(posedge clk) begin
case(bcd[bcd_index])
4'd0:seg = 8'hc0;
4'd1:seg = 8'hf9;
4'd2:seg = 8'ha4;
4'd3:seg = 8'hb0;
4'd4:seg = 8'h99;
4'd5:seg = 8'h92;
4'd6:seg = 8'h82;
4'd7:seg = 8'hf8;
4'd8:seg = 8'h80;
4'd9:seg = 8'h90;
default:seg = 8'hc0;
endcase
end
//时钟分频
clk_div clk_div_ins(
.clk(clk),
.clk1(cnt_clk),
.clk2(rfs_clk)
);
//4位bcd计数,cnt_clk是计数时钟,rfs_clk时钟决定输出bcd_index对应数位的数值
bcd4 bcd4_ins(
.cnt_clk(cnt_clk),
.read_clk(rfs_clk),
.bit_index(bcd_index),
.bcd_out(bcd_out)
);
endmodule
工程文件:
fpga_project_3.rar
(105.75 KB, 下载次数: 0)
|