spi 发送与接收 移位写法

spi _tx 发送模块 片选信号cs可以在top顶层控制模块产生

verilog 复制代码
`timescale 1ns / 1ps


module spi_rom#(
    parameter SIZE =  8     
)(
    input      wire                  clk  ,
    input      wire                  rst_n,
    input      wire      [SIZE-1:0]  data ,
    input      wire                  valid,
    output     reg                   sck  ,
    output     wire                  busy ,
    output     reg                   mosi 
    );
parameter CUNT_MAX = 100   ;
parameter BUSY     = 2'b10 ;
parameter IDEL     = 2'b01 ;



reg             fin      ;
reg  [1:0]      state    ;
reg  [10:0]     cunt     ;
reg  [10:0]     cunt_b   ;
reg  [SIZE-1:0] data_r   ; 
assign busy=(state==BUSY)?1'b1:1'b0;
//状态
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
    state<=IDEL;
    else case (state)
        IDEL:begin
            if(valid==1)
            state<=BUSY;
            else
            state<=state;
            end
        BUSY:begin
            if(fin==1)
            state<=IDEL;
            else
            state<=state;
        end
        default: ;
    endcase
end
//计数器
always @(posedge clk) begin
    if(state==IDEL)
    cunt<=11'd0;
    else begin
        if(cunt==CUNT_MAX-1)
        cunt<=11'd0;
        else
        cunt<=cunt+1'b1;
    end
end
//cunt_b
always @(posedge clk ) begin
    if(state==IDEL)
    cunt_b<=11'd0;
    else begin
        if(cunt==CUNT_MAX-1)
        cunt_b<=cunt_b+1;
        else
        cunt_b<=cunt_b;
    end    
end
//fin结束信号
always @(posedge clk ) begin
    if((cunt_b==SIZE-1)&&(cunt==CUNT_MAX-1))
    fin<=1'b1;
    else
    fin<=1'b0;
end
//数据的缓存
always @(posedge clk ) begin
    if(state==IDEL&&valid==1)
    data_r<=data;
    else if(state==BUSY&&cunt==CUNT_MAX-2)
    data_r<=(data_r<<1);
    else
    data_r<=data_r;
end
//sck的产生
always @(posedge clk ) begin
    if(state==IDEL)
    sck<=1'b0;
    else begin
        if(cunt_b==SIZE)  //防止sck出现末尾的毛刺
        sck<=1'b0;
        else if(cunt<50)
        sck<=1'b1;
        else
        sck<=1'b0;
    end
end
//tx的输出
always @(posedge clk ) begin
    if(state==IDEL)
    mosi<=1'b0;
    else begin
        if(cunt==0)
        mosi<=data_r[SIZE-1];
        else
        mosi<=mosi;
    end
end
endmodule

spi_rx

verilog 复制代码
`timescale 1ns / 1ps

module spi_rx#(
    parameter SIZE  =  8 
)(
    input                         clk   ,
    input                         rst_n ,
    input                         miso  ,
    input                         sck   ,
    input                         cs    ,
    output     reg    [SIZE-1:0]  data  ,
    output                        vlid  
    );
reg  [8:0]   cunt_b;
reg  [1:0]   rx_t  ;

assign vlid=(cunt_b==SIZE)?1'b1:1'b0;

always @(posedge clk ) begin
    if(!rst_n)
    rx_t<=2'b00;
    else 
    rx_t<={rx_t[0],sck};
end
//对下降沿计数
always @(posedge clk ) begin
    if(!rst_n)
    cunt_b<=0;
    else if(cs==0)begin 
    if(vlid==1)
    cunt_b<=0;
    else if(rx_t==2'b10)
    cunt_b<=cunt_b+1'b1;
    else
    cunt_b<=cunt_b;
    end
    else
    cunt_b<=0;
end
//data
always @(posedge clk ) begin
    if(cs==0&&rx_t==2'b10)
    data[0]<=miso;
    else if(cs==0&&rx_t==2'b01) //先移位再赋值相当于是
    data<=(data<<1);
    else
    data<=data;
end


endmodule
相关推荐
梓仁沐白3 小时前
Verilog HDL 语言整理
fpga开发
FPGA_ADDA6 小时前
基于PXIE 总线架构的Kintex UltraScale 系列FPGA 高性能数据预处理板卡
fpga开发·pxie总线·ku060·ku115
搬砖的小码农_Sky15 小时前
FPGA:Lattice的FPGA产品线以及器件选型建议
嵌入式硬件·fpga开发·硬件架构·硬件工程
超能力MAX17 小时前
ZYNQ-AXI4 DDR读写测试
fpga开发
fpga小白历险记18 小时前
BUFDS_GTE2,IBUFDS,BUFG缓冲的区别
fpga开发
zly88653721 天前
MMIO机制详解
fpga开发
北京青翼科技1 天前
【PXIE301-211】基于PXIE总线的16路并行LVDS数据采集、1路光纤数据收发处理平台
图像处理·fpga开发·信号处理
霖001 天前
PCIe数据采集系统
数据结构·经验分享·单片机·嵌入式硬件·fpga开发·信号处理
FakeOccupational2 天前
fpga系列 HDL : Microchip FPGA开发软件 Libero Soc 安装 & license申请
fpga开发
千歌叹尽执夏2 天前
FPGA: UltraScale+ bitslip实现(ISERDESE3)
fpga开发·training·ultrascale+·bitslip