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