|
![](static/image/common/ico_lz.png)
楼主 |
发表于 2013-1-16 11:27:21
|
显示全部楼层
本帖最后由 modelsim 于 2013-1-16 11:30 编辑
一个比较简单的verilog写SPI设备程序
module write_93lc46b(
clk,
rst_n,
spi_out
);
input clk;
input rst_n;
output[2:0] spi_out;
parameter T2US = 23'd99; //500kHz
reg[6:0] cnt;
always@(posedge clk or negedge rst_n)
if(!rst_n)
cnt <= 7'd0;
else if(cnt == T2US)
cnt <= 7'd0;
else
cnt <= cnt + 1'b1;
reg[8:0] addr;
reg[15:0] data;
reg[5:0] i;
reg rCS;
reg rCLK;
reg rDO;
reg[24:0] spidata;
//下面的写法 SPI的时钟就会变成250kHz
always@(posedge clk or negedge rst_n)
if(!rst_n)
begin
i <= 6'd0;
rCS <= 1'b0;
rCLK <= 1'b1;
rDO <= 1'b0;
addr <= 9'b101_00000;
data <= 16'b0000_0000_0000_0000;
spidata <= {addr,data};
end
else
case(i)
6'd0,6'd2,6'd4,6'd6,6'd8,6'd10,6'd12,6'd14,6'd16,6'd18,6'd20,6'd22,6'd24,6'd26,6'd28,6'd30,6'd32,6'd34,6'd36,6'd38,6'd40,6'd42,6'd44,6'd46,6'd48:
if(cnt == T2US)
begin
rCLK <= 1'b0;
rDO <= spidata[24-(i>>1)];
i <= i+1'b1;
end
6'd1,6'd3,6'd5,6'd7,6'd9,6'd11,6'd13,6'd15,6'd17,6'd19,6'd21,6'd23,6'd25,6'd27,6'd29,6'd31,6'd33,6'd35,6'd37,6'd39,6'd41,6'd43,6'd45,6'd47,6'd49:
if(cnt == T2US)
begin
rCLK <= 1'b1;
i <= i+1'b1;
end
6'd50:
if(cnt == T2US)
i <= i+1'b1;
6'd60:
if(cnt == T2US)
begin
i <= 6'd0;
addr <= addr + 1'b1;
data <= data + 16'b0001_0001_0001_0001;
if(addr > 9'b101_11111)
begin
addr <= 9'b101_00000;
data <= 16'b0000_0000_0000_0000;
end
spidata <= {addr,data};
end
default:
if(cnt == T2US)
i <= i+1'b1;
endcase
assign spi_out = {rCS,rCLK,rDO};
endmodule
以下是testbech
`timescale 1 ns/ 1 ns
module m93lc46b_top_vlg_tst();
reg clk;
reg rst_n;
wire [2:0] spi_out;
m93lc46b_top i1 (
.clk(clk),
.rst_n(rst_n),
.spi_out(spi_out)
);
initial
begin
clk = 0;
forever
#10 clk = ~clk;
end
initial
begin
rst_n = 0;
#1000;
rst_n = 1;
#5000000;
$stop;
end
endmodule
|
|