FPGA 数字 跑表
开发板:minifpga,六个数码管,动态扫描
两路跑表,中间空两格,计数范围0-99,可分别控制暂停或开始
计数至99后停止计数,全局复位归零。
module DFF_SW(clk, in, out);//D触发器模块
parameter n=5;
input clk;
input [n-1:0] in;
output [n-1:0] out;
reg [n-1:0] out;
always @(posedge clk) out = in ;
endmodule
module Counter(clk, rst, in0,in1, count0,count1,Light0,Light1) ;//计数器模块,in循环控制暂停开始
parameter n=5 ;
input rst, clk ,in0,in1;
output [n-1:0] count0,count1 ;
output Light0,Light1;
reg [n-1:0] next0,next1 ;
always@(*)
begin
if (count0>=99)//计数器计数范围为0-99,记到99时停止计数
next0= rst? 0 : count0;
else//rst复位信号有效,计数清零。in输入高电平时暂停,in变低后继续计数。
next0= rst? 0 : (in0? count0 : count0+ 1'b1 );
end
assign Light0=rst|in0;//清零或暂停时LED亮起以做提示。
always@(*)
begin
if (count1>=99)//计数器计数范围为0-99,记到99时停止计数
next1= rst? 0 : count1;
else//rst复位信号有效,计数清零。in输入高电平时暂停,in变低后继续计数。
next1= rst? 0 : (in1? count1 : count1+ 1'b1 );
end
assign Light1=rst|in1;//清零或暂停时LED亮起以做提示。
DFF_SW #(n) cnt0(clk, next0, count0) ; //第一路路表
DFF_SW #(n) cnt1(clk, next1, count1) ; //第二路跑表
endmodule
module div(clock_in,clock_out);//时钟分频模块
input clock_in;
output clock_out;
reg clk_p_r;
reg clk_n_r;
reg [F_DIV_WIDTH-1:0] count_p;
reg [F_DIV_WIDTH-1:0] count_n;
parameter F_DIV=48000000;//分频参数设置,因为开发板时钟为50MHz,当此值为50000000时,可得1Hz频率
parameter F_DIV_WIDTH=32;//
wire full_div_p;
wire half_div_p;
wire full_div_n;
wire half_div_n;
assign full_div_p = (count_p<F_DIV-1);
assign half_div_p = (count_p<(F_DIV>>1)-1);
assign full_div_n = (count_p<F_DIV-1);
assign half_div_n = (count_p<(F_DIV>>1)-1);
assign clock_out = (F_DIV==1)? clock_in:(F_DIV[0]? (clk_p_r&clk_n_r):clk_p_r);
always @(posedge clock_in)
begin
if(full_div_p)
begin
count_p=count_p+1'b1;
if(half_div_p)
clk_p_r=1'b0;
else
clk_p_r=1'b1;
end
else
begin
count_p=0;
clk_p_r=1'b0;
end
end
always@(negedge clock_in)
begin
if(full_div_n)
begin
count_n=count_n+1'b1;
if(half_div_n)
clk_n_r=1'b0;
else
clk_n_r=1'b1;
end
else
begin
count_n=0;
clk_n_r=1'b0;
end
end
endmodule
module disp_dec_SW(hex,dispout);//将八位的输入信号转化为两位十进制的七段译码输出,前
//八位接一个数码管显示十位,后八位接一个数码管显示个位
input [7:0] hex;
output [15:0] dispout;
reg [7:0] dec;
always@(hex)//将8位二进制数转化为2位BCD码
begin
dec[7:4]=hex/4'd10;
dec[3:0]=hex%4'd10;
end
dual_hex_SW u1(dec, dispout);//调用2位七段显示模块
endmodule
module dual_hex_SW(datain,dispout);//2位七段显示模块
input [7:0] datain;
output [15:0] dispout;
seg_decoder_SW u1(datain[7:4],dispout[15:8]);//十位
seg_decoder_SW u2(datain[3:0],dispout[7:0]);//个位
endmodule
module seg_decoder_SW (iA,oY);//一位七段译码模块Q
input [3:0] iA;
output reg [7:0] oY;
always@(iA)
begin
case(iA)
4'b0000:oY=8'h3f;//“0”
4'b0001:oY=8'h06;//“1”
4'b0010:oY=8'h5b;//“2”
4'b0011:oY=8'h4f;//“3”
4'b0100:oY=8'h66;//“4”
4'b0101:oY=8'h6d;//“5”
4'b0110:oY=8'h7d;//“6”
4'b0111:oY=8'h27;//“7”
4'b1000:oY=8'h7f;//“8”
4'b1001:oY=8'h6f;//“9”
4'b1010:oY=8'h77;//“a”
4'b1011:oY=8'h7c;//“b”
4'b1100:oY=8'h58;//“c”
4'b1101:oY=8'h5e;//“d”
4'b1110:oY=8'h79;//“e”
4'b1111:oY=8'h71;//“f”
endcase
end
endmodule
module Display(clk,rst,in1,in0,DigtronCS_out,Digtron_out);//扫描驱动模块
input clk,rst;
input [15:0] in1,in0;
output [7:0] Digtron_out;
output [5:0] DigtronCS_out;
parameter Timex=8'd200;//设置扫描频率为250kHz
reg [7:0] Digtron_out;
reg [5:0] DigtronCS_out;
reg [7:0] Count;
initial
DigtronCS_out=6'b111110;
always@(posedge clk)
begin
if(Count ==Timex)
begin
Count <=8'd0;
if(DigtronCS_out==6'b111101)//循环到中间两个数码管时跳过--
DigtronCS_out=6'b101111;//--使其片选信号始终为高,作为间隔始终不显示
else
DigtronCS_out<={DigtronCS_out[4:0],DigtronCS_out[5]}; //扫描片选状态循环
end
else
begin
Count =Count +1'b1;
DigtronCS_out<=DigtronCS_out;
end
end
always@(posedge clk)
begin
case (DigtronCS_out)
6'b111110:Digtron_out=in0[7:0];
6'b111101:Digtron_out=in0[15:8];
6'b101111:Digtron_out=in1[7:0];
6'b011111:Digtron_out=in1[15:8];
endcase
end
endmodule
顶层模块
module Stopwatch (clk,rst,in0,in1,DigtronCS_out,Digtron_out,Light0,Light1);
input clk, rst,in0,in1;
output [7:0] Digtron_out;
output [5:0] DigtronCS_out;
output Light0,Light1;
wire [7:0] o0,o1,count0,count1;
wire [15:0]o0_dis,o1_dis;
wire clk_1Hz;
assign o0=count0;
assign o1=count1;
div #(50000000,32) nclk1(clk,clk_1Hz);
Counter #(8) cnt(clk_1Hz, rst, in0,in1, count0,count1,Light0,Light1);
disp_dec_SW SW0(o0,o0_dis);
disp_dec_SW SW1(o1,o1_dis);
Display b1(clk,rst,o1_dis,o0_dis,DigtronCS_out,Digtron_out);
endmodule