SPI接口的verilog实现

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

SPI接口的verilog实现

项目中使用的许多器件需要SPI接口进行配置,比如PLL:ADF4350,AD:AD9627,VGA:AD8372等,根据SPI协议,站长编写了一个简单的SPI读写程序,可以进行32为数据的读写(读者可以修改程序中数字使其变成16位或8位读写,也可以将读写位数参数化),可以设置SPI SCLK相对于主时钟的分频比。

【SPI程序】

/* SPI interface module V1.0 一些语句做了简单的英文注释*/

module spi_master(addr, in_data, out_data, rd, wr, cs, clk, miso, mosi, sclk);

input wire [1:0] addr;

input wire [31:0] in_data;

output reg [31:0] out_data;

input wire rd;

input wire wr;

input wire cs;

input wire clk;

inout miso;

inout mosi;

inout sclk;

reg sclk_buffer = 0;

reg mosi_buffer = 0;

reg busy = 0;

reg [31:0] in_buffer = 0;

reg [31:0] out_buffer = 0;

reg [7:0] clkcount = 0;

reg [7:0] clkdiv = 0;

reg [6:0] count = 0;

always@(cs or rd or addr or out_buffer or busy or clkdiv)

begin

out_data = 32'bx;

if(cs && rd)//selected and read

begin

case(addr)

2'b00: begin out_data = out_buffer; end // read data received by SPI interface

2'b01: begin out_data = {31'b0, busy}; end // read 'busy' flag of SPI interface

2'b10: begin out_data = clkdiv; end // read 'clkdiv' number of SPI

endcase

end

end

always@(posedge clk)

begin

if(!busy) //SPI interface is not busy

begin

if(cs && wr) //selected and write

begin

case(addr)

2'b00: begin in_buffer = in_data; busy = 1'b1; end //write in_data to SPI Buffer and let 'busy' flag on 2'b10: begin clkdiv = in_data; end //write 'clkdiv' number to SPI

endcase

end

end

else

begin

clkcount = clkcount + 1;

if(clkcount >= clkdiv) //every clkdiv*period(clk) time send one bit by SPI

begin

clkcount = 0;

if((count % 2) == 0) // change data in negtive sclk

begin

mosi_buffer = in_buffer[31];

in_buffer = in_buffer << 1;

end

if(count > 0 && count < 65) //32 periods

begin

sclk_buffer = ~sclk_buffer;

end

count = count + 1;

if(count > 65)

begin

count = 0;

busy = 1'b0;

end

end

end

end

always@(posedge sclk_buffer)

begin

out_buffer = out_buffer << 1;

out_buffer[0] = miso; //read data from pin 'miso'

end

assign sclk = sclk_buffer;

assign mosi = mosi_buffer;

endmodule

【SPI程序testbench】

/*

SPI module testbench V1.0

Loujianquan

2009.7.20

*/`timescale 1ns/1ns

module spi_master_tb();

reg [1:0] addr;

reg [31:0] in_data;

wire [31:0] out_data;

reg rd;

reg wr;

reg cs;

reg clk;

tri1 miso;

wire mosi;

wire sclk;

spi_master uut(addr, in_data, out_data, rd, wr, cs, clk, miso, mosi, sclk); integer counter = 0;

initial

begin

// Init

addr = 0;

in_data = 0;

rd = 0;

wr = 0;

cs = 0;

clk = 0;

相关文档
最新文档