SPI接口设计(一)

2 篇文章 0 订阅

信号列表:

 项目要求:

模块工作时钟为100MHz;

当收到din_vld=1时,产生要求的波形。其中SCK的周期为1M;MOSI输出值为8'h37;

SCK和MOSI可以允许由20ns的偏差。

 设计思路:

8个bit,一个bit是1M=1000ns,模块时钟是100MHz=10ns,因此一个bit是需要有100个周期的,首先设计两个计数器。一个数每个bit中的时钟周期的个数(数那100个),另一个数有多少了bit(8个bit);

always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        cnt0 <= 0;
    end
    else if(add_cnt0)begin
        if(end_cnt0)
            cnt0 <= 0;
        else
            cnt0 <= cnt0 + 1;
    end
end

assign add_cnt0 = flag_add;
assign end_cnt0 = add_cnt0 && cnt0==100-1 ;

always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        cnt1 <= 0;
    end
    else if(add_cnt1)begin
        if(end_cnt1)
            cnt1 <= 0;
        else
            cnt1 <= cnt1 + 1;
    end
end

assign add_cnt1 = end_cnt0;
assign end_cnt1 = add_cnt1 && cnt1== 8-1;

接下来就是设计SCK信号,我们让SCK信号在每bit中数周期的时候,数到第一个周期的时候开始变为1,数到一半变为0;

这样就有了我们的SCK信号:


always  @(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
        sck <= 0;
    end
    else if(add_cnt0 && cnt0==1-1)begin
        sck <= 1;
    end
    else if(add_cnt0 && cnt0==50-1)begin
        sck <= 0;
    end
end

对于MOSI的数据输出,在初始值的位置赋值,设计如下代码:


    always  @(posedge clk or negedge rst_n)begin
        if(rst_n==1'b0)begin
            mosi <= 0;
        end
        else if(add_cnt0 && cnt0== 1-1)begin
            mosi <= data[7-cnt1];
        end
    end

assign data = 8'h37;

这样我们就设计完了我们所需要的信号,但是我们还需要继续补充一个flag_add的信号,这个是我们自己设计的信号:

   
    always  @(posedge clk or negedge rst_n)begin
        if(rst_n==1'b0)begin
            flag_add <= 0;
        end
        else if(en)begin
            flag_add <= 1;
        end
        else if(end_cnt1)begin
            flag_add <= 0;
        end
    end

此时,就完成了我们的项目。

完整代码如下:

module SPI_1(
    clk    ,
    rst_n  ,
        ,
    en     ,
    sck    ,
    mosi
    );


    input               clk    ;
    input               rst_n  ;
  
    input               en      ;

    output              mosi   ;
    output              sck    ;

    reg                 mosi   ;
    reg                 sck    ;
    reg                 flag_add;
    reg     [6:0]       cnt0   ;
    reg     [4:0]       cnt1   ;
    wire                add_cnt0;
    wire                end_cnt0;
    wire                add_cnt1;
    wire                end_cnt1;

    wire    [7:0]       data    ;



    always @(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            cnt0 <= 0;
        end
        else if(add_cnt0)begin
            if(end_cnt0)
                cnt0 <= 0;
            else
                cnt0 <= cnt0 + 1;
        end
    end

    assign add_cnt0 = flag_add;
    assign end_cnt0 = add_cnt0 && cnt0== 100-1;

    always @(posedge clk or negedge rst_n)begin 
        if(!rst_n)begin
            cnt1 <= 0;
        end
        else if(add_cnt1)begin
            if(end_cnt1)
                cnt1 <= 0;
            else
                cnt1 <= cnt1 + 1;
        end
    end

    assign add_cnt1 = end_cnt0;
    assign end_cnt1 = add_cnt1 && cnt1== 8-1;



    
    always  @(posedge clk or negedge rst_n)begin
        if(rst_n==1'b0)begin
            flag_add <= 0;
        end
        else if(en)begin
            flag_add <= 1;
        end
        else if(end_cnt1)begin
            flag_add <= 0;
        end
    end


    always  @(posedge clk or negedge rst_n)begin
        if(rst_n==1'b0)begin
            sck <= 0;
        end
        else if(add_cnt0 && cnt0== 1-1)begin
            sck <= 1;
        end
        else if(add_cnt0 && cnt0== 100/2-1)begin
            sck <= 0;
        end
    end





    always  @(posedge clk or negedge rst_n)begin
        if(rst_n==1'b0)begin
            mosi <= 0;
        end
        else if(add_cnt0 && cnt0== 1-1)begin
            mosi <= data[7-cnt1];
        end
    end

assign data = 8'h37;





endmodule

仿真波形:

 很明显地看出来,MOSI的输出是00110111,就是16进制的37,其他信号都是按照要求设计的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

炎龙铠甲会合体

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值