ps. 带★号处可根据需要进行修改.
发送端源码:
/******************************************************************************************
File Name: b2s_transmitter.v
Function: b2s发送端, 默认发送32bit数据,数据宽度可更改
Version: 2013-5-13 v1.0
********************************************************************************************/
module b2s_transmitter
(
clk, //时钟基准,不限频率大小,但必须与接收端一致
din, //待发送数据
b2s_dout //b2s数据输出端口
);
parameter WIDTH=32; //★设定b2s发送数据的位宽,可根据需要进行更改
input clk;
input [WIDTH-1:0] din;
output b2s_dout;
//==============================================================
//b2s数据发送时序
//==============================================================
reg b2s_dout_r;
reg [3:0] state;
reg [9:0] cnt;
reg [4:0] count; //★与发送数据位宽保持一致(如发送32bit数据时,count宽度为5;发送8bit时,count宽度为4)
always @ (posedge clk)
begin
case(state)
//初始化
0: begin
count<=0;
b2s_dout_r<=1;
if(cnt==19) //b2s_dout_r高电平持续20个时钟
begin
state<=1;
cnt<=0;
end
else
begin
cnt<=cnt+1;
end
end
//开始信号时序
1: begin
b2s_dout_r<=0;
if(cnt==19) //b2s_dout_r低电平持续20个时钟
begin
state<=2;
cnt<=0;
end
else
begin
cnt<=cnt+1;
end
end
2: begin
b2s_dout_r<=1;
if(cnt==19) //b2s_dout_r高电平持续20个时钟
begin
cnt<=0;
state<=3;
end
else
begin
cnt<=cnt+1;
end
end
//待发送数据的逻辑电平判断
3: begin
if(din[count]==1)
state<=4;
else
state<=8;
end
//逻辑1的发送时序
4: begin
b2s_dout_r<=0;
if(cnt==9) //b2s_dout_r低电平持续10个时钟
begin
cnt<=0;
state<=5;
end
else
begin
cnt<=cnt+1;
end
end
5: begin
b2s_dout_r<=1;
if(cnt==29) //b2s_dout_r高电平持续30个时钟
begin
cnt<=0;
state<=6;
end
else
begin
cnt<=cnt+1;
end
end
//逻辑0的发送时序
8: begin
b2s_dout_r<=0;
if(cnt==29) //b2s_dout_r低电平持续30个时钟
begin
cnt<=0;
state<=9;
end
else
begin
cnt<=cnt+1;
end
end
9: begin
b2s_dout_r<=1;
if(cnt==9) //b2s_dout_r高电平持续10个时钟
begin
cnt<=0;
state<=6;
end
else
begin
cnt<=cnt+1;
end
end
//统计已发送数据位数
6: begin
count<=count+1'b1;
state<=7;
end
7: begin
if(count==WIDTH) //当一组数据所有位发送完毕,返回并继续下一次发送
begin
b2s_dout_r<=1;
if(cnt==999) //b2s_dout_r高电平持续1000个时钟
begin
cnt<=0;
state<=0;
end
else
begin
cnt<=cnt+1;
end
end
else //当一组数据未发送完毕,则继续此组下一位数据的发送
state<=3;
end
//default值设定
default: begin
state<=0;
cnt<=0;
count<=0;
end
endcase
end
assign b2s_dout=b2s_dout_r;
endmodule
接收端源码:
/******************************************************************************************
Author: Bob Liu
E-mail: shuangfeiyanworld@163.com
File Name: b2s_receiver.v
Function: b2s接收端, 默认接收32bit数据,接收数据宽度请与发送端发送数据宽度保持一致
Version: 2013-5-13 v1.0
********************************************************************************************/
module b2s_receiver
(
clk, //时钟基准,不限频率大小,但必须与发送端一致
b2s_din, //b2s发送端发送过来的信号
dout //b2s接收端解码出的数据
);
parameter WIDTH=32; //★设定b2s接收数据位数, 默认接收32bit数据,接收数据宽度请与发送端发送数据宽度保持一致
input clk;
input b2s_din;
output [WIDTH-1:0] dout;
//==================================================
//b2s_din信号边沿检测
//==================================================
reg [1:0] b2s_din_edge=2'b01;
always @ (posedge clk)
begin
b2s_din_edge[0] <= b2s_din;
b2s_din_edge[1] <= b2s_din_edge[0];
end
//==================================================
//time_cnt -- 存储b2c_din信号下降沿及其最近的下一个上升沿之间的时间
//==================================================
reg [1:0] state0;
reg [5:0] time_cnt_r;
always @ (posedge clk)
begin
case(state0)
0: begin
time_cnt_r<=0;
state0<=1;
end
1: begin
if(b2s_din_edge==2'b10)
state0<=2;
else
state0<=state0;
end
2: begin
if(b2s_din_edge==2'b01)
begin
state0<=0;
end
else
time_cnt_r<=time_cnt_r+1'b1;
end
default: begin
time_cnt_r<=0;
state0<=0;
end
endcase
end
wire [5:0] time_cnt;
assign time_cnt=(b2s_din_edge==2'b01)?time_cnt_r:'b0; //当b2s_din上升沿瞬间,读取time_cnt_r的值
//==================================================
//b2s解码时序
//==================================================
reg [2:0] state;
reg [4:0] count; //★与接收数据位数保持一致(如接收32bit数据时,count宽度为5;接收8bit时,count宽度为4)
reg [WIDTH-1:0] dout_r;
always @ (posedge clk)
begin
case(state)
0: begin
count<=WIDTH;
if((time_cnt>15)&&(time_cnt<25)) //判断起始信号
state<=1;
else
state<=state;
end
1: begin
if((time_cnt>5)&&(time_cnt<15)) //判断接收到的位是否为1
begin
dout_r[WIDTH-1]<=1;
state<=2;
end
else if((time_cnt>25)&&(time_cnt<35)) //判断接收到的位是否为0
begin
dout_r[WIDTH-1]<=0;
state<=2;
end
else
begin
state<=state;
end
end
2: begin
count<=count-1'b1; //每读取一个bit,count计数减1
state<=3;
end
3: if(count==0) //数据读取完毕,返回并继续下一组数据的读取
begin
state<=0;
end
else
state<=4; //数据未读取完毕,则进行移位
4: begin
dout_r<=(dout_r>>1); //数据右移1位
state<=1;
end
default: begin
state<=0;
count<=WIDTH;
end
endcase
end
assign dout=(count==0)?dout_r:dout; //每当一组数据读取完毕,则更新一次dout的值
endmodule
也许有些盆友第一次看到上面的代码,不知如何调用,所以下面给出调用示例作为参考。
调用发送端,通过单个I/O发送出一组32bit数据:
/******************************************************************************************
Author: Bob Liu
E-mail: shuangfeiyanworld@163.com
Function: b2s功能测试:通过b2s transmitter模块将预置的32bit数据发送出去
Version: 2013-5-13 v1.0
********************************************************************************************/
module b2s_transmitter_test
(
input clk, //基准时钟
output b2s_dout //b2s数据输出端口
);
parameter WIDTH=32; //★设定b2s发送和接收数据位宽,此处可根据需要进行修改
//==============================================================
//预置待发送数据
//==============================================================
wire [WIDTH-1:0] din;
assign din='b01010101_00111100_11011100_11001111; //★此处可根据需要进行修改,不限于固定数值
//================================
//调用b2s_transmitter模块
//================================
b2s_transmitter
#
(
.WIDTH(WIDTH) //例化发送数据位宽
)
b2s_transmitter_isnt0
(
.clk(clk), //时钟基准,不限频率大小,但必须与接收端一致
.din(din), //待发送数据
.b2s_dout(b2s_dout) //b2s数据输出端口
);
endmodule
调用接收端,解码发送端所发出的32bit数据:
/******************************************************************************************
Author: Bob Liu
E-mail: shuangfeiyanworld@163.com
Function: b2s功能测试:通过b2s receiver模块进行对b2s transmitter发送的数据进行接收解码
Version: 2013-5-13 v1.0
********************************************************************************************/
module b2s_receiver_test
(
input clk, //基准时钟
input b2s_dout, //b2s发送端发送过来的信号
output [31:0] dout //解码出的32bit数据
);
parameter WIDTH=32; //★设定b2s发送和接收数据位数,此处可根据需要进行修改
//================================
//调用b2s_receiver模块
//================================
b2s_receiver
#
(
.WIDTH(WIDTH) //例化接收数据位宽
)
b2s_receiver_inst0
(
.clk(clk), //时钟基准,不限频率大小,但必须与发送端一致
.b2s_din(b2s_dout), //b2s发送端发送过来的信号
.dout(dout) //b2s接收端解码出的数据
);
endmodule |