一、顶层文件
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)beginif(!sys_rst)begindsp_data <={4'd11,4'd10,4'd10,4'd10,4'd10,4'd10,4'd10,4'd10};//初始值,表示没有效数字时钟的显示led <=8'b11111111;end else beginif(S1_debounce_reg&&!S1_debounce)beginled[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)beginif(!sys_rst)begin key1_state<=KEY1_STATE1;end else beginif(S1_debounce_reg&&!S1_debounce) beginkey1_state <= (key1_state ==KEY1_STATE1) ? KEY1_STATE2:KEY1_STATE1;endend
end
//检测按键二的状态
always @(posedge sys_clk or negedge sys_rst)beginif(!sys_rst)begin key2_state<=KEY2_STATE1;end else beginif(S2_debounce_reg&&!S2_debounce) beginkey2_state <= (key2_state ==KEY2_STATE1) ? KEY2_STATE2:KEY2_STATE1;endend
endwire [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)beginif(!sys_rst)beginwr_req<=1'b0;end else if({key1_state==KEY1_STATE2&&(S1_debounce_reg&&!S1_debounce)}||{key1_state==KEY1_STATE1&&(S2_debounce_reg && !S2_debounce)})beginwr_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)beginif(!sys_rst) beginstate <=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;elsestate <=2;end2:begin//状态2:数据加载完毕//进一步处理逻辑rd_req<=0;debounce_couter<=16'b0;end default:state <=0;endcaseend
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'd50000; //reg [19:0] dsp_count ;
reg [3:0] bits ;
reg [3:0] bcd ;//1ms的计数器
always @(posedge clk or negedge rst)begin if(!rst)dsp_count <= 20'd0;else begin if (dsp_count == DSP_COUNT-1) begin dsp_count <= 20'd0;end else dsp_count <= dsp_count + 20'd1;end
end
//位选端
always @(posedge clk or negedge rst) begin if(!rst)beginsel <= 8'b1111_1111;bits <=4'd0;end else begin if(dsp_count==DSP_COUNT-1)begin//每一毫秒更新一次if(bits==4'd8)bits <=4'd0;elsebits<=bits+4'd1;case(bits)4'd0: begin sel<=8'b1111_1110;bcd<=dsp_data[31:28] ;end4'd1: begin sel<=8'b1111_1101;bcd<=dsp_data[27:24] ;end4'd2: begin sel<=8'b1111_1011;bcd<=dsp_data[23:20] ;end4'd3: begin sel<=8'b1111_0111;bcd<=dsp_data[19:16] ;end4'd4: begin sel<=8'b1110_1111;bcd<=dsp_data[15:12] ;end4'd5: begin sel<=8'b1101_1111;bcd<=dsp_data[11:8] ;end4'd6: begin sel<=8'b1011_1111;bcd<=dsp_data[7:4] ;end4'd7: begin sel<=8'b0111_1111;bcd<=dsp_data[3:0] ;enddefault:sel<=8'b1111_1111;endcaseend end
end
//段选端
always @(posedge clk or negedge rst)beginif(!rst)seg<=DIGOFF;else begin case(bcd)4'd0: seg<=DIGIT0;4'd1: seg<=DIGIT1;4'd2: seg<=DIGIT2;4'd3: seg<=DIGIT3;4'd4: seg<=DIGIT4;4'd5: seg<=DIGIT5;4'd6: seg<=DIGIT6;4'd7: seg<=DIGIT7;4'd8: seg<=DIGIT8;4'd9: seg<=DIGIT9;4'd10:seg<=8'b1011_1111;//-4'd11:seg<=8'b1000_1100;//pdefault: seg<=DIGOFF;endcaseend
end
endmodule
三、按键驱动
module key(input wire sys_clk,input wire rst,input wire [0:0] key_in,//按键输入信号,假设最多支持4个按键output reg [0:0] S_debounce,//去抖后的按键输出output reg [0:0] S_debounce_reg //去抖的寄存器输出
);reg [15:0] debounce_counter;//去抖计数器//按键去抖模块
always @(posedge sys_clk or negedge rst)beginif(!rst)beginS_debounce<=0;S_debounce_reg<=0;debounce_counter<=16'b0;end else begin//针对每个按键经行去抖if(key_in==1'b0)begin//按键按下if(debounce_counter< 16'hFFFF)debounce_counter<=debounce_counter+1;elseS_debounce_reg<=1'b1;//该按键去抖确认按下end else begindebounce_counter<=16'b0;S_debounce_reg<=1'b0;//按键松开endend//更新去抖后的按键输出S_debounce <=S_debounce_reg;end
endmodule
四、计数器模块
module counter_time(
input wire clk,
input wire rst_n,
input wire key_in1,//消抖后的脉冲信号,高有效
input wire key_in2,//消抖后的脉冲信号,高有效
input wire key_in3,//消抖后的脉冲信号,高有效
input wire [23:0]rd_data,
input wire rd_req,
output wire [23:0]din_out//输出当前计数值
);parameter MAX_1MS=16'd49_999;//1ms
parameter MAX_1S=10'd999;//1ms*1000=1s
parameter MAX_1MIN=6'd59;//1s*60=1min
parameter MAX_1H=6'd59;//1min*60=1hreg flag;//开始、暂停结束信号
reg [15:0]cnt_1ms;
wire add_cnt_1ms;
wire end_cnt_1ms;reg [9:0]cnt_1s;
wire add_cnt_1s;
wire end_cnt_1s;reg [5:0]cnt_1min;
wire add_cnt_1min;
wire end_cnt_1min;reg [5:0]cnt_1h;
wire add_cnt_1h;
wire end_cnt_1h;reg [7:0] data_min;//保存此时有多少分钟
reg [7:0] data_s;//保存此时有多少秒
reg [7:0] data_ms;//保存此时有多少毫秒,只取高两位//flag
always @(posedge clk or negedge rst_n)beginif(!rst_n)beginflag<=1'b0;endelse if(key_in1) beginflag<=~flag;endelse beginflag<=flag;endend
//1ms计数器
always @(posedge clk or negedge rst_n or posedge key_in2) beginif(!rst_n||key_in2)begincnt_1ms<=16'd0;end else if(add_cnt_1ms)beginif(end_cnt_1ms)begincnt_1ms<=16'd0;end else begincnt_1ms<=cnt_1ms+1'b1;endend
end assign add_cnt_1ms=flag;
assign end_cnt_1ms=add_cnt_1ms&&{cnt_1ms==MAX_1MS};//1S计数器
always @(posedge clk or negedge rst_n ) beginif(!rst_n)begincnt_1s<=10'd0;end else if(key_in3||rd_req)begincnt_1s<=rd_data[7:0]*10;endelse if(key_in2)begincnt_1s<=0;endelse if(add_cnt_1s)beginif(end_cnt_1s)begincnt_1s<=10'd0;endelse begincnt_1s<=cnt_1s+1'b1;endend
end assign add_cnt_1s=end_cnt_1ms;
assign end_cnt_1s=add_cnt_1s&&cnt_1s==MAX_1S;//1min计数器
always @(posedge clk or negedge rst_n or posedge key_in2) beginif(!rst_n||key_in2)begincnt_1min<=6'd0;end else if(key_in3||rd_req)begincnt_1min<=rd_data[23:16];endelse if(add_cnt_1min)beginif(end_cnt_1min)begincnt_1min<=6'd0;endelse begincnt_1min<=cnt_1min+1'b1;endend
end assign add_cnt_1min=end_cnt_1s;
assign end_cnt_1min=add_cnt_1min&&cnt_1s==MAX_1MIN;
//1H计数器
always @(posedge clk or negedge rst_n or posedge key_in2) beginif(!rst_n||key_in2)begincnt_1h<=6'd0;end else if(key_in3||rd_req)begincnt_1h<=rd_data[15:8];endelse if(add_cnt_1h)beginif(end_cnt_1h)begincnt_1h<=6'd0;endelse begincnt_1h<=cnt_1h+1'b1;endend
end assign add_cnt_1h=end_cnt_1min;
assign end_cnt_1h=add_cnt_1h&&cnt_1h==MAX_1H;//数据输出
always @(posedge clk or negedge rst_n)begin if(!rst_n)begindata_min<=8'd3;data_s<=8'd7;data_ms<=8'd2;
end
else
begindata_min<=cnt_1h;data_s<=cnt_1min;data_ms<=cnt_1s/10;end
end
assign din_out={data_min,data_s,data_ms};
endmodule
五、I2C驱动
module i2c( input clk ,input rst ,input [7:0] wr_data ,input [4:0] cmd ,input cmd_vld ,output [7:0] rd_data ,output rd_data_vld ,output reg rev_ack ,output done ,output reg scl ,inout sda
);//para define
localparam IDLE = 7'b0000001,START = 7'b0000010,WR_DATA = 7'b0000100,RD_DATA = 7'b0001000,R_ACK = 7'b0010000,T_ACK = 7'b0100000,STOP = 7'b1000000;
parameter T = 100_000,SCL_MAX = 50_000_000 / T;
parameter SCL_LOW_HALF = (SCL_MAX * 1 / 4) - 1,SCL_HIGH_HALF = (SCL_MAX * 3 / 4) - 1;
`define START_BIT 5'b00001
`define WRITE_BIT 5'b00010
`define READ_BIT 5'b00100
`define STOP_BIT 5'b01000
`define ACK_BIT 5'b10000
`define ACK 0
`define NO_ACK 1//reg define
reg [6:0] cstate ;
reg [6:0] nstate ;
reg [4:0] cmd_r ;
reg [7:0] wr_data_r ;
reg [7:0] rd_data_r ;
reg sda_out ;
reg OE ;
reg [8:0] cnt_bit ;
reg [3:0] num ;
reg [3:0] cnt_num ;//wire define
wire sda_in ;
wire add_cnt_bit ;
wire end_cnt_bit ;
wire add_cnt_num ;
wire end_cnt_num ;
wire IDLE_START ;
wire START_WR_DATA ;
wire WR_DATA_R_ACK ;
wire R_ACK_IDLE ;
wire IDLE_WR_DATA ;
wire R_ACK_STOP ;
wire STOP_IDLE ; wire IDLE_RD_DATA ;
wire RD_DATA_T_ACK ;
wire T_ACK_IDLE ;
wire T_ACK_STOP ;assign add_cnt_bit = cstate != IDLE;
assign end_cnt_bit = add_cnt_bit && cnt_bit == SCL_MAX - 1'd1;
assign add_cnt_num = end_cnt_bit;
assign end_cnt_num = add_cnt_num && cnt_num == num - 1;assign IDLE_START = (cstate == IDLE) && cmd_vld && (cmd & `START_BIT) ;
assign START_WR_DATA = (cstate == START) && end_cnt_num && (cmd_r & `WRITE_BIT) ;
assign WR_DATA_R_ACK = (cstate == WR_DATA) && end_cnt_num ;
assign R_ACK_IDLE = (cstate == R_ACK) && end_cnt_num && !(cmd_r & `STOP_BIT) ;
assign IDLE_WR_DATA = (cstate == IDLE) && cmd_vld && (cmd & `WRITE_BIT) ;
assign R_ACK_STOP = (cstate == R_ACK) && end_cnt_num && (cmd_r & `STOP_BIT) ;
assign STOP_IDLE = (cstate == STOP) && end_cnt_num ;
assign IDLE_RD_DATA = (cstate == IDLE) && cmd_vld && (cmd & `READ_BIT) ;
assign RD_DATA_T_ACK = (cstate == RD_DATA) && end_cnt_num ;
assign T_ACK_IDLE = (cstate == T_ACK) && end_cnt_num && !(cmd_r & `STOP_BIT) ;
assign T_ACK_STOP = (cstate == T_ACK) && end_cnt_num && (cmd_r & `STOP_BIT) ;assign sda = OE ? sda_out : 1'bz;
assign sda_in = sda;
assign done = R_ACK_IDLE || T_ACK_IDLE || STOP_IDLE;
assign rd_data = rd_data_r;
assign rd_data_vld = T_ACK_IDLE || T_ACK_STOP;//
always @(posedge clk or negedge rst) beginif (!rst) beginwr_data_r <= 'd0;cmd_r <= 'd0;endelse if (cmd_vld) beginwr_data_r <= wr_data;cmd_r <= cmd;end
end//
always @(posedge clk or negedge rst) begin if(!rst)begincnt_bit <= 'd0;end else if(add_cnt_bit)begin if(end_cnt_bit)begin cnt_bit <= 'd0;endelse begin cnt_bit <= cnt_bit + 1'd1;end end
end //IIC_SCL
always @(posedge clk or negedge rst) beginif (!rst) beginscl <= 'd1;endelse if (cnt_bit == (SCL_MAX - 1 ) >> 1 || STOP_IDLE) beginscl <= 'd1;endelse if (end_cnt_bit) beginscl <= 'd0;end
end//
always @(posedge clk or negedge rst)begin if(!rst)begincnt_num <= 'd0;end else if(add_cnt_num)begin if(end_cnt_num)begin cnt_num <= 'd0;endelse begin cnt_num <= cnt_num + 1'd1;end end
end //
always @(*) begincase (cstate)IDLE : num = 1;START : num = 1;WR_DATA : num = 8;RD_DATA : num = 8;R_ACK : num = 1;T_ACK : num = 1;STOP : num = 1;default : num = 1;endcase
end//
always @(posedge clk or negedge rst)begin if(!rst)begincstate <= IDLE;end else begin cstate <= nstate;end
end//
always @(*) begincase(cstate)IDLE : beginif (IDLE_START) beginnstate = START;endelse if (IDLE_WR_DATA) beginnstate = WR_DATA;endelse if (IDLE_RD_DATA) beginnstate = RD_DATA;endelse beginnstate = cstate;endend START : beginif (START_WR_DATA) beginnstate = WR_DATA;endelse beginnstate = cstate;endend WR_DATA : beginif (WR_DATA_R_ACK) beginnstate = R_ACK;endelse beginnstate = cstate;endend RD_DATA : beginif (RD_DATA_T_ACK) beginnstate = T_ACK;endelse beginnstate = cstate;endend R_ACK : beginif (R_ACK_STOP) beginnstate = STOP;endelse if (R_ACK_IDLE) beginnstate = IDLE;endelse beginnstate = cstate;endend T_ACK : beginif (T_ACK_STOP) beginnstate = STOP;endelse if (T_ACK_IDLE) beginnstate = IDLE;endelse beginnstate = cstate;endend STOP : beginif (STOP_IDLE) beginnstate = IDLE;endelse beginnstate = cstate;endend default : nstate = cstate;endcase
end//
always @(posedge clk or negedge rst) beginif (!rst) beginOE <= 'b0;end else if (IDLE_START || START_WR_DATA || IDLE_WR_DATA || R_ACK_STOP || RD_DATA_T_ACK) beginOE <= 'b1;end else if (IDLE_RD_DATA || WR_DATA_R_ACK || STOP_IDLE) beginOE <= 'b0;end
end//
always @(posedge clk or negedge rst) beginif (!rst) beginsda_out <= 1;endelse begincase (cstate)IDLE :sda_out <= 1;START :beginif (cnt_bit == SCL_LOW_HALF) beginsda_out <= 'b1;endelse if (cnt_bit == SCL_HIGH_HALF) beginsda_out <= 'b0;endendWR_DATA :beginif (cnt_bit == SCL_LOW_HALF) beginsda_out <= wr_data_r[7 - cnt_num];endendT_ACK :beginif (cnt_bit == SCL_LOW_HALF) beginif (cmd & `ACK_BIT) beginsda_out <= `NO_ACK;endelse beginsda_out <= `ACK;endendendSTOP :beginif (cnt_bit == SCL_LOW_HALF) beginsda_out <= 'b0;endelse if (cnt_bit == SCL_HIGH_HALF) beginsda_out <= 'b1;endenddefault: sda_out <= 'b1;endcaseend
end//
always @(posedge clk or negedge rst) beginif (!rst) beginrev_ack <= 0;rd_data_r <= 8'b0;endelse begincase (cstate)RD_DATA:beginif (cnt_bit == SCL_HIGH_HALF) beginrd_data_r[7-cnt_num] <= sda_in;endendR_ACK :beginif (cnt_bit == SCL_HIGH_HALF) beginrev_ack <= sda_in;endenddefault:; endcaseend
endendmodule
六、eeprom模块
module eeprom ( input wire clk ,input wire rst ,input wire wr_req ,input wire rd_req ,input wire [6:0] device_id ,input wire [7:0] reg_addr ,input wire reg_addr_vld,input wire [7:0] wr_data ,input wire wr_data_vld ,output wire [7:0] rd_data ,output wire rd_data_vld ,output wire ready ,output wire scl ,inout wire sda
); //para define
`define START_BIT 5'b00001
`define WRITE_BIT 5'b00010
`define READ_BIT 5'b00100
`define STOP_BIT 5'b01000
`define ACK_BIT 5'b10000
localparam IDLE = 6'b000001,WR_REQ = 6'b000010,WR_WAIT = 6'b000100,RD_REQ = 6'b001000,RD_WAIT = 6'b010000,DONE = 6'b100000;localparam WR_CTRL_BYTE = 8'b1010_0000;
localparam RD_CTRL_BYTE = 8'b1010_0001;//wire define
wire IDLE_WR_REQ ;
wire IDLE_RD_REQ ;
wire WR_REQ_WR_WAIT ;
wire RD_REQ_RD_WAIT ;
wire WR_WAIT_WR_REQ ;
wire WR_WAIT_DONE ;
wire RD_WAIT_RD_REQ ;
wire RD_WAIT_DONE ;
wire DONE_IDLE ;
wire done ;
wire add_cnt_byte ;
wire end_cnt_byte ;//reg define
reg [5:0] cstate ;
reg [5:0] nstate ;
reg [2:0] num ;
reg [4:0] cmd ;
reg cmd_vld ;
reg [7:0] op_wr_data ;
reg [15:0] addr_r ;
reg [7:0] wr_data_r ;
reg [2:0] cnt_byte ;
reg wr_req_r ;
reg rd_req_r ;assign add_cnt_byte = done;
assign end_cnt_byte = add_cnt_byte && cnt_byte == num - 1;
assign IDLE_WR_REQ = (cstate == IDLE) && wr_req_r;
assign IDLE_RD_REQ = (cstate == IDLE) && rd_req_r;
assign WR_REQ_WR_WAIT = (cstate == WR_REQ) && 1;
assign RD_REQ_RD_WAIT = (cstate == RD_REQ) && 1;
assign WR_WAIT_WR_REQ = (cstate == WR_WAIT) && done;
assign WR_WAIT_DONE = (cstate == WR_WAIT) && end_cnt_byte;
assign RD_WAIT_RD_REQ = (cstate == RD_WAIT) && done;
assign RD_WAIT_DONE = (cstate == RD_WAIT) && end_cnt_byte;
assign DONE_IDLE = (cstate == DONE) && 1;
assign ready = cstate == IDLE; //
always @(posedge clk or negedge rst) beginif (!rst) beginwr_req_r <=0;rd_req_r <= 0;endelse beginwr_req_r <= wr_req;rd_req_r <= rd_req;end
end//
always @(posedge clk or negedge rst) beginif (!rst) beginaddr_r <= 'd0;endelse if (reg_addr_vld) beginaddr_r <= reg_addr;end
end//
always @(posedge clk or negedge rst) beginif (!rst) beginwr_data_r <= 'd0;endelse if (wr_req) beginwr_data_r <= wr_data;end
end//
always @(posedge clk or negedge rst)begin if(!rst)begincnt_byte <= 'd0;end else if(add_cnt_byte)begin if(end_cnt_byte)begin cnt_byte <= 'd0;endelse begin cnt_byte <= cnt_byte + 1'd1;end end
end //
always @(posedge clk or negedge rst) beginif (!rst) beginnum <= 1;endelse if (wr_req) beginnum <= 4;endelse if (rd_req) beginnum <= 5;endelse if (end_cnt_byte) beginnum <= 1;end
end//
always @(posedge clk or negedge rst)begin if(!rst)begincstate <= IDLE;end else begin cstate <= nstate;end
end//
always @(*) begincase(cstate)IDLE :beginif (IDLE_WR_REQ) beginnstate = WR_REQ;endelse if (IDLE_RD_REQ) beginnstate = RD_REQ;endelse beginnstate = cstate;endend WR_REQ :beginif (WR_REQ_WR_WAIT) beginnstate = WR_WAIT;endelse beginnstate = cstate;endend WR_WAIT :beginif (WR_WAIT_DONE) beginnstate = DONE;endelse if (WR_WAIT_WR_REQ) beginnstate = WR_REQ;endelse beginnstate = cstate;endend RD_REQ :beginif (RD_REQ_RD_WAIT) beginnstate = RD_WAIT;endelse beginnstate = cstate;endend RD_WAIT :beginif (RD_WAIT_DONE) beginnstate = DONE;endelse if (RD_WAIT_RD_REQ) beginnstate = RD_REQ;endelse beginnstate = cstate;endend DONE :beginif (DONE_IDLE) beginnstate = IDLE;endelse beginnstate = cstate;endend default : nstate = cstate;endcase
end//
always @(posedge clk or negedge rst) beginif (!rst) beginTX(0,4'h0,8'h00);endelse begincase (cstate)RD_REQ:begincase (cnt_byte)0 : TX(1,(`START_BIT | `WRITE_BIT),WR_CTRL_BYTE);1 : TX(1,(`WRITE_BIT ),addr_r[15:8]);2 : TX(1,(`WRITE_BIT ),addr_r[7:0] );3 : TX(1,(`START_BIT | `WRITE_BIT),RD_CTRL_BYTE);4 : TX(1,(`READ_BIT | `STOP_BIT ),8'h00 );default: TX(0,cmd,op_wr_data);endcaseendWR_REQ:begincase (cnt_byte)0 : TX(1,(`START_BIT | `WRITE_BIT),WR_CTRL_BYTE);1 : TX(1,(`WRITE_BIT ),addr_r[15:8]);2 : TX(1,(`WRITE_BIT ),addr_r[7:0] );3 : TX(1,(`WRITE_BIT | `STOP_BIT ),wr_data_r );default: TX(0,cmd,op_wr_data);endcaseenddefault: TX(0,cmd,op_wr_data);endcaseend
endi2c inst_i2c(.clk (clk),.rst (rst),.wr_data (op_wr_data),.cmd (cmd),.cmd_vld (cmd_vld),.rd_data (rd_data),.rd_data_vld (rd_data_vld),.done (done),.scl (scl),.sda (sda));task TX;input task_cmd_vld ;input [3:0] task_cmd ;input [7:0] task_wr_data ;begincmd_vld = task_cmd_vld ;cmd = task_cmd ;op_wr_data = task_wr_data ;end
endtaskendmodule
七、管脚约束

声明: 本代码借鉴网络资料,如有侵权请联系作者删除,如有错误请在评论区或者私信作者纠正。