verilog 仿真时实现 spi slave

SPI的CPHA固定为0,CPOL可配置,仿真时可参考的spi_slave 模块代码如下:

    module spi_slave (
        input                           I_SPI_DI                                ,
        output  reg                     O_SPI_DO                                ,
        input                           I_SPI_ENB                               ,
        input                           I_SPI_CLK                    
    );

    parameter                           p_SCLK_CNT_WIDTH            =  5        ;
    parameter                           p_OP_ADDR                   =  13       ;
    parameter                           p_SPI_CPHA                  =  0        ;
    
    localparam                          p_SPI_CPOL                  =  0        ;

    reg   [p_SCLK_CNT_WIDTH -1 :0]      r_SCLK_CNT      ;
    reg                                 r_WR_FLAG       ;
    reg   [p_OP_ADDR -1 :0]             r_OP_ADDR       ;
    reg   [ 7:0]                        r_WR_DATA       ;

generate
if(p_SPI_CPHA == 0) begin

    always @(posedge I_SPI_CLK or posedge I_SPI_ENB)
    begin
        if(I_SPI_ENB)
            r_SCLK_CNT <= 'b0;
        else
            r_SCLK_CNT <= r_SCLK_CNT + 'b1;
    end
 
    always @(posedge I_SPI_CLK or posedge I_SPI_ENB)
    begin
        if(I_SPI_ENB) begin
            r_WR_FLAG <= 'b1;
        end else begin
            if(r_SCLK_CNT == 'b0)
                r_WR_FLAG <= I_SPI_DI;
            else
                r_WR_FLAG <= r_WR_FLAG;
        end
    end
   
    always @(posedge I_SPI_CLK)
    begin
        if(I_SPI_ENB) begin
            r_OP_ADDR <= 'b1;
        end else begin
            if((r_SCLK_CNT >= 'b1) && (r_SCLK_CNT <= 'd15) )
                r_OP_ADDR <= {r_OP_ADDR,I_SPI_DI};
            else
                r_OP_ADDR <= r_OP_ADDR;
        end
    end
    
    always @(posedge I_SPI_CLK)
    begin
        if((r_SCLK_CNT >= 'd16) && (r_WR_FLAG == 'b1))
            r_WR_DATA <= {r_WR_DATA,I_SPI_DI};
        else
            r_WR_DATA <= r_WR_DATA;
    end
    
    always @(negedge I_SPI_CLK or posedge I_SPI_ENB)
    begin
        if(I_SPI_ENB) begin
            O_SPI_DO <= 'b1;
        end else begin
            if(r_WR_FLAG == 'b0)
                O_SPI_DO <= r_WR_DATA[23-r_SCLK_CNT];
            else
                O_SPI_DO <= O_SPI_DO;
        end
    end

end else begin

    always @(negedge I_SPI_CLK or posedge I_SPI_ENB)
    begin
        if(I_SPI_ENB)
            r_SCLK_CNT <= 'b0;
        else
            r_SCLK_CNT <= r_SCLK_CNT + 'b1;
    end
 
    always @(negedge I_SPI_CLK or posedge I_SPI_ENB)
    begin
        if(I_SPI_ENB) begin
            r_WR_FLAG <= 'b1;
        end else begin
            if(r_SCLK_CNT == 'b0)
                r_WR_FLAG <= I_SPI_DI;
            else
                r_WR_FLAG <= r_WR_FLAG;
        end
    end
   
    always @(negedge I_SPI_CLK)
    begin
        if(I_SPI_ENB) begin
            r_OP_ADDR <= 'b1;
        end else begin
            if((r_SCLK_CNT >= 'b1) && (r_SCLK_CNT <= 'd15) )
                r_OP_ADDR <= {r_OP_ADDR,I_SPI_DI};
            else
                r_OP_ADDR <= r_OP_ADDR;
        end
    end
    
    always @(negedge I_SPI_CLK)
    begin
        if((r_SCLK_CNT >= 'd16) && (r_WR_FLAG == 'b1))
            r_WR_DATA <= {r_WR_DATA,I_SPI_DI};
        else
            r_WR_DATA <= r_WR_DATA;
    end
    
    always @(posedge I_SPI_CLK or posedge I_SPI_ENB)
    begin
        if(I_SPI_ENB) begin
            O_SPI_DO <= 'b1;
        end else begin
            if(r_WR_FLAG == 'b0)
                O_SPI_DO <= r_WR_DATA[23-r_SCLK_CNT];
            else
                O_SPI_DO <= O_SPI_DO;
        end
    end
end

endgenerate

endmodule

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值