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
相关推荐
北京太速科技股份有限公司21 小时前
太速科技-FMC144 -八路 250MSPS 14bit AD FMC子卡
fpga开发
不可思议迷宫2 天前
Verilog编程实现一个分秒计数器
单片机·嵌入式硬件·fpga开发
Terasic友晶科技2 天前
第3篇:Linux程序访问控制FPGA端LEDR<一>
fpga开发·嵌入式系统·de1-soc开发板
双料毒狼_s2 天前
【FPGA】状态机思想回顾流水灯
fpga开发
双料毒狼_s2 天前
【FPGA实战】基于DE2-115实现数字秒表
fpga开发
Cynthia的梦2 天前
FPGA学习-基于 DE2-115 板的 Verilog 分秒计数器设计与按键功能实现
fpga开发
9527华安3 天前
Xilinx系列FPGA实现HDMI2.1视频收发,支持8K@60Hz分辨率,提供2套工程源码和技术支持
fpga开发·音视频·8k·hdmi2.1
大熊Superman3 天前
FPGA实现LED流水灯
fpga开发
泪水打湿三角裤3 天前
fpga:分秒计时器
fpga开发
奋斗的牛马3 天前
FPGA_AXI仿真回环(一)
fpga开发