今天尝试了FPGA的数码管实现。
具体功能是通过动态显示在8位数码管上显示从0开始,每秒增1的8位数字。
由于一开始没有看开发板的资料,没有注意到数码管是共阴还是共阳,想当然的写成了共阴极的代码。
然后就一直调试,一直不成功。
后来通过查看开发板自带程序发现是共阳极的,遂正确。
FPGA的verilog实现几乎都是并行,每个always的代码块都是并行运算,但可以通过设置always的敏感变量来控制相对应always块的执行顺序。
以下是verilog代码,说来惭愧,代码风格一直很臃肿,要努力改改。
module leds(
clk, //50Mhz时钟
rst_n, //低电平复位
seg, //段选信号
bit //位选信号
);
input clk;
input rst_n;
output[7:0] seg;
output[7:0] bit;
reg[7:0] seg;
reg[7:0] bit;
reg[3:0] dis_seg; //段选辅助寄存器
reg[25:0] cnt_1s; //计时1s
reg[15:0] cnt_1ms; //计时1ms
reg[31:0] display; //显示的数字
//==========the 1s gap====================
always@(posedge clk or negedge rst_n)
if(!rst_n)
cnt_1s <= 26'd0;
else if(cnt_1s >= 26'd49_999_999)
cnt_1s <= 26'd0;
else
cnt_1s <= cnt_1s + 26'b1;
//==========the 1ms gap ===================
always@(posedge clk or negedge rst_n)
if(!rst_n)
cnt_1ms <= 26'd0;
else if(cnt_1ms >= 16'd50000)
cnt_1ms <= 16'd0;
else
cnt_1ms <= cnt_1ms + 16'b1;
//============显示数増一,位选循环=============
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
display <= 32'd0;
else if(cnt_1s >= 26'd49_999_999)
display <= display + 32'd1;
else
display <= display;
if(!rst_n)
bit <= 8'b11111110;
else if(cnt_1ms >= 16'd50000)
bit <= {bit[6:0],bit[7]};
else
bit <= bit;
end
//==========位选显示==========================
always@(bit)
begin
case(bit)
8'b11111110 : dis_seg <= display[3:0];
8'b11111101 : dis_seg <= display[7:4];
8'b11111011 : dis_seg <= display[11:8];
8'b11110111 : dis_seg <= display[15:12];
8'b11101111 : dis_seg <= display[19:16];
8'b11011111 : dis_seg <= display[23:20];
8'b10111111 : dis_seg <= display[27:24];
8'b01111111 : dis_seg <= display[31:28];
default : dis_seg <= dis_seg;
endcase
end
//========片选显示===========================
always@(dis_seg)
begin
case(dis_seg)
4'h0 : seg <= 8'hc0; // "0"
4'h1 : seg <= 8'hf9; // "1"
4'h2 : seg <= 8'ha4; // "2"
4'h3 : seg <= 8'hb0; // "3"
4'h4 : seg <= 8'h99; // "4"
4'h5 : seg <= 8'h92; // "5"
4'h6 : seg <= 8'h82; // "6"
4'h7 : seg <= 8'hf8; // "7"
4'h8 : seg <= 8'h80; // "8"
4'h9 : seg <= 8'h90; // "9"
4'ha : seg <= 8'h88; // "a"
4'hb : seg <= 8'h83; // "b"
4'hc : seg <= 8'hc6; // "c"
4'hd : seg <= 8'ha1; // "d"
4'he : seg <= 8'h86; // "e"
4'hf : seg <= 8'h8e; // "f"
default : seg <= seg;
endcase
end
initial
begin
display <= 32'd0;
dis_seg <= 4'd0;
bit <= 8'b11111110;
end
endmodule