写一个ADV7391的Virelog调试过程
所用:vivado 2018.3
一、原理图
二、调试ADV7391的I2C口,上Block design
三、上干货
module I2C_7391
(
input wire en_clk, //27MHz
// input reset_ok,
input wire rst_n,
output wire mreset,
output wire SCL,
inout wire SDA,
output wire [2:0] cnt_o,
output wire sda_r_out,
output wire [7:0] d_r_out,
output wire [23:0] data_out,
output wire led2
);
reg mreset_r;
reg reset1=0;
reg [31:0] Mdelay;
//assign mreset = mreset_r;
always @ (posedge en_clk or negedge rst_n) begin
//always @ (*) begin //27000/400=67.5 300/4=75 300/1 = 300
if ((rst_n==0)) begin
Mdelay <= 0;
mreset_r <= 1'b0;
reset1 <= 1'b0;
end else begin
if (Mdelay <= (32'd27_000_000*6)) begin // 延时 ?s
Mdelay <= Mdelay+1;
mreset_r <= 1'b0;
if (Mdelay == (32'd27_000_000*2)) reset1 <= 0;
else reset1 <= 1'b1;
end else begin
mreset_r <= 1'b1;
reset1 <= 1'b1;
end
end
end
//****************frequency******************
reg [8:0] cnt_delay;
reg [2:0]cnt;
//always @ (posedge CLK or negedge RST_N) begin
// if(!RST_N) begin
always @ (posedge en_clk/*CLK or negedge RST_N*/) begin
//if(!RST_N)
if (reset1==0) begin
cnt_delay <= 9'd0;
end
//else if(cnt_delay>=9'd125) cnt_delay <=9'd0; //SCL = 400KHZ ; T=10us
else if(cnt_delay>=9'd240) cnt_delay <=9'd0; //270000/125=215 270000/240 `= 120 27000/300=90khz 27000/500 = 54khz
else cnt_delay <= cnt_delay +1'b1;
end
always @ (posedge en_clk/*CLK or negedge RST_N*/) begin
//if(!RST_N)
if (reset1==0) cnt <=3'd0;
else begin
case (cnt_delay)
9'd60: cnt <= 3'd1; //SCL高电平中间采样点
9'd120: cnt <= 3'd2; //SCL下降沿
9'd180: cnt <= 3'd3; //SCL低电平中间采样点,用于数据的变化
9'd0: cnt <= 3'd0; //SCL上升沿
default : cnt <= 3'd5;
endcase
end
end
`define SCL_POS (cnt==3'd0)
`define SCL_HIG (cnt==3'd1)
`define SCL_NEG (cnt==3'd2)
`define SCL_LOW (cnt==3'd3)
reg scl_r; //定义SCL的时序脉冲,1为高电平,0为低电平
always @ (posedge en_clk/*CLK or negedge RST_N*/) begin
//if(!RST_N)
if (reset1==0)
scl_r <= 1'b0;
else if(cnt == 3'd2) scl_r<= 1'b0; //
else if(cnt == 3'd0) scl_r<= 1'b1; //
end
parameter IDLE = 4'd0,
Start = 4'd1,
Add1 = 4'd2,
Ack1 = 4'd3,
Add2 = 4'd4,
Ack2 = 4'd5,
Data = 4'd6,
Ack3 = 4'd7,
Ass = 4'd8,
End = 4'd9,
Ack4 = 4'd10;
reg [6:0]state; //状态寄存器
reg [7:0] db_r; //IIC上要传送的数据寄存器
reg sda_r; //输出数据寄存器
reg sda_link; //双向传输控制
reg [3:0]sda_num; //并转串数据发送计数器寄存器
//reg ack;
reg[23:0]data;
reg[1:0] state1;
reg[4:0] LUT_INDEX;
reg[15:0]LUT_DATA;
reg scl_bp_r = 0;
reg [7:0] num;
assign cnt_o = cnt;
assign SCL = scl_bp_r ? 1 : scl_r;
assign SDA = sda_link ? sda_r:1'bz;
parameter LUT_SIZE = 8;//3;
always @ (posedge en_clk ) //CLK /*or negedge RST_N*/)
//if(!RST_N) begin
if (reset1==0) begin
state <= IDLE;
sda_r <= 1'b1;
sda_link <= 1'b0;
sda_num <= 4'd0;
num <= 8'd0;
//ack <= 1'b0;
end
else begin
case(state)
IDLE:begin
if (`SCL_NEG) begin
sda_num <= sda_num + 1'd1;
// if (sda_num == 8'd15) begin //250 = 25 不行 , 15 行
if (sda_num == 4'd2) begin //250 = 25 不行 , 15=10 行
state <= Start;
end else begin
sda_link <= 1;
sda_r <= 1;
state <= IDLE;
end
end else begin
sda_link <= 1;
sda_r <= 1;
state <= IDLE;
end
/* sda_link <= 1;
sda_r <= 1;
state <= Start;
*/
end
Start:begin
if(`SCL_HIG)begin
sda_link <=1'b1;
sda_r <=1'b0; //SCL在高电平期间将SDA拉低
sda_num <=4'd0;
state <= Ass;
end
else state <= Start;
end
Ass:begin
if (LUT_INDEX == 6)
data = {8'h8a,LUT_DATA};
else
data = {8'h54,LUT_DATA};
db_r = data[23:16];
state = Add1;
sda_link = 1'b1;
sda_num = 4'd0;
end
Add1:begin
if(`SCL_LOW) begin
if(sda_num==4'd8)begin
sda_r <= 1'b1; //数据发送完毕后释放SDA总线
sda_link <= 1'b0; //双向输入输出口设为高阻态
sda_num <= 4'd0;
state <= Ack1;
end
else begin
sda_num <= sda_num +1'b1;
sda_link <= 1'b1;
state <= Add1;
case (sda_num) //串行数据传送,从高位开始传送
4'd0 : sda_r <= db_r[7];
4'd1 : sda_r <= db_r[6];
4'd2 : sda_r <= db_r[5];
4'd3 : sda_r <= db_r[4];
4'd4 : sda_r <= db_r[3];
4'd5 : sda_r <= db_r[2];
4'd6 : sda_r <= db_r[1];
4'd7 : sda_r <= db_r[0];
default : ;
endcase
end
end
else state <=Add1;
end
Ack1:begin
if(`SCL_NEG)begin
state <= Add2;
db_r <= data[15:8];
end
else state <= Ack1;
end
Add2:begin
if(`SCL_LOW) begin
if(sda_num==4'd8)begin
sda_r <= 1'b1; //数据发送完毕后释放SDA总线
sda_link <= 1'b0; //双向输入输出口设为高阻态
sda_num <= 4'd0;
state <= Ack2;
end
else begin
sda_num <= sda_num +1'b1;
sda_link <= 1'b1;
state <= Add2;
case (sda_num) //串行数据传送,从高位开始传送
4'd0 : sda_r <= db_r[7];
4'd1 : sda_r <= db_r[6];
4'd2 : sda_r <= db_r[5];
4'd3 : sda_r <= db_r[4];
4'd4 : sda_r <= db_r[3];
4'd5 : sda_r <= db_r[2];
4'd6 : sda_r <= db_r[1];
4'd7 : sda_r <= db_r[0];
default : ;
endcase
end
end
else state <=Add2;
end
Ack2:begin
if(`SCL_NEG)begin
state <= Data;
db_r <= data[7:0];
end
else state <= Ack2;
end
Data:begin
if(`SCL_LOW) begin
if(sda_num==4'd8)begin
sda_r <= 1'b1; //数据发送完毕后释放SDA总线
sda_link <= 1'b0; //双向输入输出口设为高阻态
sda_num <= 4'd0;
state <= Ack3;
end
else begin
sda_num <= sda_num +1'b1;
sda_link <= 1'b1;
state <= Data;
case (sda_num) //串行数据传送,从高位开始传送
4'd0 : sda_r <= db_r[7];
4'd1 : sda_r <= db_r[6];
4'd2 : sda_r <= db_r[5];
4'd3 : sda_r <= db_r[4];
4'd4 : sda_r <= db_r[3];
4'd5 : sda_r <= db_r[2];
4'd6 : sda_r <= db_r[1];
4'd7 : sda_r <= db_r[0];
default : ;
endcase
end
end
else state <=Data;
end
Ack3:begin
if(`SCL_NEG)begin
if (LUT_INDEX == LUT_SIZE-1 ) begin
LUT_INDEX = 0;
num = num+8'd1;
end
else
LUT_INDEX = LUT_INDEX +1;
if (num > 8'd10) state <= End; //删此则永远反复便于观察
else //删此则永远反复便于观察
if (LUT_INDEX==6) begin
state <= Ass;
end else begin
state <= IDLE;
end
end
else begin
state <= Ack3;
end
end
End:begin
if(`SCL_LOW)begin
sda_r <= 1'b1; //原来=0
sda_link <= 1'b1;
scl_bp_r <= 1'b1;
state <= End;
end
else begin
state <= End;
end
end
default: state <= IDLE;
endcase
end
assign d_r_out = db_r;
assign data_out = data;
assign sda_r_out = sda_r;
/ Config Data LUT //
/*
always @(*) // 配置ADV7390芯片,输出内部测试图案
begin
case (LUT_INDEX)
// 0 : LUT_DATA = 16'h1702 ; // 软件复位
0 : LUT_DATA = 16'h001c ; // 所有DAC使能。PLL使能(16×)
1 : LUT_DATA = 16'h82cb ; //
2 : LUT_DATA = 16'h8440 ; //
// 3 : LUT_DATA = 16'hFFFF ; //
// 4 : LUT_DATA = 16'hFFFF ; //
default : LUT_DATA = 0;
endcase
end
*/
always @(*) // 配置ADV7390芯片,输出PAL制式的视频流
begin
case (LUT_INDEX)
// 0 : LUT_DATA = 16'h1702 ; // 软件复位
0 : LUT_DATA = 16'h001c ; // 所有DAC使能。PLL使能(16×)
1 : LUT_DATA = 16'h001c ; // 所有DAC使能。PLL使能(16×)
2 : LUT_DATA = 16'h0100 ; // 标清输入模式
3 : LUT_DATA = 16'h8011 ; // PAL标准。SSAF亮度滤波器使能。1.3 MHz色度滤波器使能
4 : LUT_DATA = 16'h82c3 ; // 像素数据有效。CVBS/Y-C(S视频)输出
5 : LUT_DATA = 16'h8ccb ; // PAL模式(27 MHz输入时钟)下CVBS和/或S视频(Y-C)输出的副载波频率寄存器:
6 : LUT_DATA = 16'h092a ; //
// 6 : LUT_DATA = 16'h8d8a ; //
// 7 : LUT_DATA = 16'h8e09 ; //
// 8 : LUT_DATA = 16'h8f2a ; //
7 : LUT_DATA = 16'h001c ; // 所有DAC使能。PLL使能(16×)
default : LUT_DATA = 0;
endcase
end
reg led2_t;
assign led2 = led2_t;
reg[31:0] timer_cnt2;
always @ (posedge en_clk) //27000/400=67.5 300/4=75 300/1 = 300
if (reset1==0) begin
//cnt_delay <= 9'd0;
end
else begin
if(timer_cnt2 >=(32'd13_500_000)) //模拟1S时间 30MHz=30_000_000Hz
begin
// timer_cntx <= timer_cntx+1;
led2_t<=~led2_t;
timer_cnt2<=32'd0;
end
else
begin
//timer_cntx <= timer_cntx;
led2_t<=led2_t;
timer_cnt2<=timer_cnt2+32'd1;
end
end
endmodule
看一看波形图:
我原来程序由于副载波频率可能IIC有问题,干脆8c\8d\8e\8f四个同一次传,终于搞定。
四、再来干货
`timescale 1 ns / 1 ps
module video_axi4
(
input rst_n,
output [7:0] en_d,
output en_vs,
output en_hs,
input en_clk,
output [10:0] colp,
output [9:0] rowp
);
reg [10:0] cols = 0; //0---1727
reg [9:0] row = 0; //0---624
reg [7:0] data; //8位数据
// y cb cr
reg [23:0] white = {8'heb, 8'h80, 8'h80};//{8'd235, 8'd128, 8'd128};
reg [23:0] yellow = {8'hd2, 8'h10, 8'h92};//{8'd162, 8'd44, 8'd142};
reg [23:0] cyan = {8'haa, 8'ha6, 8'h10};//{8'd131, 8'd156, 8'd44};
reg [23:0] green = {8'h91, 8'h36, 8'h22};//{8'd112, 8'd72, 8'd58};
reg [23:0] magenta = {8'h6a, 8'hca, 8'hde};//{8'd84, 8'd184, 8'd198};
reg [23:0] red = {8'h51, 8'h5a, 8'hf0};//{8'd65, 8'd100, 8'd212};
reg [23:0] blue = {8'h29, 8'hf0, 8'h6e};//{8'd35, 8'd212, 8'd114};
reg [23:0] black = {8'h10, 8'h80, 8'h80};//{8'd16, 8'd128, 8'd128};
reg [23:0] cur_color;
//产生图像数据,数据 8 个 8 个出
function [7:0] colorValue;
input [10:0] cols; //col = 288~1727
begin
if(452 > cols)
cur_color = black;
else if(652 >cols)
cur_color = blue;
else if(812 > cols)
cur_color = red;
else if(992 > cols)
cur_color = magenta;
else if(1172 > cols)
cur_color = green;
else if(1352 > cols)
cur_color = cyan;
else if(1532 > cols)
cur_color = yellow;
else
cur_color = white;
//* Y
if(cols[0] == 1'b1) //288 = 120h
colorValue = cur_color[23:16];// y
//* Cr and Cb
else if(cols[1] == 1'b0)
colorValue = cur_color[15:8]; //* cb
else
colorValue = cur_color[7:0]; //* Cr
end
endfunction
function [7:0] EAV;
input [9:0] row;
begin
if (row <= 311) begin
if (row < 22)
EAV = 8'hb6;
else if (row < 310)
EAV = 8'h9d;
else
EAV = 8'hb6;
end else begin
if (row < 335)
EAV = 8'hf1;
else if (row < 623)
EAV = 8'hda;
else
EAV = 8'hf1;
end
end
endfunction
function [7:0] SAV;
input [9:0] row;
begin
if (row <= 311) begin
if (row < 22)
SAV = 8'hab;
else if (row < 310)
SAV = 8'h80;
else
SAV = 8'hab;
end else begin
if (row < 335)
SAV = 8'hec;
else if (row < 623)
SAV = 8'hc7;
else
SAV = 8'hec;
end
end
endfunction
reg hsvs;
always@(negedge en_clk) //仿真用
begin
if ((rst_n==0))begin
cols = 11'd0;
row = 10'd0;
data = 8'd0;
hsvs = 0;
end else begin
hsvs = ~hsvs;
// 0 1 2 3 4 <= col <= 283 284 285 286 287 288 <= col <=1727
//0~21行 FF 0 0 B6 0x80和0x10交替 FF 0 0 AB 0x80和0x10交替
//22~309行 FF 0 0 9d 0x80和0x10交替 FF 0 0 80 视频数据
//310~311行 FF 0 0 b6 0x80和0x10交替 FF 0 0 ab 0x80和0x10交替
//312~334行 FF 0 0 f1 0x80和0x10交替 FF 0 0 ec 0x80和0x10交替
//335~622行 FF 0 0 da 0x80和0x10交替 FF 0 0 c7 视频数据
//623~624行 FF 0 0 f1 0x80和0x10交替 FF 0 0 ec 0x80和0x10交替
if (cols <= 11'd283) begin
if (cols < 11'd3) begin
case (cols)
0:data = 8'hff; //0
1:data = 8'h00; //1
2:data = 8'h00; //2
endcase
end else begin
if (cols==11'd3) begin
data = EAV(row); //3
end else begin
data = (cols[0] == 0) ? 8'h80 : 8'h10; //4~283
end
end
end else begin
if (cols < 11'd287) begin
case (cols)
284:data = 8'hff; //284
285:data = 8'h00; //285
286:data = 8'h00; //286
endcase
end else begin
if (cols==11'd287) begin
data = SAV(row); //287
end else begin
if ((row >= 22 && row <= 309) || (row >= 335 && row <= 622))
data = colorValue(cols); //288~1727
else
data = (cols[0] == 0) ? 8'h80 : 8'h10; //288~1727
end
end
end
if (cols < 11'd1727)
cols = cols + 1'b1;
else begin
cols = 11'd0;
hsvs = 0;
if (row < 10'd624)
row = row + 1'b1;
else row = 10'd0;
end
end
end
assign en_d = data;
assign en_vs = hsvs;
assign en_hs = ~hsvs;
assign colp = cols;
assign rowp = row;
endmodule
写在最后:
我在网上找了很多资料:
很难找ADV7391的Verilog源码,我将此篇贡献于此。
写一个ADV7391的Virelog调试过程相关推荐
- dotnet core 应用是如何跑起来的 通过自己写一个 dotnet host 理解运行过程
在上一篇博客是使用官方提供的 AppHost 跑起来整个 dotnet 程序.本文告诉大家在 dotnet 程序运行到托管代码之前,所需要的 Native 部分的逻辑.包括如何寻找 dotnet 运行 ...
- 用.netcore写一个简单redis驱动,调试windows版本的redis
1. 下载windows版本的redis 2.开发环境vs2017 新建一个 .net core控制台. private static Socket socket = new Socket(Addr ...
- linux下Qt编写串口调试助手,如何在linux下用QT写一个简单的串口调试助手
如何在linux下用QT写一个简单的串口调试助手 QT5串口类 在QT5以前,编写串口一般使用的是qextserialport类,但在QT5之后有了QT自带的串口类SerialPort(串口基础类)和 ...
- VB.net写一个简易串口RS485调试助手
最近在调试带rs485串口通讯的设备,项目上主要是用PLC和串口通讯,因为PLC有集成好的串口块,使用起来比较容易,为了方便测试,就想着用上位机写一个简易的串口通讯程序,用于调试. 在网上查找了一些资 ...
- 一个完整的gdb调试过程以及一些常用的命令
1. 启动调试 <span style="color:#000000"><code>gcc -g test.c // 编译文件,生成可执行程序,并且给文件加 ...
- 单片机shell命令_单片机裸机下写一个自己的shell调试器
result = paramBuffer[i] -'A'+10; } else { //出现范围之外的数据,返回1 return 1; } valueResult += (u32)(result*fa ...
- ChatGPT实现用C语言写一个扫雷小游戏
前几天我们利用 ChatGPT实现用C语言写一个学生成绩管理系统 其过程用时不到30秒,速度惊人 今天又让ChatGPT用C语言写了一个扫雷小游戏,它的回答是:抱歉,我是AI语言模型,无法编写程序. ...
- 案例一: 使用IDA PRO+OllyDbg+PEview 追踪windows API 动态链接库函数的调用过程。 首先用文本编辑器写一个C++源程序名为StackFrame.cpp ,代码如下:
案例一: 使用IDA PRO+OllyDbg+PEview 追踪windows API 动态链接库函数的调用过程. 首先用文本编辑器写一个C++源程序名为StackFrame.cpp ,代码如下: 1 ...
- 手把手教你写一个串口调试助手
硬件攻城狮 2022-05-20 14:05 发表于广东 果果小师弟. 电子信息工程硕士在读,分享单片机.嵌入式linux.物联网等知识,致力于打造最硬核的嵌入式技术公众号. 摘要:前段时间发布了一个 ...
最新文章
- 天猫国际618一骑绝尘,占中国跨境进口电商总订单超七成
- 锐起无盘服务器安装教程,锐起无盘安装方法 图文教程
- AIgorand区块链中VRF随机函数的应用
- 强烈推荐 MicroSoft Office OneNote
- endpointimpl怎么填参数_App拉新:以老拉新活动怎么做?
- 智能手机RAM和ROM的区别以及SD卡的作用
- anaconda moviepy_Anaconda、Jupyter Notebook安装与使用
- 使用SoapUI生成wsdl文件客户端(二)
- iOS混排计算中英文个数,中午算一个字符,英文和符号算半个字符
- 关于Initializing Spring root WebApplicationContext解决方法
- HTML怎么引入字体包中的字体
- jclasslib 查看类信息
- 【黄啊码】关于vue的PC端和手机端框架
- AtCoder Grand Contest 007题解
- 我要用生锈的机关枪击穿现在
- oracle 查看用户配额,【Quota】获取及调整用户表空间配额方法
- 运维:你们 JAVA 服务怎么又又又又出问题了,内存降不下来
- 【Windows】【VS】error C2220: 以下警告被视为错误
- 两种批处理方式(操作系统)
- C语言利用瑞丽分布产生高斯白噪声
热门文章
- Java毕设项目家政服务公司管理信息计算机(附源码+系统+数据库+LW)
- 程序员版的“鱿鱼游戏”趣图来了!
- 《山东体育科技》是核心期刊吗?
- uniapp引入字体
- 陕西农民挖地基,竟然挖出2700年前的青铜家谱!专家:这是中国第一盘
- android 利用重力感应监听 来电时翻转手机后静音。
- gitlab 社区版 多人 review 实现
- linux sockaddr in,Linux C中sockaddr和sockaddr_in的区别
- QCharts - 5.示例-条形统计图
- AI导出图片分辨率增大问题