常用串行总线——SPI协议(下)

2. 从模块(spi_slave):
module spi_slave(
input rst_n,input cs_n,input sclk,input mosi,output miso,output [7:0] reg0_out,output [7:0] reg1_out,output [7:0] reg2_out,output [7:0] reg3_out);
reg miso_r;
reg [7:0] reg1_out_r;
reg [7:0] reg2_out_r;
reg [7:0] reg3_out_r;
reg [7:0] reg0_out_r;
reg start;
reg wr_rd;
reg [3:0] bit_cnt;
reg [6:0] reg_addr;
reg [7:0] reg_data;
parameter reg0_address = 7'b0000000; //address of reg0
parameter reg1_address = 7'b0000001; //address of reg1
parameter reg2_address = 7'b0000010; //address of reg2
parameter reg3_address = 7'b0000011; //address of reg3
//start
always @ (posedge sclk or negedge rst_n)
begin
if(~rst_n)
start <= 1'b0;else
start <= 1'b1;end
//bit_cnt
always @ (posedge sclk or negedge rst_n)
begin
if(~rst_n)
bit_cnt <= 4'b0;else if(start)
bit_cnt <= bit_cnt + 1'b1;end
//wr_rd
always @ (posedge sclk or negedge rst_n)
begin
if(~rst_n)
wr_rd <= 1'b0;else if(bit_cnt == 4'b0 && mosi == 1'b0)
wr_rd <= 1'b0;else if(bit_cnt == 4'b0 && mosi == 1'b1)
wr_rd <= 1'b1;end
//reg_addr
always @ (negedge sclk or negedge rst_n)
begin
if(~rst_n)
reg_addr = 4'd1 && bit_cnt <= 4'd7)
reg_addr <= {reg_addr[5:0],mosi};end
//reg_data
always @ (posedge sclk or negedge rst_n)
begin
if(~rst_n)
reg_data = 4'd7)
reg_data <= {reg_data[6:0],mosi};else if(wr_rd && bit_cnt == 4'd6)
reg_data = 4'd7)
reg_data <= {reg_data[6:0],reg_data[7]};end
//reg_out
assign reg0_out = reg0_out_r;
assign reg1_out = reg1_out_r;
assign reg2_out = reg2_out_r;
assign reg3_out = reg3_out_r;
always @ (negedge sclk or negedge rst_n)
begin
if(~rst_n)
begin
reg0_out_r <= 8'b0;reg1_out_r <= 8'b0;reg2_out_r <= 8'b0;reg3_out_r <= 8'b0;end
else if(!wr_rd && bit_cnt == 4'd0)
case(reg_addr)
reg0_address: reg0_out_r <= reg_data;reg1_address: reg1_out_r <= reg_data;reg2_address: reg2_out_r <= reg_data;reg3_address: reg3_out_r <= reg_data;endcase
end
//miso
assign miso = miso_r;
always @ (negedge sclk or posedge rst_n)
begin
if(~rst_n)
miso_r = 4'd7)
miso_r <= reg_data[7];end
endmodule
3. testbench(tb):
`timescale 1us/1us
module tb();
regclk_40k;
regrst_n;
reg [7:0] data_in;
regsend_start;
wiresclk;
wirecs_n;
wiremosi;
wiremiso;
wire [7:0] data_out;
wire data_out_vld;
wire [7:0] reg0_out;
wire [7:0] reg1_out;
wire [7:0] reg2_out;
wire [7:0] reg3_out;
spi_master i_spi_master(
.clk_40k (clk_40k), .rst_n (rst_n),.data_in (data_in),.send_start (send_start),.sclk (sclk),.cs_n (cs_n),.mosi (mosi),.miso (miso),.data_out (data_out), .data_out_vld (data_out_vld));
spi_slave i_spi_slave(
.rst_n (rst_n), .cs_n (cs_n),.sclk (sclk), .mosi (mosi), .miso (miso), .reg0_out (reg0_out), .reg1_out (reg1_out), .reg2_out (reg2_out), .reg3_out (reg3_out));
initial
begin
rst_n = 1'b0;#10rst_n = 1'b1;end
initial
begin
clk_40k = 1'b0;forever#1clk_40k = ~clk_40k;end
initial
begin
send_start = 1'b0;data_in = 8'd0;foreverbegin #200; data_in = $random()%256; send_start = 1'b1; #2 send_start = 1'b0; #8000;endend
endmodule
4. 仿真结果:
按照testbench对spi主从设备进行仿真,仿真结果如图:
系统时钟和spi时钟不一致,clk_40k为高频系统时钟,利用计数器分频实现1k波特率spi时钟;复位信号rst_n低电平有效,正常传输时始终处于高电平;开始传输时send_start信号拉高,传输结束时data_out_vld信号拉高;spi主设备将输入数据data_in并行转mosi串行输出,spi从设备将接收到的串行存入数据,将移位后的数据data_out并行转miso串行输出。05
spi的优缺点
5.1 spi协议优点
全双工同步串行通信;允许数据逐位传递;允许数据传输暂停;硬件结构简单,不需要精密时钟;从机不需要唯一地址,也不需要收发器。5.1 spi协议缺点
需要4个引脚接口;支持传输距离较短;硬件层面没有定义校错协议和从机应答信号。

AMD2800X被曝将是10核20线程 跑分堪比英特尔i9
高频变压器的线圈匝数和线径计算步骤介绍
光纤传感器-罐头盖计数应用案例-阿童木光纤传感器
Imagination推出基于硬件又高度灵活的异构计算产品组合
诺基亚CFO:只要能盈利就继续生产Symbian手机
常用串行总线——SPI协议(下)
如何让PCB设计更加精简?
山灵M5s试听:以旗舰之名回应催更的热情
空气开关的结构
软银发布新款扫地机器人Whiz
Maxim全新2款LED驱动器 为汽车照明提供更高亮度LED驱动方案
单片微波集成电路同相正交混频器——HMC520A
带霍尔传感器的三相无刷直流电机控制
骁龙670加码vivo X23,发现更多美
科技元素大融合 汽车驾驶更智能
Imagination在OnCloud平台上使用AI驱动的Cadence Cerebrus优化PPA结果,加快低功耗GPU的交付
华为云耀云服务器 L 实例的多元应用场景,助力企业高效运营
浅析电磁接触器的组成及原理
什么是通感算一体化?通感算一体化的应用场景
康佳冰箱匠心设计引领行业风潮 获线上消费者追捧