|
我写了个程序,反复修改,仍然有问题。但是,我已经找不出问题所在了。麻烦帮忙看下。程序的功能如下:
整个文件共有4个进程:一个进程用来实现软件复位;一个用来赋值数据端口;一个是用来产生I2C总线始终的控制信号;再有一个是用来实现芯片配置。
产生I2C总线的进程设计如下:
I2C数据率400Kbps,输入时钟10MHZ,分频系数25;当计数器计数到5、10、15、20时分别将phase0、phase1、phase2、phase3置1;然后在下一个SysClk10M时钟将其置0;如图
实现芯片配置进程工作如下:
在start_up信号为1时,启动状态机。传输方式:启动->传输从机地址->传输IC芯片子地址->传输配置数据(一个字节+Ack)->再次启动->传输从机地址->传输IC芯片子地址->传输配置数据(一个字节+Ack)->完成。
I2C时序模拟如下:
问题:
1、 next_state的运行状态与程序设定不符
2、 SignalTap中显示的状态编码出现了程序中为定义的状态(如101、110),为什么?
附件给出了SignalTap实时数据波形截图以及工程文件源码及TopFile。
恭请赐教
由于无法在文本中添加图片,详细的说明以附件形式给出。下面是源码:
//**************************************************
//SAA7126 initial configuration based on IIC bus .
//SysClk10M=10MHZ
//IIC bus data rate=400kb/s
//Clock used in program =25*400khz
//Clock_Div=25
//**************************************************
module SAA7126Control(
SysClk10M, //10MHZ
//输出端口
SCL, //I2C时钟
MP, //VGA数据输出
DARST, //软件复位SAA7126复位管脚,Active Low
//双向端口
SDA);
//输入端口声明
input SysClk10M;
//输出端口声明
output DARST,
SCL;
output[7:0] MP;
reg DARST,SCL;
reg [7:0] MP;
reg[7:0] data_buf; //配置数据暂存寄存器
inout SDA;
//计数器
reg[23:0]count; //复位计数器
reg[1:0]send_num; //寄存器地址
reg[7:0]CLK_div; //分频系数
//状态变量声明
reg[2:0] next_state; //状态机状态变量
reg[3:0] inner_state; //字节传输内部状态变量
reg phase0,phase1,phase2,phase3;//SCL时钟的四个相位定义
reg start_up; //状态机启动信号
reg SDA_buf;
reg SDA_enable; //SDA输入输出控制
reg data_en; //将相机数据送到MP口使能
//字节传输状态定义
parameter first= 4'b0001, //第1位
second= 4'b0010, //第2位
third= 4'b0011, //第3位
fourth= 4'b0100, //第4位
fifth= 4'b0101, //第5位
sixth= 4'b0110, //第6位
seventh=4'b0111, //第7位
eighth= 4'b1000, //第8位
ack= 4'b1001; //第9位
parameter start= 3'b000, //开始位
slave_addr=3'b001,
sub_addr= 3'b010,
send_data= 3'b011,
stop= 3'b100;//停止位
//持续赋值;
assign SDA=SDA_enable?SDA_buf:1'bZ;
//寄存器配置表
reg[7:0] slave_address=8'h88; //默认为写SAA7126寄存器配置
reg[7:0] sub_address[2:1];
reg[7:0] data[2:1]; //配置寄存器列表
reg[7:0] byte_buffer;
//复位操作(软件复位)
//复位时间为1s
always @ (posedge SysClk10M)
begin
if(count==24'd10000000)
begin
DARST<=1'b1;
start_up<=1'b1;
SDA_enable<=1'b1;
//Initialization********
sub_address[2]=8'h6b;
sub_address[1]=8'h3a;
data[2]=8'h93;
data[1]=8'h12;
//**********************
end
else begin
count<=count+24'b1;
start_up<=1'b0;
SDA_enable<=1'b0;
DARST<=1'b0;
end
end
//图像数据送入到SAA7126
always@(posedge SysClk10M)
begin
if(data_en==1'b1)
MP[7:0]<=8'b0000_0000;
end
//相位定义
always@(posedge SysClk10M)
begin
if(!start_up)begin
phase0<=0;
phase1<=0;
phase2<=0;
phase3<=0;
CLK_div<=0;
end
else begin
if(CLK_div==24)
CLK_div<=0;
else CLK_div<=CLK_div+8'b1;
if(phase0)
phase0<=0;
else if(CLK_div==5)
phase0<=1;
if(phase1)
phase1<=0;
else if(CLK_div==10)
phase1<=1;
if(phase2)
phase2<=0;
else if(CLK_div==15)
phase2<=1;
if(phase3)
phase3<=0;
else if(CLK_div==20)
phase3<=1;
end
end
//配置寄存器
always@(posedge SysClk10M)
begin
if(!start_up)begin
next_state<=start;
inner_state<=first;
SDA_buf<=1'b1;//总线上的器件都释放总线
SCL<=1'b1; //总线上的器件都释放总线
//复位初始化
data_en<=1'b0;
send_num<=1;
end
else begin
if(phase0)
SCL<=1;
else if(phase2)
SCL<=0;
case(next_state)
//启动信号*****************
start:begin
if(phase1) begin
SDA_buf<=0;
next_state<=slave_addr;
end
end
//送从地址******************
slave_addr:
case(inner_state)
first:
if(phase3) begin
SDA_buf<=slave_address[7];
inner_state<=second;
end
second:
if(phase3) begin
SDA_buf<=slave_address[6];
inner_state<=third;
end
third:
if(phase3) begin
SDA_buf<=slave_address[5];
inner_state<=fourth;
end
fourth:
if(phase3) begin
SDA_buf<=slave_address[4];
inner_state<=fifth;
end
fifth:
if(phase3) begin
SDA_buf<=slave_address[3];
inner_state<=sixth;
end
sixth:
if(phase3) begin
SDA_buf<=slave_address[2];
inner_state<=seventh;
end
seventh:
if(phase3) begin
SDA_buf<=slave_address[1];
inner_state<=eighth;
end
eighth:
if(phase3) begin
SDA_buf<=slave_address[0];
inner_state<=ack;
end
ack: begin
if(phase3)
SDA_buf<=SDA;
if(phase1)begin
if(SDA_buf==1)begin
next_state<=start;
end
else begin
next_state<=sub_addr;
inner_state<=first;
byte_buffer<=sub_address[send_num];
end
end
end
endcase
//送子地址
sub_addr:
case(inner_state)
first:
if(phase3) begin
SDA_buf<=byte_buffer[7];
inner_state<=second;
end
second:
if(phase3) begin
SDA_buf<=byte_buffer[6];
inner_state<=third;
end
third:
if(phase3) begin
SDA_buf<=byte_buffer[5];
inner_state<=fourth;
end
fourth:
if(phase3) begin
SDA_buf<=byte_buffer[4];
inner_state<=fifth;
end
fifth:
if(phase3) begin
SDA_buf<=byte_buffer[3];
inner_state<=sixth;
end
sixth:
if(phase3) begin
SDA_buf<=byte_buffer[2];
inner_state<=seventh;
end
seventh:
if(phase3) begin
SDA_buf<=byte_buffer[1];
inner_state<=eighth;
end
eighth:
if(phase3) begin
SDA_buf<=byte_buffer[0];
inner_state<=ack;
end
ack: begin
if(phase3)
SDA_buf<=SDA;
if(phase1)begin
if(SDA_buf==1)begin
next_state<=start;
end
else begin
next_state<=send_data;
data_buf<=data[send_num];
inner_state<=first;
end
end
end
endcase
//配置寄存器
send_data:
case(inner_state)
first:
if(phase3) begin
SDA_buf<=data_buf[7];
inner_state<=second;
end
second:
if(phase3) begin
SDA_buf<=data_buf[6];
inner_state<=third;
end
third:
if(phase3) begin
SDA_buf<=data_buf[5];
inner_state<=fourth;
end
fourth:
if(phase3) begin
SDA_buf<=data_buf[4];
inner_state<=fifth;
end
fifth:
if(phase3) begin
SDA_buf<=data_buf[3];
inner_state<=sixth;
end
sixth:
if(phase3) begin
SDA_buf<=data_buf[2];
inner_state<=seventh;
end
seventh:
if(phase3) begin
SDA_buf<=data_buf[1];
inner_state<=eighth;
end
eighth:
if(phase3) begin
SDA_buf<=data_buf[0];
inner_state<=ack;
end
ack: begin
if(phase3)
SDA_buf<=SDA;
if(phase1)begin
if(SDA_buf==1)begin
next_state<=start;
end
else begin
send_num<=send_num+2'b1;
if(send_num==2)begin
next_state<=stop;
SDA_buf<=0;
end
else next_state<=start;
end
end
end
endcase
//发送“停止”命令
stop: begin
if(phase1)
SDA_buf<=1;
next_state<=stop;
end
//缺省情况
default:
next_state<=start;
endcase
end
end
endmodule |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?我要注册
x
|