
IIC协议的Verilog代码(1)——主机写模块开发
发布日期:2021-05-07 22:56:20
浏览次数:23
分类:精选文章
本文共 5298 字,大约阅读时间需要 17 分钟。
Verilog代码
//Module Name:IIC Write//Author:Yang Cheng Yu//Date:2020/4/21//==================defines=====================`define SIMmodule iic_write( //================System Signal================ input clk , input rst_n , //================Interface==================== output reg scl , inout sda , output reg flag_wr , input wr_req , output reg flag_wr_done , input[6:0] dev_addr , input[7:0] data_wr , output reg[5:0] state ); //================parameters=================== parameter SYS_FRE =50_000_000; parameter IIC_FRE =10_000; `ifndef SIM localparam CNT_BAUD =SYS_FRE/IIC_FRE; localparam CNT_BAUD_HALF =CNT_BAUD/2; `else localparam CNT_BAUD = 500; localparam CNT_BAUD_HALF = 250; `endif //state machine localparam S_IDLE =6'b0000_01; localparam S_START =6'b0000_10; localparam S_DEV_ADDR =6'b0001_00; localparam S_ACK_DEV_ADDR =6'b0010_00; localparam S_DATA =6'b0100_00; localparam S_ACK_DATA =6'b1000_00; //================System regs================== reg[15:0] cnt_baud; reg[2:0] cnt_bit; wire flag_bit; reg flag_start_bit; reg SDA; reg wr_req_t0; reg wr_req_t1; wire wr_req_trig; reg flag_get_ack; reg[6:0] dev_addr_reg; reg[7:0] data_wr_reg; //================Main Codes=================== //scl always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0) scl <= 1'b1; else if(flag_start_bit==1'b1&&flag_wr==1'b1) scl <= 1'b1; else if(flag_start_bit==1'b0&&flag_wr==1'b1) if(cnt_baud<=CNT_BAUD_HALF-1) scl <= 1'b0; else if(cnt_baud>CNT_BAUD_HALF-1) scl <= 1'b1; else scl <= 1'b1; end //flag_wr always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0) flag_wr <= 1'b0; else if(flag_wr==1'b0&&wr_req_trig==1'b1) flag_wr <= 1'b1; else if(state==S_ACK_DATA&&flag_bit==1'b1) flag_wr <= 1'b0; end //sda assign sda = (state==S_ACK_DATA||state==S_ACK_DEV_ADDR)?1'bz:SDA; //cnt_baud always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0) cnt_baud <= 'd0; else if(flag_start_bit==1'b1&&flag_wr==1'b1) if(cnt_baud==CNT_BAUD_HALF-1) cnt_baud <= 'd0; else cnt_baud <= cnt_baud + 1'b1; else if(flag_start_bit==1'b0&&flag_wr==1'b1) if(cnt_baud==CNT_BAUD-1) cnt_baud <= 'd0; else cnt_baud <= cnt_baud + 1'b1; else cnt_baud <= 'd0; end //cnt_bit always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0) cnt_bit <= 'd0; else case(state) S_IDLE:cnt_bit <= 'd0; S_START:cnt_bit <= 'd0; S_DEV_ADDR:begin if(cnt_bit==3'd7&&flag_bit==1'b1) cnt_bit <= 'd0; else if(flag_bit==1'b1) cnt_bit <= cnt_bit + 1'b1; end S_ACK_DEV_ADDR:cnt_bit <= 'd0; S_DATA:begin if(cnt_bit==3'd7&&flag_bit==1'b1) cnt_bit <= 'd0; else if(flag_bit==1'b1) cnt_bit <= cnt_bit + 1'b1; end S_ACK_DATA:cnt_bit <= 'd0; endcase end //flag_bit assign flag_bit = (cnt_baud==CNT_BAUD-1)?1'b1:1'b0; //flag_start_bit always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0) flag_start_bit <= 1'b0; else if(flag_wr==1'b0&&wr_req_trig==1'b1) flag_start_bit <= 1'b1; else if(flag_start_bit==1'b1&&cnt_baud==CNT_BAUD_HALF-1) flag_start_bit <= 1'b0; end //state machine always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0) state <= S_IDLE; else case(state) S_IDLE:begin if(wr_req_trig==1'b1) state <= S_START; else state <= S_IDLE; end S_START:begin if(cnt_baud==CNT_BAUD_HALF-1) state <= S_DEV_ADDR; else state <= S_START; end S_DEV_ADDR:begin if(cnt_bit==3'd7&&flag_bit==1'b1) state <= S_ACK_DEV_ADDR; else state <= S_DEV_ADDR; end S_ACK_DEV_ADDR:begin if(cnt_baud
Test Bench
`timescale 1ns/1ns //时间精度`define clock_period 20 //时钟周期module tb_iic_write; //实体名称 //state machine localparam S_IDLE =6'b0000_01; localparam S_START =6'b0000_10; localparam S_DEV_ADDR =6'b0001_00; localparam S_ACK_DEV_ADDR =6'b0010_00; localparam S_DATA =6'b0100_00; localparam S_ACK_DATA =6'b1000_00;//===================== <系统端口> ============================= reg clk ; reg rst_n ;//===================== <外设端口> ============================= wire scl ; wire sda ; wire flag_wr ; reg wr_req ; wire flag_wr_done ; reg[6:0] dev_addr ; reg[7:0] data_wr ; wire[5:0] state ; assign sda = (state==S_ACK_DATA||state==S_ACK_DEV_ADDR)?1'b1:1'bz; iic_write iic_write_inst( //================System Signal================ .clk (clk), .rst_n (rst_n), //================Interface==================== .scl (scl), .sda (sda), .flag_wr (flag_wr), .wr_req (wr_req), .flag_wr_done (flag_wr_done), .dev_addr (dev_addr), .data_wr (data_wr), .state (state));//===================== <时钟信号> =============================initial begin clk = 1; forever #(`clock_period/2) clk = ~clk;end//===================== <复位信号> =============================initial begin rst_n = 0;#(`clock_period*20+1); rst_n = 1;end//===================== <激励信号> =============================initial begin dev_addr = 7'b011_0101; data_wr = 8'h00; wr_req = 0; #(`clock_period*20+1);//初始化 data_wr = 8'h56; #20; wr_req = 1; #20; wr_req = 0; #20_0000; data_wr = 8'h78; dev_addr = 7'b100_1010; #20; wr_req = 1; #20; wr_req = 0;end endmodule 激励信号> 复位信号> 时钟信号> 外设端口> 系统端口>
波形图
发表评论
最新留言
路过按个爪印,很不错,赞一个!
[***.219.124.196]2025年04月02日 02时36分15秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
python负数存储
2021-05-08
求二维数组中最大值的位置
2021-05-08
python中sort和sorted的区别
2021-05-08
vue中echart数据动态切换,一看就懂
2021-05-08
Python3.6爬虫记录
2021-05-08
搞清楚Spring Cloud架构原理的这4个点,轻松应对面试
2021-05-08
1月份2月份GitHub上最热门的23个Java开源项目
2021-05-08
maven安装
2021-05-08
2020第十五届全国大学生智能汽车竞赛——4X4矩阵键盘+Flash调参系统
2021-05-08
合并两个有序数组
2021-05-08
Ubuntu 环境下使用中文输入法
2021-05-08
小白学习Vue(?)--model选项的使用(自定义组件文本框双向绑定)
2021-05-08
聊聊我的五一小假期
2021-05-08
面向对象之异常处理:多路捕获
2021-05-08
Python简易五子棋
2021-05-08
MySQL8.0.19 JDBC下载与使用
2021-05-08
Vue新建项目——页面初始化
2021-05-08
Cent OS 7.6 服务器软件安装(这篇博客主要是为了方便我配置云主机的)
2021-05-08
MySQL使用系列文章
2021-05-08
Node.js包使用系列(一)——修改NPM全局下载和缓存路径
2021-05-08