module SpiDataShift #(
parameter DATA_WIDTH = 8 // 数据宽度,默认为 8 位
) (
input wire clk, // 输入时钟信号
input wire rst_n, // 复位信号,低电平有效
input wire [(DATA_WIDTH * 8) - 1:0] data_in, // 输入的数据,总位宽取决于数据宽度和输入数量
output reg [7:0] spi_data, // 输出 SPI 数据
output reg done // 数据传输完成标志
);
// 定义状态机状态
reg [3:0] byte_counter;
reg [(DATA_WIDTH * 8) - 1:0] data_buffer; // 数据缓冲区
reg [7:0] data_out; // 缓存当前传输的数据
always @(*) begin
if (byte_counter == 0 ) begin
// 提取第一个数据
data_buffer <= data_in;
done <= 0; // 进入数据传输状态时重置 done 信号
end
end
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
byte_counter <= 0;
data_out <= 0;
spi_data <= 0;
done <= 0; // 初始化为 0,表示数据传输未完成
end else begin
if (byte_counter < DATA_WIDTH) begin // 8 bits in a byte
// 数据传输状态
data_out <= data_buffer[(DATA_WIDTH - byte_counter - 1) * 8 +: 8];
byte_counter <= byte_counter + 1;
end else begin
if (byte_counter == DATA_WIDTH) begin
// 传输最后一个字节
data_out <= data_buffer[7:0];
done <= 1; // 数据传输完成
end
end
end
end
// 输出传输的数据和传输完成标志
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
spi_data <= 0;
done <= 0;
end else begin
if (byte_counter <= DATA_WIDTH) begin
spi_data <= data_out;
end
end
end
endmodule
`include “SpiDataShift.v”
module SpiDataShift_tb;
// Parameters
parameter DATA_WIDTH = 10;
parameter CLK_PERIOD = 10; // Clock period set to 10 time units
// Inputs
reg clk = 0;
reg rst_n = 1;
reg [79:0] data_in; // Input data
// Outputs
wire [7:0] spi_data;
wire done;
// Instantiate the SpiDataShift module
SpiDataShift #(
.DATA_WIDTH(DATA_WIDTH)
) dut (
.clk(clk),
.rst_n(rst_n),
.data_in(data_in),
.spi_data(spi_data),
.done(done)
);
// Clock generation
always #((CLK_PERIOD/2)) clk <= ~clk;
// Initial stimulus
initial begin
// Reset
rst_n = 0;
#20;
rst_n = 1;
// Input data initialization
data_in = 80'h01_02_03_04_05_06_07_08_09_0a; // Convert string to ASCII values
// Dump waveform to a VCD file
$dumpfile("waveform.vcd");
$dumpvars(0, SpiDataShift_tb);
// Wait for simulation to finish
#200;
$finish;
end
// Monitor
always @(posedge clk) begin
$display("spi_data = %c, done = %b", spi_data, done);
end
endmodule
串转单字节输出,