一、顶层文件
module test(
input wire sys_clk,
input wire sys_rst,
input wire [3:0]key_in,
output reg [7:0]led,
output wire scl,
inout wire sda,//i2c的信号
output wire [7:0]sel,
output wire [7:0]seg//数码管的驱动
);
wire [23:0] data ;
reg [31:0] dsp_data;
reg [23:0] bcd;
wire S1_debounce,S1_debounce_reg;
wire S2_debounce,S2_debounce_reg;
wire S3_debounce,S3_debounce_reg;
localparam KEY1_STATE1=2'b00;//停止状态
localparam KEY1_STATE2=2'b01;//启动状态
localparam KEY2_STATE1=2'b00;
localparam KEY2_STATE2=2'b01;
reg [1:0] key1_state;//当前状态
reg [1:0] key2_state;//当前状态
//显示eeprom读取的数据
always @(posedge sys_clk or negedge sys_rst)begin
if(!sys_rst)begin
dsp_data <={4'd11,4'd10,4'd10,4'd10,4'd10,4'd10,4'd10,4'd10};//初始值,表示没有效数字时钟的显示
led <=8'b11111111;
end else begin
if(S1_debounce_reg&&!S1_debounce)begin
led[0]<=~led[0];
end
bcd[7:4]<=data[7:0]/10;
bcd[3:0]<=data[7:0]%10;
bcd[11:8]<=data[15:8]%10;
bcd[15:12]<=data[15:8]/10;
bcd[19:16]<=data[23:16]%10;
bcd[23:20]<=data[23:16]/10;
dsp_data<={4'd11,bcd[23:16],4'd10,bcd[15:8],4'd10,bcd[7:4]};
end
end
//按键一的状态
always @(posedge sys_clk or negedge sys_rst)begin
if(!sys_rst)begin
key1_state<=KEY1_STATE1;
end else begin
if(S1_debounce_reg&&!S1_debounce) begin
key1_state <= (key1_state ==KEY1_STATE1) ? KEY1_STATE2:KEY1_STATE1;
end
end
end
//检测按键二的状态
always @(posedge sys_clk or negedge sys_rst)begin
if(!sys_rst)begin
key2_state<=KEY2_STATE1;
end else begin
if(S2_debounce_reg&&!S2_debounce) begin
key2_state <= (key2_state ==KEY2_STATE1) ? KEY2_STATE2:KEY2_STATE1;
end
end
end
wire [23:0] rd_data;
wire rd_data_vld;
//reg define
reg [23:0] wr_data;
reg wr_req;
reg rd_req=0;
//检测写入EEPROM的条件
always @(posedge sys_clk or negedge sys_rst)begin
if(!sys_rst)begin
wr_req<=1'b0;
end
else if({key1_state==KEY1_STATE2&&(S1_debounce_reg&&!S1_debounce)}||{key1_state==KEY1_STATE1&&(S2_debounce_reg && !S2_debounce)})begin
wr_data <=data;
wr_req <=1'b1;
end
else
wr_req<=1'b0;
end
reg [3:0] state=0;
reg [15:0] debounce_couter=0;//去抖计数器
reg [15:0] debounce_couter2=0;//去抖计数器
//上电读取eeprom的数据
always @(posedge sys_clk or negedge sys_rst)begin
if(!sys_rst) begin
state <=0;
rd_req<=0;
debounce_couter <=16'b0;
end else begin
case(state)
0:begin
//状态0:等待读取开始
state<=1;
end
1:begin
//状态1;从EEprom读取数据
rd_req<=1;
if(debounce_couter<=16'hFFFF)
debounce_couter <=debounce_couter+1;
else
state <=2;
end
2:begin
//状态2:数据加载完毕
//进一步处理逻辑
rd_req<=0;
debounce_couter<=16'b0;
end
default:state <=0;
endcase
end
end
//eeprom module
eeprom inst_eeprom(
.clk(sys_clk),
.rst(sys_rst),
.wr_req(wr_req),
.rd_req((~key_in[2])||rd_req),//read data from EEProm
.device_id(),
.reg_addr(8'h03),
.reg_addr_vld(1'b1),
.wr_data(wr_data),
.wr_data_vld(wr_req),
.rd_data(rd_data),
.rd_data_vld(rd_data_vld),
.ready(),
.scl(scl),
.sda(sda)
);
//按键模块
key debounce_L1(
.sys_clk(sys_clk),
.rst(sys_rst),
.key_in(key_in[0]),
.S_debounce(S1_debounce),
.S_debounce_reg(S1_debounce_reg)
);
key debounce_L2(
.sys_clk(sys_clk),
.rst(sys_rst),
.key_in(key_in[1]),
.S_debounce(S2_debounce),
.S_debounce_reg(S2_debounce_reg)
);
key debounce_L3(
.sys_clk(sys_clk),
.rst(sys_rst),
.key_in(key_in[2]),
.S_debounce(S3_debounce),
.S_debounce_reg(S3_debounce_reg)
);
//时间计数模块
counter_time u_couter_time(
.clk(sys_clk),
.rst_n(sys_rst),
.key_in1(S1_debounce_reg &&!S1_debounce),
.key_in2(S2_debounce_reg &&!S2_debounce),
.key_in3(S3_debounce_reg &&!S3_debounce),
.rd_req(rd_req),
.rd_data(rd_data),
.din_out(data)
);
//数码管显示模块
segdisplay segdisplay_inst(
.clk(sys_clk),
.rst(sys_rst),
.dsp_data(dsp_data),
.seg(seg),
.sel(sel)
);
endmodule
二、数码管驱动
module segdisplay
(
input wire clk ,
input wire rst ,
input wire [31:0] dsp_data ,
output reg [7:0] seg ,//段选端
output reg [7:0] sel //位选段
);
localparam [7:0] DIGIT0 =8'b1100_0000 ;//16精制C0
localparam [7:0] DIGIT1 =8'b1111_1001 ;//F9
localparam [7:0] DIGIT2 =8'b1010_0100;//A4
localparam [7:0] DIGIT3 =8'b1011_0000;//B0
localparam [7:0] DIGIT4 =8'b1001_1001;//99
localparam [7:0] DIGIT5 =8'b1001_0010;//92
localparam [7:0] DIGIT6 =8'b1000_0010;//82
localparam [7:0] DIGIT7 =8'b1111_1000;//F8
localparam [7:0] DIGIT8 =8'b1000_0000;//80
localparam [7:0] DIGIT9 =8'b1001_0000 ;//90
localparam [7:0] DIGITX =8'b1011_1111 ;//
localparam [7:0] DIGOFF =8'b1111_1111 ;//FF
localparam [7:0] DIGITC =8'hC6 ;
localparam DSP_COUNT = 20'