资讯动态

EEPROM

发布时间:2026/10/14 9:58:35 来源:尧图企业网站定制
通过IIC控制EEPROM。共6个模块Module。module IIC( input wire clk , input wire rst_n , input wire start_iic , //开始信号外部模块引入信号 input wire worr , //方向信号用于状态跳转 input wire [7:0] sendnum , //单位字节发送数据量,,用于多数据传输 input wire [7:0] recvnum , //接收的数据量 用于多数据传输 input wire [7:0] data_i_icc , //要发送到rom的数据 output wire [7:0] data_o_iic , //读出的数据 output wire done_w , //写完成信号 output wire done_r , //接收字节完成的信号 output wire done_iic , //整体工作结束 output wire done_nack , //错误信号即工作异常的时候出现 inout wire scl , inout wire sda ); parameter sysclk 50_000_000, iicclk 100_000, delay sysclk/iicclk, MID delay/2, //1/2节点 Q_MID delay/4, //1/4节点 TQ_MID MID Q_MID; //3/4节点 parameter id_w 8b1010_0000, //写地址 id_r 8b1010_0001; //读地址 //变量 reg [9:0] cnt; //工作周期计数1bit计数 reg [3:0] cnt_bit; //多少bit计数 reg [7:0] sendcnt; //发送字节个数计数器 reg [7:0] recvcnt; //接收字节个数计数器 reg [1:0] start_reg; //开始信号寄存 reg worr_reg; //方向信号寄存器 reg [7:0] sendnum_reg; //发送数据量寄存器 reg [7:0] recvnum_reg; //接收数据量寄存器 reg [7:0] data_reg; //发送数据寄存器 reg [7:0] data_temp; //接收数据寄存器 reg ack_flag; //应答信号寄存器 assign done_nack ack_flag; //三态门 wire scl_in; reg scl_en,scl_out; assign scl (scl_en)?scl_out:1bz; assign scl_in scl; wire sda_in; reg sda_en,sda_out; assign sda (sda_en)?sda_out:1bz; assign sda_in sda; //开始信号寄存 always (posedge clk) begin if(!rst_n) start_reg 2b0; else start_reg {start_reg[0],start_iic}; end //状态机 localparam IDLE 1 , START1 2 , IDW 3 , ACK1 4 , WDATA 5 , ACK2 6 , STOP 7 , START2 8 , IDR 9 , ACK3 10 , RDATA 11 , ACK4 12 ; reg [3:0] c_state,n_state; // always(posedge clk) if(!rst_n) c_state IDLE; else c_state n_state; // always (*) begin if(!rst_n) n_state IDLE; else case (c_state) IDLE :begin if(start_reg 2b01) n_state START1; else n_state c_state; end START1:begin if(cnt delay Q_MID - 1 worr_reg 0) n_state IDW; else if(cnt delay Q_MID - 1 worr_reg 1) n_state IDR; else n_state c_state; end IDW :begin if(cnt delay - 1 cnt_bit 7) n_state ACK1; else n_state c_state; end ACK1 :begin if(ack_flag 1) n_state IDLE; else if(cnt delay - 1 ack_flag 0) n_state WDATA; else n_state c_state; end WDATA :begin if(cnt delay - 1 cnt_bit 7) n_state ACK2; else n_state c_state; end ACK2 :begin if(ack_flag 1) n_state IDLE; else if(cnt delay - 1 ack_flag 0 sendnum_reg sendcnt recvnum_reg 0) n_state STOP; else if(cnt delay - 1 ack_flag 0 sendnum_reg sendcnt recvnum_reg ! 0) n_state START2; //实现写一个读一个效果 else if(cnt delay - 1 ack_flag 0 sendnum_reg sendcnt) n_state WDATA; else n_state c_state; end STOP :begin if(cnt delay Q_MID - 1) n_state IDLE; else n_state c_state; end START2:begin if(cnt delay Q_MID - 1) n_state IDR; else n_state c_state; end IDR :begin if(cnt delay - 1 cnt_bit 7) n_state ACK3; else n_state c_state; end ACK3 :begin if(ack_flag 1) n_state IDLE; if(cnt delay - 1 ack_flag 0) n_state RDATA; else n_state c_state; end RDATA :begin if(cnt delay - 1 cnt_bit 7) n_state ACK4; else n_state c_state; end ACK4 :begin if(cnt delay - 1 recvnum_reg recvcnt) n_state STOP; else if(cnt delay - 1 recvnum_reg recvcnt) n_state RDATA; else n_state c_state; end default: n_state IDLE; endcase end // always (posedge clk) begin if(!rst_n)begin cnt 0 ; //工作周期计数1bit计数 cnt_bit 0 ; //多少bit计数 sendcnt 0 ; //发送字节个数计数器 recvcnt 0 ; //接收字节个数计数器 worr_reg 0 ; //方向信号寄存器 sendnum_reg 0 ; //发送数据量寄存器 recvnum_reg 0 ; //接收数据量寄存器 data_reg 0 ; //发送数据寄存器 data_temp 0 ; //接收数据寄存器 ack_flag 0 ; //应答信号寄存器 scl_en 0 ; //开关都不工作关闭 scl_out 1 ; //高阻1 sda_en 0 ; //开关都不工作关闭 sda_out 1 ; //高阻1 end else case (c_state) IDLE : begin //寄存信号 cnt 0 ; //工作周期计数1bit计数 cnt_bit 0 ; //多少bit计数 sendcnt 0 ; //发送字节个数计数器 recvcnt 0 ; //接收字节个数计数器 worr_reg worr ; //方向信号寄存器 sendnum_reg sendnum ; //发送数据量寄存器 recvnum_reg recvnum ; //接收数据量寄存器 data_reg data_i_icc ; //发送数据寄存器 data_temp 0 ; //接收数据寄存器 ack_flag 0 ; //应答信号寄存器 scl_en 0 ; //开关都不工作关闭 sda_en 0 ; //开关都不工作关闭 scl_out 1 ; //高阻1 sda_out 1 ; //高阻1 end START1,START2:begin //寄存信号 if(cnt delay Q_MID - 1) cnt 0 ; //工作周期计数1bit计数 else cnt cnt 1; cnt_bit 0 ; //多少bit计数 sendcnt 0 ; //发送字节个数计数器 recvcnt 0 ; //接收字节个数计数器 data_temp 0 ; //接收数据寄存器 ack_flag 0 ; //应答信号寄存器 scl_en 1 ; //开关主机工作打开 sda_en 1 ; //开关主机工作打开 //sda先拉低scl后拉低 if(cnt delay -1) scl_out 0 ; else scl_out 1; if(cnt MID - 1) sda_out 0 ; else sda_out 1 ; end IDW :begin //寄存信号 if(cnt delay - 1) cnt 0 ; //工作周期计数1bit计数 else cnt cnt 1; if(cnt delay - 1)begin if(cnt_bit 7) cnt_bit 0 ; //多少bit计数 else cnt_bit cnt_bit 1; end sendcnt 0 ; //发送字节个数计数器 recvcnt 0 ; //接收字节个数计数器 data_temp 0 ; //接收数据寄存器 ack_flag 0 ; //应答信号寄存器 scl_en 1 ; //开关主机工作打开 sda_en 1 ; //开关主机工作打开 //两边为低中间为高 if(cnt Q_MID || cnt TQ_MID) scl_out 0 ; else scl_out 1; //先发高位低电平发送高电平保持 if(cnt 0) sda_out id_w[7 - cnt_bit] ; end ACK1,ACK3 :begin //寄存信号 if(cnt delay - 1) cnt 0 ; //工作周期计数1bit计数 else cnt cnt 1; cnt_bit 0 ; //多少bit计数 sendcnt 0 ; //发送字节个数计数器 recvcnt 0 ; //接收字节个数计数器 data_temp 0 ; //接收数据寄存器 if(cnt MID) ack_flag sda_in ; //应答信号寄存器 scl_en 1 ; //开关主机工作打开 sda_en 0 ; //开关主机工作打开 //两边为低中间为高 if(cnt Q_MID || cnt TQ_MID) scl_out 0 ; else scl_out 1; //不工作 sda_out 1 ; end WDATA :begin //寄存信号 if(cnt delay - 1) cnt 0 ; //工作周期计数1bit计数 else cnt cnt 1; if(cnt delay - 1)begin if(cnt_bit 7) cnt_bit 0 ; //多少bit计数 else cnt_bit cnt_bit 1; end recvcnt 0 ; //接收字节个数计数器 data_temp 0 ; //接收数据寄存器 ack_flag 0 ; //应答信号寄存器 scl_en 1 ; //开关主机工作打开 sda_en 1 ; //开关主机工作打开 //两边为低中间为高 if(cnt Q_MID || cnt TQ_MID) scl_out 0 ; else scl_out 1; //先发送高位低电平发送高电平保持 if(cnt 0) sda_out data_reg[7 - cnt_bit] ; //从高位开始 end ACK2 :begin //发送时钟主机接收应答从机更新数据计数 if(cnt delay - 1) cnt 0 ; //工作周期计数1bit计数 else cnt cnt 1; cnt_bit 0 ; //多少bit计数 if(cnt MID) sendcnt sendcnt 1; //发送字节个数计数器 recvcnt 0 ; //接收字节个数计数器 data_temp 0 ; //接收数据寄存器 if(cnt MID) ack_flag sda_in ; //应答信号寄存器 //更新数据 data_reg data_i_icc; scl_en 1 ; //开关主机工作打开 sda_en 0 ; //开关从机工作关闭 //两边为低中间为高 if(cnt Q_MID || cnt TQ_MID) scl_out 0 ; else scl_out 1; //不工作 sda_out 1 ; end STOP :begin //寄存信号 if(cnt delay Q_MID - 1) cnt 0 ; //工作周期计数1bit计数 else cnt cnt 1; cnt_bit 0 ; //多少bit计数 sendcnt 0 ; //发送字节个数计数器 recvcnt 0 ; //接收字节个数计数器 data_temp 0 ; //接收数据寄存器 ack_flag 0 ; //应答信号寄存器 scl_en 1 ; //开关主机工作打开 sda_en 1 ; //开关主机工作打开 //sda后拉高scl先拉高 if(cnt Q_MID -1) scl_out 1 ; else scl_out 0; if(cnt TQ_MID - 1) sda_out 1 ; else sda_out 0 ; end IDR :begin //寄存信号 if(cnt delay - 1) cnt 0 ; //工作周期计数1bit计数 else cnt cnt 1; if(cnt delay - 1)begin if(cnt_bit 7) cnt_bit 0 ; //多少bit计数 else cnt_bit cnt_bit 1; end sendcnt 0 ; //发送字节个数计数器 recvcnt 0 ; //接收字节个数计数器 data_temp 0 ; //接收数据寄存器 ack_flag 0 ; //应答信号寄存器 scl_en 1 ; //开关主机工作打开 sda_en 1 ; //开关主机工作打开 //两边为低中间为高 if(cnt Q_MID || cnt TQ_MID) scl_out 0 ; else scl_out 1; //先发送高位低电平发送高电平保持 if(cnt 0) sda_out id_r[7 - cnt_bit] ; end RDATA :begin //发送时钟主机接收数据 if(cnt delay - 1) cnt 0 ; //工作周期计数1bit计数 else cnt cnt 1; if(cnt delay - 1)begin if(cnt_bit 7) cnt_bit 0 ; //多少bit计数 else cnt_bit cnt_bit 1; end sendcnt 0 ; //发送字节个数计数器 if(cnt MID) data_temp[7-cnt_bit] sda_in ; //接收数据寄存器 ack_flag 0 ; //应答信号寄存器 scl_en 1 ; //开关主机工作打开 sda_en 0 ; //开关从机工作关闭 //两边为低中间为高 if(cnt Q_MID || cnt TQ_MID) scl_out 0 ; else scl_out 1; //不工作 sda_out 1 ; end ACK4 :begin //发送时钟主机接收应答从机更新数据计数 if(cnt delay - 1) cnt 0 ; //工作周期计数1bit计数 else cnt cnt 1; cnt_bit 0 ; //多少bit计数 sendcnt 0; //发送字节个数计数器 if(cnt Q_MID) recvcnt recvcnt 1 ; //接收字节个数计数器 ack_flag 0 ; //应答信号寄存器 scl_en 1 ; //开关主机工作打开 sda_en 1 ; //开关主机工作打开 //两边为低中间为高 if(cnt Q_MID || cnt TQ_MID) scl_out 0 ; else scl_out 1; //发送应答/非应答 if(recvnum_reg recvcnt) sda_out 1 ; else sda_out 0; end default: begin cnt_bit 0 ; //多少bit计数 sendcnt 0 ; //发送字节个数计数器 recvcnt 0 ; //接收字节个数计数器 worr_reg 0 ; //方向信号寄存器 sendnum_reg 0 ; //发送数据量寄存器 recvnum_reg 0 ; //接收数据量寄存器 data_reg 0 ; //发送数据寄存器 data_temp 0 ; //接收数据寄存器 ack_flag 0 ; //应答信号寄存器 scl_en 0 ; //开关都不工作关闭 scl_out 1 ; //高阻1 sda_en 0 ; //开关都不工作关闭 sda_out 1 ; //高阻1 end endcase end assign data_o_iic (c_state ACK4)?data_temp:0; assign done_r (c_state ACK4 cnt MID)?1:0; assign done_w (c_state ACK2 cnt MID)?1:0; assign done_iic (c_state STOP cnt MID)?1:0; endmodulemodule ctrl_r( input wire clk , input wire rst_n , input wire done_r , input wire [7:0] data_o_iic , input wire done_tx , input wire done_iic , output wire [7:0] data_tx , //并行输入数据 output wire start_tx ); //fifo wire [7:0] data; wire wrreq; wire rdreq; wire empty; wire full; wire [7:0] q; wire [7:0] usedw; //写 assign data data_o_iic; assign wrreq done_r; //读 assign rdreq ((done_iic || done_tx) !empty)?1:0; assign data_tx q; reg rdreqr; always(posedge clk) if(!rst_n) rdreqr0; else rdreqrrdreq; assign start_tx (rdreqr) ?1:0; fifo fifo_r ( .aclr ( !rst_n), .clock ( clk ), .data ( data ), .rdreq ( rdreq ), .wrreq ( wrreq ), .empty ( empty ), .full ( full ), .q ( q ), .usedw ( usedw ) ); endmodulemodule ctrl_w( input clk , input rst_n , input wire [7:0] data_rx , //并行输出信号 input data_done , //数据完成标志 input done_iic , //数据结束清空fifo条件 input done_w , //数据更新 input done_nack , //清空fifo output wire start_iic , //开始信号外部模块引入信号 output wire worr , //方向信号用于状态跳转 output wire [7:0] sendnum , //单位字节发送数据量 output wire [7:0] recvnum , //接收的数据量 output wire [7:0] data_i_icc //要发送到rom的数据 ); /* 接收指令 如果iic工作异常 解析指令 */ //fifo reg [7:0] data; reg wrreq; wire rdreq; wire empty; wire full; wire [7:0] q; wire [7:0] usedw; localparam IDLE 1, //识别包头 WORR 2, //data_done方向信号 SENDNUM 3, //data_done RECVNUM 4, //data_done ADDR 5, //data_done 识别包尾 DATA 6, //data_done 识别包尾就不传输进fifo STOP 7; // 直接跳到空闲 reg [3:0] c_state,n_state; reg worr_reg ; //读写信号标志0是写非0是读 reg [7:0] sendnum_reg ; //发送数据量 reg [7:0] recvnum_reg ; //接收数据量 reg [7:0] addr_reg ; //地址 reg [7:0] data_reg ; //数据 reg [7:0] data_temp; // always(posedge clk) if(!rst_n) c_state 0; else c_state n_state; //二段状态机 always (*) begin if(!rst_n) n_state IDLE; else case (c_state) IDLE :begin if(data_done data_rx8hfe ) // n_state WORR; else n_state c_state; end WORR :begin if(data_done ) n_state SENDNUM; else n_state c_state; end SENDNUM:begin if(data_done ) n_state RECVNUM; else n_state c_state; end RECVNUM:begin if(data_done ) n_state ADDR; else n_state c_state; end ADDR :begin if(data_done data_rx 8hee) n_state STOP; else if(data_done data_rx ! 8hee) n_state DATA; else n_state c_state; end DATA :begin if(data_done data_rx 8hee) n_state STOP; else n_state c_state; end STOP :begin /* if(done_iic) n_state IDLE; else */ n_state IDLE; end default: n_state IDLE; endcase end //三段状态机,fifo写 always (posedge clk) begin if(!rst_n)begin worr_reg 0; sendnum_reg 0; recvnum_reg 0; addr_reg 0; data 0; wrreq 0; end else case (c_state) IDLE :begin worr_reg worr_reg ; sendnum_reg sendnum_reg; recvnum_reg recvnum_reg; addr_reg addr_reg ; data 0; wrreq 0; end WORR :begin if(data_done) worr_reg data_rx; //给方向信号赋值 sendnum_reg 0; recvnum_reg 0; addr_reg 0; data 0; wrreq 0; end SENDNUM:begin if(data_done) sendnum_reg data_rx; recvnum_reg 0; addr_reg 0; data 0; wrreq 0; end RECVNUM:begin if(data_done) recvnum_reg data_rx; addr_reg 0; data 0; wrreq 0; end ADDR :begin if(data_done) addr_reg data_rx; data 0; wrreq 0; end DATA :begin if(data_done data_rx ! 8hee)begin data data_rx; wrreq 1; end else begin data 0; wrreq 0; end end STOP :begin data 0; wrreq 0; end default: begin worr_reg 0; sendnum_reg 0; recvnum_reg 0; addr_reg 0; data 0; wrreq 0; end endcase end assign rdreq done_w; reg rdreqr; always(posedge clk) if(!rst_n) rdreqr 0; else rdreqr rdreq; //数据交互 always(posedge clk) if(!rst_n) data_temp 0; else if(rdreqr) data_temp q; else if(data_done c_state DATA) data_temp addr_reg; assign start_iic (c_state STOP)?1:0; assign worr worr_reg; assign sendnum sendnum_reg; assign recvnum recvnum_reg; assign data_i_icc data_temp; fifo fifo_w ( .aclr ( !rst_n || done_nack || done_iic ), .clock ( clk ), .data ( data ), .rdreq ( rdreq ), .wrreq ( wrreq ), .empty ( empty ), .full ( full ), .q ( q ), .usedw ( usedw ) ); endmodulemodule rx_check( input clk, input rst_n, input rx, //串行输入信号 output wire [7:0] data_rx, //并行输出信号//81奇偶校验位 output data_done //数据完成标志 ); parameter TIME 50_000_000 , bps 9600 , adtime TIME / bps ; //5208个 parameter MODE 0;//0:无校验1:奇2:偶3:校验常为14:0 localparam IDLE 5b00001, //空闲 START 5b00010, //开始状态 DATA 5b00100, //数据传输状态 CHECK 5b01000, //校验核对状态 STOP 5b10000; //停止状态 //定义5个状态 reg [1:0] rx_reg ; //数据变化寄存检测上升下降变化 reg [12:0] cnt_cout ; //存储一个数据时间周期的时间数据量即计数5208 reg [3:0] cnt_bit ;//计数多少个数据 reg [7:0] data_reg ;//数据采样计数一半采集数据 reg check_reg ;//校验位 reg check_num ;//校验计算 reg check_flag; //状态寄存器 reg [4:0] c_state,n_state; always(posedge clk) if(!rst_n) c_state IDLE; else c_staten_state; //状态切换条件,组合逻辑 always(*) if(!rst_n) n_state IDLE; else case(c_state) IDLE :begin if(rx_reg 2b10) n_state START; else n_state c_state; end START :begin if(cnt_cout adtime - 1) n_state DATA; else n_state c_state; end DATA :begin //对模式判断是否进行数据校验 if(cnt_cout adtime - 1 cnt_bit 7 MODE ! 0) n_state CHECK; else if(cnt_cout adtime - 1 cnt_bit 7 MODE 0) n_state STOP; else n_state c_state; end CHECK :begin if(cnt_cout adtime - 1) n_state STOP; else n_state c_state; end STOP :begin if(cnt_cout adtime/2 - 1) n_state IDLE;//n_state c_state;// else n_state c_state; end default:n_state IDLE; endcase //时序逻辑 always(posedge clk) if(!rst_n)begin rx_reg 2b11; cnt_cout 0; cnt_bit 0; data_reg 0; check_reg 0; check_num 0; end else case(c_state) IDLE :begin rx_reg {rx_reg[0],rx};//2级寄存 cnt_cout 0; cnt_bit 0; data_reg 0; check_reg 0; check_num 0; check_flag 0; end START :begin rx_reg 2b11; if(cnt_cout adtime - 1) cnt_cout 0; else cnt_cout cnt_cout 1; cnt_bit 0;//不需要计数数据 data_reg 0; check_reg 0; check_num 0; check_flag 0; end DATA :begin rx_reg 2b11; if(cnt_cout adtime - 1) cnt_cout 0; else cnt_cout cnt_cout 1; if(cnt_cout adtime - 1)begin if(cnt_bit 7) cnt_bit 0; else cnt_bit cnt_bit 1; end else cnt_bit cnt_bit; if(cnt_cout adtime/2-1) data_reg[cnt_bit] rx; else data_reg data_reg; check_reg 0; check_num 0; check_flag 0; end CHECK :begin rx_reg 2b11; if(cnt_cout adtime - 1) cnt_cout 0; else cnt_cout cnt_cout 1; cnt_bit 0;// data_reg data_reg; if(cnt_cout adtime/2-1) check_reg rx; else check_reg check_reg; case (MODE) 0:check_num 0; 1:check_num ~^data_reg; 2:check_num ^data_reg; 3:check_num 1; 4: check_num 0; default: check_num 0; endcase check_flag 0; end STOP :begin rx_reg 2b11; if(cnt_cout adtime/2 - 1) cnt_cout 0; else cnt_cout cnt_cout 1; cnt_bit 0;//不需要计数数据 data_reg data_reg; check_reg check_reg; check_num check_num; if(check_reg check_num cnt_cout adtime/4) check_flag 1; else if(check_reg ! check_num cnt_cout adtime/4) check_flag 0; else check_flag check_flag; end default:begin rx_reg 2b11; cnt_cout 0; cnt_bit 0; data_reg 0; check_reg 0; check_num 0; end endcase assign data_rx (check_flag 1) ? data_reg : 0; assign data_done (c_state STOP cnt_cout adtime/2-1) ? 1 : 0; endmodulemodule tx_check( input clk , input rst_n , input [7:0] data_tx , //并行输入数据 input start_tx , //开始信号标志 output tx , output done_tx ); parameter TIME 50_000_000 , bps 9600 , delay TIME / bps ; parameter MODE 0;//0:无校验1:奇2:偶3:校验常为14:0 reg [7:0] data_reg; //寄存并行数据,整个工作过程中数据保持不变 reg [12:0] cnt; //一个bit的计数 reg [3:0] cnt_bit; reg tx_reg; //发送寄存器 //reg check_num; //计算校验 localparam IDLE 5b00001, //空闲 START 5b00010, //开始状态 DATA 5b00100, //数据传输状态 CHECK 5b01000, //校验核对状态 STOP 5b10000; //停止状态 //定义5个状态 //状态寄存器 reg [4:0] c_state,n_state; always(posedge clk) if(!rst_n) c_state IDLE; else c_staten_state; //状态切换条件,组合逻辑 always(*) if(!rst_n) n_state IDLE; else case(c_state) IDLE :begin if(start_tx) n_state START; else n_state c_state; end START:begin if(cnt delay - 1) n_state DATA; else n_state c_state; end DATA :begin if(cnt delay - 1 cnt_bit 8 MODE ! 0) n_state CHECK; else if(cnt delay - 1 cnt_bit 8 MODE 0) n_state STOP; else n_state c_state; end CHECK:begin if(cnt delay - 1) n_state STOP; else n_state c_state; end STOP :begin if(cnt delay - 1) n_state IDLE; else n_state c_state; end default:n_state IDLE; endcase always(posedge clk) if(!rst_n)begin data_reg 0; //寄存并行数据,整个工作过程中数据保持不变 cnt 0; //一个bit的计数 cnt_bit 0; tx_reg 1; //初值为1体现为空闲位 end else case(c_state) IDLE :begin if(start_tx) data_reg data_tx; //寄存并行数据,整个工作过程中数据保持不变 else data_reg data_reg; cnt 0; //一个bit的计数 cnt_bit 0; tx_reg 1; //初值为1体现为空闲位 end START:begin data_reg data_reg; //寄存并行数据,整个工作过程中数据保持不变 if(cnt delay - 1) cnt 0; //一个bit的计数 else cnt cnt 1; cnt_bit 0; tx_reg 0; //初值为0体现为起始位 end DATA :begin data_reg data_reg; //寄存并行数据,整个工作过程中数据保持不变 if(cnt delay - 1) cnt 0; //一个bit的计数 else cnt cnt 1; if(cnt delay - 1)begin if(cnt_bit 8) cnt_bit 0; //清零消除毛刺 else cnt_bit cnt_bit 1; end else cnt_bit cnt_bit; tx_reg data_reg[cnt_bit]; //数据位的发送 end CHECK:begin data_reg data_reg; //寄存并行数据,整个工作过程中数据保持不变 if(cnt delay - 1) cnt 0; //一个bit的计数 else cnt cnt 1; cnt_bit 0; case(MODE) 0:tx_reg 0; //数据位的发送 1:tx_reg ~^data_reg; //奇校验同或 2:tx_reg ^data_reg; //偶校验异或 3:tx_reg 1; // 4:tx_reg 0; // default:tx_reg 0; //数据位的发送 endcase end STOP :begin data_reg 0; //寄存并行数据,整个工作过程中数据保持不变 if(cnt delay - 1) cnt 0; //一个bit的计数 else cnt cnt 1; cnt_bit 0; tx_reg 1; //为1 end default:begin data_reg 0; //寄存并行数据,整个工作过程中数据保持不变 cnt 0; //一个bit的计数 cnt_bit 0; tx_reg 1; //初值为1体现为空闲位 end endcase assign tx tx_reg; assign done_tx (c_state STOP cnt delay - 1)?1:0; endmodulemodule top( input wire clk , input wire rst_n, input wire rx , output wire RTC , output tx , inout wire scl , inout wire sda ); assign RTC 0; //硬件复位 //rx wire [7:0] data_rx ; wire data_done; //ctrl_w wire start_iic ; wire worr ; wire [7:0] sendnum ; wire [7:0] recvnum ; wire [7:0] data_i_icc; //IIC wire [7:0] data_o_iic; wire done_w ; wire done_nack ; wire done_r ; wire done_iic ; //tx wire done_tx ; //ctrl_r wire [7:0] data_tx ; wire start_tx ; IIC IIC_inst( .clk (clk ), .rst_n (rst_n ), .start_iic (start_iic ), //开始信号外部模块引入信号 .worr (worr ), //方向信号用于状态跳转 .sendnum (sendnum ), //单位字节发送数据量 .recvnum (recvnum ), //接收的数据量 .data_i_icc (data_i_icc), //要发送到rom的数据 .data_o_iic (data_o_iic), //读出的数据 .done_w (done_w ), //写完成信号 .done_r (done_r ), //接收字节完成的信号 .done_iic (done_iic ), //整体工作结束 .done_nack (done_nack ), .scl (scl ), .sda (sda ) ); ctrl_w ctrl_w_inst( .clk (clk ), .rst_n (rst_n ), .data_rx (data_rx ), //并行输出信号//81奇偶校验位 .data_done (data_done ), //数据完成标志 .done_iic (done_iic ), //数据结束 .done_w (done_w ), //数据更新 .start_iic (start_iic ), //开始信号外部模块引入信号 .done_nack (done_nack ), .worr (worr ), //方向信号用于状态跳转 .sendnum (sendnum ), //单位字节发送数据量 .recvnum (recvnum ), //接收的数据量 .data_i_icc (data_i_icc) //要发送到rom的数据 ); ctrl_r ctrl_r_inst( .clk (clk ), .rst_n (rst_n ), .done_r (done_r ), .data_o_iic (data_o_iic), .done_tx (done_tx ), .done_iic (done_iic ), .data_tx (data_tx ), //并行输入数据 .start_tx (start_tx ) ); tx_check tx_check_inst( .clk (clk ), .rst_n (rst_n ), .data_tx (data_tx ), //并行输入数据 .start_tx (start_tx), //开始信号标志 .tx (tx ), .done_tx (done_tx ) ); rx_check rx_check_inst( .clk (clk ), .rst_n (rst_n ), .rx (rx ), //串行输入信号 .data_rx (data_rx ), //并行输出信号//81奇偶校验位 .data_done (data_done) //数据完成标志 ); endmodule

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑