当前位置: 首页 > news >正文

蓝桥杯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

 七、管脚约束

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

相关文章:

  • 【Pandas】pandas DataFrame ewm
  • 复盘20250508
  • 坐标系与坐标系数转换
  • zookeeper实现分布式获取全局唯一自增ID的案例。
  • BFS算法的学习
  • Android平台FFmpeg视频解码全流程指南
  • 跨平台移动开发框架React Native和Flutter性能对比
  • GuPPy-v1.2.0安装与使用-生信工具52
  • 数字孪生医疗:构建患者特异性数字孪生体路径探析
  • JVM运行时数据区域(Run-Time Data Areas)的解析
  • 关于 wordpress 统计访问量初始数值错误的解决方法
  • Qt获取CPU使用率及内存占用大小
  • typecho中的Widget设计文档
  • 17.thinkphp的分页功能
  • 广州AI数字人:从“虚拟”走向“现实”的变革力量
  • 软件工程(五):设计模式
  • 体绘制中的传输函数(transfer func)介绍
  • 网站公安备案流程及审核时间
  • Django进阶:用户认证、REST API与Celery异步任务全解析
  • flutter build apk出现的一些奇怪的编译错误
  • 印度外交秘书:“朱砂行动”不针对军事设施,无意升级事态
  • “上海之帆”巡展在日本大阪开幕,松江区组织企业集体出展
  • 国家发改委副主任谈民营经济促进法:以法治的稳定性增强发展的确定性
  • 两部门发布外汇领域行刑反向衔接案例,织密金融安全“防护网”
  • 北京:下调个人住房公积金贷款利率
  • 41年轮回,从洛杉矶奔向洛杉矶,李宁故地重游再出发