【FPGA笔记】

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

串转单字节输出,请添加图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值