蓝桥杯FPGA赛道第二次模拟题代码

一、顶层文件

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

 七、管脚约束

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/48991.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

R 语言机器学习:为遥感数据处理开启新视角

技术点目录 基础理论、机器学习与数据准备建模与空间预测实践案例与项目了解更多 ——————————————————————————————————————————— 前言综述 在当今科技快速发展的时代&#xff0c;遥感技术为生态学研究提供了海量的数据资源&#xf…

AI与脑机接口:人机融合的终极形态?

AI与脑机接口&#xff1a;人机融合的终极形态&#xff1f; 系统化学习人工智能网站&#xff08;收藏&#xff09;&#xff1a;https://www.captainbed.cn/flu 文章目录 AI与脑机接口&#xff1a;人机融合的终极形态&#xff1f;摘要引言技术路线对比1. 信号采集&#xff1a;侵…

20250508在WIN10下使用移远的4G模块EC200A-CN直接上网

1、在WIN10/11下安装驱动程序&#xff1a;Quectel_Windows_USB_DriverA_Customer_V1.1.13.zip 2、使用移远的专用串口工具&#xff1a;QCOM_V1.8.2.7z QCOM_V1.8.2_win64.exe 3、配置串口UART42/COM42【移远会自动生成连续三个串口&#xff0c;最小的那一个】 AT命令&#xf…

南京大学OpenHarmony技术俱乐部正式揭牌 仓颉编程语言引领生态创新

2025年4月24日&#xff0c;由OpenAtom OpenHarmony&#xff08;以下简称“OpenHarmony”&#xff09;项目群技术指导委员会与南京大学软件学院共同举办的“南京大学OpenHarmony技术俱乐部成立大会暨基础软件与生态应用论坛”在南京大学仙林校区召开。 大会聚焦国产自主编程语言…

中小企业设备预测性维护:从技术原理到中讯烛龙实践落地指南

在工业 4.0 与智能制造浪潮的推动下&#xff0c;中小企业正面临设备管理模式的深刻变革。传统的事后维修与预防性维护策略&#xff0c;因缺乏数据驱动与智能决策能力&#xff0c;已难以满足企业降本增效的核心诉求。据 Gartner 统计&#xff0c;非计划停机导致的生产损失平均每…

服务器数据恢复—硬盘坏道导致EqualLogic存储不可用的数据恢复

服务器存储数据恢复环境&故障&#xff1a; 一台EqualLogic某型号存储中有一组由16块SAS硬盘组建的RAID5阵列。上层采用VMFS文件系统&#xff0c;存放虚拟机文件&#xff0c;上层一共分了4个卷。 磁盘故障导致存储不可用&#xff0c;且设备已经过保。 服务器存储数据恢复过程…

STM32的SysTick

SysTick介绍 定义&#xff1a;Systick&#xff0c;即滴答定时器&#xff0c;是内核中的一个特殊定时器&#xff0c;用于提供系统级的定时服务。该定时器是一个24位的递减计数器&#xff0c;具有自动重载值寄存器的功能。当计数器到达自动重载值时&#xff0c;它会自动重新加载…

电子电气架构 --- 如何有助于提安全性并减少事故

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 钝感力的“钝”,不是木讷、迟钝,而是直面困境的韧劲和耐力,是面对外界噪音的通透淡然。 生活中有两种人,一种人格外在意别人的眼光;另一种人无论…

跨浏览器自动化测试的智能生成方法

一、背景与挑战&#xff1a;跨浏览器测试为什么“难”&#xff1f; 在现代Web应用开发中&#xff0c;跨浏览器兼容性是用户体验的底线保障。面对Chrome、Firefox、Safari、Edge乃至IE、移动浏览器等多种运行环境&#xff0c;开发者与测试人员常面临&#xff1a; 相同DOM在不同…

小程序与快应用:中国移动互联网的渐进式革命——卓伊凡的技术演进观

小程序与快应用&#xff1a;中国移动互联网的渐进式革命——卓伊凡的技术演进观 在知乎看到很多&#xff1a;“懂王”发布的要把内行笑疯了的评论&#xff0c;卓伊凡必须怼一下&#xff0c;真印证那句话&#xff0c;无知者无畏 一、Web与小程序的技术本质差异 1.1 浏览器渲染…

抛物线法(二次插值法)

抛物线法简介 抛物线法&#xff08;Quadratic Interpolation Method&#xff09;是一种用于一维单峰函数极值搜索的经典优化方法。该方法通过在区间内选取三个不同的点&#xff0c;拟合一条二次抛物线&#xff0c;并求取这条抛物线的极值点作为新的迭代点&#xff0c;从而逐步…

记录一次华为魔改 fusionlnsight和ai问答的狗血故事

需求 需要通过客户端连接 fusionlnsight 平台&#xff0c;平台开启了高可用和 kerberos 认证 。现在需要连接时不使用高可用连接&#xff0c;也就是不使用 zookeeper&#xff0c;适用ip:port 直连。 踩坑记录 尝试使用 平台上面的主节点的ip10000默认端口连接&#xff0c;连…

【杂谈】Godot 2D游戏窗口设置

如切如磋&#xff0c;如琢如磨。 目录 一、引言二、设置&#xff08;一&#xff09;基本尺寸&#xff08;二&#xff09;拉伸&#xff08;三&#xff09;手持设备朝向&#xff08;四&#xff09;​​窗口模式​​ 一、引言 在开发2D游戏时&#xff0c;​​窗口尺寸的设定是游戏…

mac 使用 Docker 安装向量数据库Milvus独立版的保姆级别教程

Milvus 特点&#xff1a;开源的云原生向量数据库&#xff0c;支持多种索引类型和GPU加速&#xff0c;能够在亿级向量规模下实现低延迟高吞吐。具有灵活的部署选项和强大的社区支持。 适用场景&#xff1a;适合处理超大规模数据和高性能需求的应用&#xff0c;如图像搜索、推荐…

(14)Element Plus项目综合案例

本系列教程目录&#xff1a;Vue3Element Plus全套学习笔记-目录大纲 文章目录 第3章 综合案例3.1 搭建项目3.1.1 创建Vite工程3.1.2 配置路由 3.2 登录模块页面3.2.1 注册页面3.2.2 登录页面3.2.3 忘记密码页面 3.3 导航设置3.3.1 头部3.3.2 侧边栏与底部1&#xff09;头像部分…

基于腾讯云MCP广场的AI自动化实践:爬取小红书热门话题

基于腾讯云MCP广场的AI自动化实践&#xff1a;爬取小红书热门话题 我正在参加Trae「超级体验官」创意实践征文&#xff0c;本文所使用的 Trae 免费下载链接&#xff1a;www.trae.com.cn/?utm_source… &#x1f50e; 背景 在人工智能快速发展的时代&#xff0c;AI技术不仅重…

C++从入门到实战(十四)初识STL与STL简介

C从入门到实战&#xff08;十四&#xff09;初识STL与STL简介 前言一、什么是 STL&#xff1f;二、STL 的版本三、STL六大组件&#xff08;目前了解即可&#xff0c;后面会逐步讲解&#xff09;1. 容器&#xff08;Containers&#xff09;—— 装数据的“盒子”2. 算法&#xf…

【LeetCode 42】接雨水(单调栈、DP、双指针)

题面&#xff1a; 思路&#xff1a; 能接雨水的点&#xff0c;必然是比两边都低&#xff08;小&#xff09;的点。有两种思路&#xff0c;一种是直接计算每个点的最大贡献&#xff08;也就是每个点在纵向上最多能接多少水&#xff09;&#xff0c;另一种就是计算每个点在横向上…

ruoyi-flowable-plus 前端框架启动报错修复

版本 1. ruoyi-flowable-plus 前端框架启动报错修复 启动时设置环境变量 "scripts": {"dev": "SET NODE_OPTIONS--openssl-legacy-provider && vue-cli-service serve","build:prod": "vue-cli-service build",&qu…

Python全流程开发实战:基于IMAP协议安全下载个人Gmail邮箱内所有PDF附件

文章目录 一、需求分析与安全前置&#xff1a;为什么需要专用工具&#xff1f;1.1 痛点场景1.2 技术方案选择 二、准备工作&#xff1a;Gmail账号安全配置与环境搭建2.1 开启两步验证&#xff08;必做&#xff01;&#xff09;2.2 创建应用专用密码&#xff08;替代普通密码&am…