首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

原创单总线传输协议b2s

原创单总线传输协议b2s

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        
the king of nerds
返回列表