spi verilog

发布于:2025-05-25 ⋅ 阅读:(30) ⋅ 点赞:(0)

master

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2025/05/24 14:34:15
// Design Name: 
// Module Name: spi_master
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module spi_master
    (
    // clk and rst_n
        input   wire        sys_clk         ,
        input   wire        sys_rst_n       ,
    // in_data and send enable
        input   wire [7:0]  in_data         ,
        input   wire        enable_send     ,
    // SCLK
        output  wire        sclk            ,
    // SS
        output  wire        ss              ,
    // MOSI
        output  wire        mosi            ,
    // MISO
        input   wire        miso
    );
    
    localparam   IDLE        =   4'b0000 ;
    localparam   SEND        =   4'b0001 ;
    
    reg  [3:0]      current_state   ;
    reg  [3:0]      next_state      ;
    
    reg             end_send        ;
    
    reg         out_ss              ;
    reg         out_mosi            ;
    
    reg  [7:0]  cnt_bit             ;
    reg  [7:0]  cnt_send            ;
    assign  sclk    =   ( current_state == SEND && cnt_send >= 1 )?sys_clk:1'b0     ;
    assign  ss      =   out_ss      ;
    assign  mosi    =   ( current_state == SEND )?out_mosi:1'b1    ;
    
    //one
    always@( posedge sys_clk or negedge sys_rst_n )
    begin
        if( sys_rst_n == 1'b0 )
        begin
            current_state   <=  IDLE    ;
        end
        else
        begin
            current_state   <=  next_state  ;
        end
    end
    //two
    always@( * )
    begin
        case( current_state )
            IDLE    :
                begin
                    if( enable_send == 1'b1 )
                    begin
                        next_state  =   SEND    ;
                    end
                    else
                    begin
                        next_state  =   IDLE    ;
                    end
                end
            SEND    :
                begin
                    if( end_send == 1'b1 )
                    begin
                        next_state  =   IDLE    ;
                    end
                    else
                    begin
                        next_state  =   SEND    ;
                    end
                end
            default :
                begin
                    next_state  =   IDLE    ;
                end
        endcase
    end
    //three
    always@( posedge sys_clk or negedge sys_rst_n )
    begin
        if( sys_rst_n == 1'b0 )
        begin
            out_ss      <=  1'b0    ;
            out_mosi    <=  1'b1    ;
            cnt_bit     <=  8'd0    ; 
        end
        else
        begin
            case( current_state )
                IDLE    :
                    begin
                        out_ss      <=  1'b0    ;
                        out_mosi    <=  1'b1    ;  
                        cnt_bit     <=  8'd0    ; 
                        end_send    <=  1'b0    ; 
                        cnt_send    <=  8'd0    ;                   
                    end
                SEND    :
                    begin
                        out_ss      <=  1'b1        ;
                        cnt_send    <=  cnt_send + 1'b1 ;
                        
                        if( cnt_bit == 8'd0 )
                        begin
                            out_mosi    <=  in_data[0]  ;
                            cnt_bit     <=  cnt_bit + 1'b1  ;
                        end
                        else if( cnt_bit == 8'd1 )
                        begin
                            out_mosi    <=  in_data[1]  ;
                            cnt_bit     <=  cnt_bit + 1'b1  ;
                        end
                        else if( cnt_bit == 8'd2 )
                        begin
                            out_mosi    <=  in_data[2]  ;
                            cnt_bit     <=  cnt_bit + 1'b1  ;
                        end
                        else if( cnt_bit == 8'd3 )
                        begin
                            out_mosi    <=  in_data[3]  ;
                            cnt_bit     <=  cnt_bit + 1'b1  ;
                        end
                        else if( cnt_bit == 8'd4 )
                        begin
                            out_mosi    <=  in_data[4]  ;
                            cnt_bit     <=  cnt_bit + 1'b1  ;
                        end
                        else if( cnt_bit == 8'd5 )
                        begin
                            out_mosi    <=  in_data[5]  ;
                            cnt_bit     <=  cnt_bit + 1'b1  ;
                        end
                        else if( cnt_bit == 8'd6 )
                        begin
                            out_mosi    <=  in_data[6]  ;
                            cnt_bit     <=  cnt_bit + 1'b1  ;
                        end
                        else if( cnt_bit == 8'd7 )
                        begin
                            out_mosi    <=  in_data[7]  ;
                            cnt_bit     <=  cnt_bit + 1'b1  ;
                            end_send    <=  1'b1    ;
                        end
                    end
                default :
                    begin
                        out_ss      <=  1'b0    ;
                        out_mosi    <=  1'b1    ;  
                        cnt_bit     <=  8'd0    ; 
                        end_send    <=  1'b0    ; 
                    end
            endcase
        end
    end
    
endmodule

tb master code

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2025/05/24 15:14:56
// Design Name: 
// Module Name: tb_spi_master
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module tb_spi_master
    (

    );

    // clk and rst_n
        reg         sys_clk         ;
        reg         sys_rst_n       ;
    // in_data and send enable
        reg  [7:0]  in_data         ;
        reg         enable_send     ;
    // SCLK
        wire        sclk            ;
    // SS
        wire        ss              ;
    // MOSI
        wire        mosi            ;
    // MISO
        wire        miso            ;
    
    initial
    begin
        sys_clk     =   1'b0    ;
        sys_rst_n   =   1'b0    ;
        #50 ;
        in_data     =   8'b01100011 ;
        sys_rst_n   =   1'b1    ;
        enable_send =   1'b1    ;
        #10 ;
        enable_send =   1'b0    ;
        #80 ;
        $stop   ;
    end
    always #5
    begin
        sys_clk =   ~sys_clk    ;
    end
    spi_master      inst_spi_master
    (
        .sys_clk         (sys_clk),
        .sys_rst_n       (sys_rst_n),
        .in_data         (in_data),
        .enable_send     (enable_send),
        .sclk            (sclk),
        .ss              (ss),
        .mosi            (mosi),
        .miso            (miso)
    );
    
endmodule

tb master


网站公告

今日签到

点亮在社区的每一天
去签到