文档库 最新最全的文档下载
当前位置:文档库 › verilog实现串并转换

verilog实现串并转换

//-------------------------------------------ptosda.v 文件开始-------------------------------------------
/************************************************************************
*** 模块功能:按照设计要求把输入的4位平行数据转换为协议要求的串行数据流
*** 由scl和sda配合输出
*** 本模块为RTL可综合模块,已通过综合后门级网表仿真
*************************************************************************/
module ptosda (sclk,d_ena,scl,sda,rst,data);
input sclk, rst, d_ena;
input [3:0] data;
output scl;
inout sda; //定义sda为双向的串行总线

reg scl, link_sda, sdabuf;
reg [3:0] databuf;
reg [7:0] state;

assign sda = link_sda? sdabuf: 1'bz; //link_sda 控制 sdabuf输出到串行总线上

parameter ready = 8'b0000_0000,
start = 8'b0000_0001,
bit1 = 8'b0000_0010,
bit2 = 8'b0000_0100,
bit3 = 8'b0000_1000,
bit4 = 8'b0001_0000,
bit5 = 8'b0010_0000,
stop = 8'b0100_0000,
IDLE = 8'b1000_0000;

always @(posedge sclk or negedge rst) //由输入的sclk时钟信号产生串行输出时钟scl
begin
if(!rst)
scl <= 1;
else
scl <= ~scl;
end

always @(posedge d_ena) //从并行data端口接收数据到databuf保存
begin
databuf <= data;
end

//----主状态机:产生控制信号,根据databuf中保存的数据,按照协议产生sda串行信号
always @(negedge sclk or negedge rst)
if (!rst)
begin
link_sda<=0; // 把sdabuf与sda串行总线连接
state <= ready;
sdabuf<= 1;
end
else begin
case(state)
ready: if (d_ena) //并行数据已经到达
begin
link_sda<=1; // 把sdabuf与sda串行总线连接
state <= start;
end
else //并行数据尚未到达
begin
link_sda<=0; //把sda总线让出,此时sda可作为输入
state <= ready;
end
start: if (scl && d_ena) //产生sda的开始信号
begin
sdabuf<=0; //在sda 连接的前提下,输出开始信号
state <= bit1;
end
else state <= start;
bit1: if (!scl) //在scl为低电平时送出最高位databuf[3]
begin sdabuf<=databuf[3];
state <= bit2;
end
else state <= bit1;
bit2: if (!scl) //在scl为低电平时送出次高位databuf[2]
begin sdabuf<=databuf[2];
state <= bit3;
end
else state <= bit2;
bit3: if (!scl) //在scl为低电平时送出次低位databuf[1]


begin sdabuf<=databuf[1];
state <= bit4;
end
else state <= bit3;
bit4: if (!scl) //在scl为低电平时送出最低位databuf[0]
begin sdabuf<=databuf[0];
state <= bit5;
end
else state <= bit4;
bit5: if (!scl) //为产生结束信号做准备,先把sda变为低
begin sdabuf<=0;
state <= stop;
end
else state <= bit5;
stop: if (scl) //在scl为高时把sda由低变高产生结束信号
begin sdabuf<=1;
state <= IDLE;
end
else state <= stop;
IDLE: begin link_sda <= 0; // 把sdabuf与sda串行总线脱开
state <= ready;
end
default: begin link_sda <= 0;
sdabuf<=1;
state <= ready;
end
endcase
end

endmodule

相关文档