欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

如何让FPGA中的SPI与其他模块互动起来

发布时间:2025/3/14 53 豆豆
生活随笔 收集整理的这篇文章主要介绍了 如何让FPGA中的SPI与其他模块互动起来 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

 

在上一篇文章《FPGA的SPI从机模块实现》中,已经实现了SPI的从机模块,如何通过SPI总线与FPGA内部其他模块进行通信,是本文的主要讨论内容。

 

一. 新建FPGA内部DAC控制模块

这里由于手上项目需求,有两块单独DAC902核心板,其中一片DAC902的输出作为另一片DAC902的基准源输入,我们分别称它们为DACref和DACsin,顾名思义一片提供基准源电压,一片输出正弦信号或者扩展成DDS信号输出。 因此,此模块的RTL模型必须有与SPI模块通信端和外部控制DAC902的信号管脚。所以预设计这个模块为: module dac_reg_rw_spi(clk, nrst, rec_flag, rec_data, send_flag, sending_flag, send_data, dac_clk, dacref_clk, dacref_fudu, dacsin_output); input clk, nrst; //模块系统时钟、复位 //与spi模块交互引脚input rec_flag; //spi字节接收标志input[7:0] rec_data; //spi接收数据缓存寄存器input sending_flag; //spi模块正在发送数据标志位 //与spi模块交互引脚output send_flag; //dac控制模块存在需要发送数据标志位,主要负责触发spi发送output[7:0] send_data; //spi需要发送的数据 //与外部dac通信引脚output[11:0] dacref_fudu; //直接输出到dacref中output[11:0] dacsin_output;output dac_clk;output dacref_clk;

这里假定先发送一个字节的命令,紧接着通过spi发送、接收dac控制模块所需的数据。所以定义命令字如下:

 

//指令代号parameter read_dacref_fudukongzhizi=8'b00000001; //读取dacref的幅度控制字parameter read_dacsin_xiangweikongzhizi=8'b00000010; //读取dacsin的相位控制字parameter read_dacsin_pinlvkongzhizi=8'b00000011; //读取dacsin的频率控制字parameter set_dacsin_pinlvkongzhizi=8'b00100001; //写入dacsin的频率控制字parameter set_dacsin_xiangweikongzhizi=8'b00100010; //写入dacsin的相位控制字parameter set_dacref_fudukongzhizi=8'b00100011; //写入dacref的幅度控制字parameter set_dac_clk_pdf=8'b00100100; //设置dac时钟预分频parameter reset_to_default=8'b11100000; //复位dac控制模块parameter start_dac=8'b11100001; //开启dac模块parameter stop_dac=8'b11100010; //停止dac模块
由于spi属于串行接收,一次以8位传输格式,而我们的DDS模块需要32位的频率控制字、10位的相位控制字、12位的基准源幅度控制字(具体DDS原理,由于篇幅有限,这里就不再详细介绍了),因此我们需要读取这几个寄存器或者写入这几个寄存器,需要输出、接收不等的字节长度,而dds模块处于实时运行中,所以这里需要影子寄存器的介入。

 

 

//dac配置的影子寄存器(dac运作依据的值)reg[11:0] dacref_fudukongzhizi_shadow;reg[31:0] dacsin_pinlvkongzhizi_shadow;reg[9:0] dacsin_xiangweikongzhizi_shadow;reg[3:0] dac_clk_pdf_shadow;
开始设计dac的模块吧:

 

 

reg[3:0] rw_reg_status; //处理spi接收发送数据状态机reg[3:0] rw_reg_status_temp; 处理spi接收发送数据状态机(影子寄存器)reg[7:0] rec_data_temp; //8位spi数据接收缓存reg[3:0] delay_cnt; //发送数据延时计数器//dac配置寄存器临时值reg[31:0] dacsin_pinlvkongzhizi; reg[11:0] dacref_fudukongzhizi;reg[9:0] dacsin_xiangweikongzhizi;reg[7:0] send_data; //与myspi模块通信脚reg send_flag; //与myspi模块通信脚reg[2:0] byte_sended_cnt; //发送数据字节数计数器reg[2:0] byte_received_cnt; //接收数据字节数计数器reg dac_start_flag; //dac使能脚reg dacref_clk;//spi通信处理状态机,需要注意的是,clk时钟频率必须为sck时钟频率约10倍以上,保证正确操作。always @ (posedge clk or negedge nrst)beginif(~nrst)begin //初始化上述寄存器rw_reg_status <= 4'h0;rw_reg_status_temp <= 4'h0; //处理spi接收发送数据状态机(影子寄存器)rec_data_temp <= 8'h00;dacsin_pinlvkongzhizi <= 32'h00412345;dacsin_xiangweikongzhizi <= 10'h123;dacref_fudukongzhizi <= 12'h800;delay_cnt <= 4'b0000;byte_sended_cnt <= 3'b000;send_flag <= 1'b0;byte_received_cnt <= 3'b000;dac_start_flag <= 1'b0;dacref_clk <= 1'b0;dacref_fudukongzhizi_shadow <= 12'h800;dacsin_pinlvkongzhizi_shadow <= 32'h00423456;dacsin_xiangweikongzhizi_shadow <= 10'h200;dac_clk_pdf_shadow <= 4'h1;endelsebegin case (rw_reg_status)4'b0000: begin //从机接收指令if(rec_flag)beginrec_data_temp <= rec_data;rw_reg_status <= 4'b0001; //进入命令解析endend4'b0001: begin //指令解析,跳转相应状态case (rec_data_temp)reset_to_default: beginrw_reg_status <= 4'b1110;endread_dacref_fudukongzhizi: beginrw_reg_status <= 4'b0011; //读dacref的幅度控制字endread_dacsin_xiangweikongzhizi: beginrw_reg_status <= 4'b0010; //读dacsin的相位控制字endread_dacsin_pinlvkongzhizi: beginrw_reg_status <= 4'b0110; //读dacsin的频率控制字endset_dacsin_pinlvkongzhizi: beginrw_reg_status <= 4'b1101; //设置dacsin的频率控制字rw_reg_status_temp <= 4'b0101;endset_dacsin_xiangweikongzhizi: begin //设置dacsin的相位控制字rw_reg_status <= 4'b1101;rw_reg_status_temp <= 4'b0100;endset_dacref_fudukongzhizi: begin //设置dacref的幅度控制字rw_reg_status <= 4'b1101;rw_reg_status_temp <= 4'b1100;endset_dac_clk_pdf: begin //设置dac时钟预分频值rw_reg_status <= 4'b1101;rw_reg_status_temp <= 4'b1001;endstart_dac: beginrw_reg_status <= 4'b1010;//rw_reg_status_temp <= 4'b0000;endstop_dac: beginrw_reg_status <= 4'b1011;//rw_reg_status_temp <= 4'b0000;enddefault: beginrw_reg_status <= 4'b1101;rw_reg_status_temp <= 4'b0000;endendcaseend//----------------------------------------------------4'b0011: begin //先发送幅度控制字高八位字节然后发送低八位字节if(~sending_flag) begin //判断spi是否处于发送状态case (byte_sended_cnt)3'b000: beginsend_data <= {4'b0000, dacref_fudukongzhizi_shadow[11:8]};rw_reg_status_temp <= 4'b0011;rw_reg_status <= 4'b0111;end3'b001: beginsend_data <= dacref_fudukongzhizi_shadow[7:0];rw_reg_status_temp <= 4'b0011;rw_reg_status <= 4'b0111;enddefault: beginbyte_sended_cnt <= 3'b000;rw_reg_status_temp <= 4'b0000;rw_reg_status <= 4'b0000; //发送完成endendcaseendelse beginsend_flag <= 1'b0;endend//----------------------------------------------------4'b0010: beginif(~sending_flag) begin //判断spi是否处于发送状态case (byte_sended_cnt)3'b000: beginsend_data <= {6'b000000, dacsin_xiangweikongzhizi_shadow[9:8]};rw_reg_status_temp <= 4'b0010; //4'b0110;rw_reg_status <= 4'b0111;end3'b001: beginsend_data <= dacsin_xiangweikongzhizi_shadow[7:0];rw_reg_status_temp <= 4'b0010; //4'b0110;rw_reg_status <= 4'b0111;enddefault: beginrw_reg_status <= 4'b0000; //发送完成rw_reg_status_temp <= 4'b0000;byte_sended_cnt <= 3'b000;endendcaseendelse beginsend_flag <= 1'b0;endend//----------------------------------------------------4'b0110: beginif(~sending_flag) begin //判断spi模块是否处于发送状态case (byte_sended_cnt)3'b000: beginsend_data <= dacsin_pinlvkongzhizi_shadow[31:24];rw_reg_status_temp <= 4'b0110;rw_reg_status <= 4'b0111; //4'b0100;end3'b001: beginsend_data <= dacsin_pinlvkongzhizi_shadow[23:16];rw_reg_status_temp <= 4'b0110;rw_reg_status <= 4'b0111; //4'b0100;end3'b010: begin send_data <= dacsin_pinlvkongzhizi_shadow[15:8];rw_reg_status_temp <= 4'b0110;rw_reg_status <= 4'b0111;end3'b011: beginsend_data <= dacsin_pinlvkongzhizi_shadow[7:0];rw_reg_status_temp <= 4'b0110;rw_reg_status <= 4'b0111;enddefault: beginrw_reg_status <= 4'b0000; //发送完成rw_reg_status_temp <= 4'b0000;byte_sended_cnt <= 3'b000;endendcaseendelse beginsend_flag <= 1'b0;endend //通用状态 4'b0111: begin //dac控制模块向spi模块提出发送请求,即生成send_flag脉冲send_flag <= 1'b1;if(delay_cnt == 4'b0011)begindelay_cnt <= 4'b0000;rw_reg_status <= rw_reg_status_temp;byte_sended_cnt <= byte_sended_cnt+1;endelsebegindelay_cnt <= delay_cnt+1;endend//----------------------------------------------------4'b0101: begin//if(rec_flag) begin case (byte_received_cnt)3'b000: beginif(rec_flag) begin //spi字节接收完成标志位dacsin_pinlvkongzhizi[31:24] <= rec_data;rw_reg_status <= 4'b1101;byte_received_cnt <= 3'b001;endend3'b001: beginif(rec_flag) begindacsin_pinlvkongzhizi[23:16] <= rec_data;rw_reg_status <= 4'b1101;byte_received_cnt <= 3'b010;endend3'b010: beginif(rec_flag) begindacsin_pinlvkongzhizi[15:8] <= rec_data;rw_reg_status <= 4'b1101;byte_received_cnt <= 3'b011;endend3'b011: beginif(rec_flag) begindacsin_pinlvkongzhizi[7:0] <= rec_data;rw_reg_status <= 4'b1101;byte_received_cnt <= 3'b100;endend3'b100: begindacsin_pinlvkongzhizi_shadow <= dacsin_pinlvkongzhizi;byte_received_cnt <= 3'b101;end3'b101: beginrw_reg_status <= 4'b1101;rw_reg_status_temp <= 4'b0000;byte_received_cnt <= 3'b000;endendcase//endend//---------------------------------------------------- 在spi接收到命令字时,下一个系统时钟clk上跳沿则进入此状态,此时rec_flag可能仍然是有效,所以会先进入4'b1101模块等待rec_flag标志位复位后再接收数据,其他状态其实大同小异,这里不一一描述。4'b0100: begin//if(rec_flag) begincase (byte_received_cnt)3'b000: beginif(rec_flag) begindacsin_xiangweikongzhizi[9:8] <= rec_data[1:0];rw_reg_status <= 4'b1101;byte_received_cnt <= 3'b001;endend3'b001: beginif(rec_flag) begindacsin_xiangweikongzhizi[7:0] <= rec_data;rw_reg_status <= 4'b1101;byte_received_cnt <= 3'b010;endend3'b010: begindacsin_xiangweikongzhizi_shadow <= dacsin_xiangweikongzhizi;byte_received_cnt <= 3'b011;end3'b011: beginrw_reg_status <= 4'b1101; //4'b0000;rw_reg_status_temp <= 4'b0000;byte_received_cnt <= 3'b000;endendcase//endend//----------------------------------------------------4'b1100: begin//if(rec_flag) begincase (byte_received_cnt)3'b000: beginif(rec_flag) begindacref_fudukongzhizi[11:8] <= rec_data[3:0];rw_reg_status <= 4'b1101;byte_received_cnt <= 3'b001;endend3'b001: beginif(rec_flag) begindacref_fudukongzhizi[7:0] <= rec_data;rw_reg_status <= 4'b1101;byte_received_cnt <= 3'b010;endend3'b010: begindacref_fudukongzhizi_shadow <= dacref_fudukongzhizi;byte_received_cnt <= 3'b011;end3'b011: begindacref_clk <= 1'b1;if(delay_cnt == 4'b0011)begindelay_cnt <= 4'b0000;byte_received_cnt <= 3'b111;endelsebegindelay_cnt <= delay_cnt+1;endend3'b111: begindacref_clk <= 1'b0;rw_reg_status <= 4'b1101;rw_reg_status_temp <= 4'b0000;byte_received_cnt <= 3'b000;endendcase//endend4'b1101: beginif(~rec_flag) begin //字节接收完成标志位复位等待rw_reg_status <= rw_reg_status_temp;endend//----------------------------------------------------4'b1110: begindacsin_pinlvkongzhizi <= 32'h00454321;dacsin_xiangweikongzhizi <= 10'h234;dacref_fudukongzhizi <= 12'h321;rw_reg_status_temp <= 4'b0000;rw_reg_status <= 4'b1101;end4'b1111: beginif(delay_cnt == 4'b0011)begindelay_cnt <= 4'b0000;rw_reg_status <= 4'b0000;endelsebegindelay_cnt <= delay_cnt+1;endend//----------------------------------------------------4'b1010: begindac_start_flag <= 1'b1;rw_reg_status <= 4'b1101;rw_reg_status_temp <= 4'b0000;end//----------------------------------------------------4'b1011: begindac_start_flag <= 1'b0;rw_reg_status <= 4'b1101;rw_reg_status_temp <= 4'b0000;end//----------------------------------------------------4'b1001: beginif(rec_flag) begindac_clk_pdf_shadow <= rec_data[3:0];rw_reg_status <= 4'b1101;rw_reg_status_temp <= 4'b0000;endendendcaseendend
既然dac控制模块的spi接收和发送设计好了,dds模块当然不能少,这部分就相对简单些。

 

//dac时钟分频模块reg dac_clk;reg[3:0] dac_clk_cnt; //分频,后面可以对dac_clk_cnt进行预分频处理reg[3:0] dac_clk_pdf; //预分频always @ (posedge clk or negedge nrst)beginif(~nrst)begindac_clk <= 1'b0;dac_clk_cnt <= 4'b0;dac_clk_pdf <= 4'h1;endelse beginif(dac_start_flag) beginif(dac_clk_cnt == dac_clk_pdf) begindac_clk_cnt <= 4'b0;dac_clk <= ~dac_clk;dac_clk_pdf <= dac_clk_pdf_shadow;endelse begindac_clk_cnt <= dac_clk_cnt+1;endendendend//dac输出模块assign dacref_fudu = dacref_fudukongzhizi_shadow; //直接输出到dacref中//reg[11:0] dacsin_output;reg[31:0] leijiazi;reg[9:0] dac_rom_addr;//assign dacsin_enable = nrst&dac_start_flag;always @ (posedge clk or negedge nrst)beginif(~nrst) //dacsin失能beginleijiazi <= {dacsin_xiangweikongzhizi_shadow, 22'h000000}; //累加字存储器dac_rom_addr <= 10'h000;endelse //dacsin使能beginif(dac_start_flag) beginleijiazi <= leijiazi+dacsin_pinlvkongzhizi_shadow;dac_rom_addr <= leijiazi[31:22];endelse begindac_rom_addr <= 10'h000;endendendsin_table U3(.clka(clk),.addra(dac_rom_addr),.douta(dacsin_output)); 这里用到了名为sin_table的ROM软核,使用Block RAM组合成12位数据输出,10位数据深度(即1024个存储空间)的ROM,空间为12bits*1024。

 

题外话:既然提到了核,那么想当然联想到他们的分类:软核、固核和硬核三种。

软核:属于综合之前的RTL模型,只经过功能仿真,最后需要进行综合及布线后才能使用。但是不同的布线环境对其效果是不一样的,存在发送错误的可能性。

固核:带有局部规划信息的网表,对时序有一定约束后的产物,只需要通过布线工具就可以使用。

硬核:就是经过验证的设计版图,其物理版图不允许再进行修改,模块时序要求非常严格,可靠性相当高。

二. 修改spi从机模块

根据上面的dac控制模块,我们需要对先前的spi从机模块进行适当修改。 module myspi(nrst, clk, ncs, mosi, miso, sck, rec_flag, rec_data, send_flag, sending_flag, send_data); //miso主入从出,mosi主出从入input clk, nrst;input ncs, mosi, sck;input send_flag;input[7:0] send_data;output[7:0] rec_data;output miso;output sending_flag;output rec_flag; 这样,spi模块就加入与dac控制模块的通信线路了,是不是很方便。

三. 生成顶层模块

这个主要是考虑fpga最终IO口输出情况,有点像将模块打包成一个模块,在外看FPGA内部模块相当于一个黑匣子,我们操作的时候则只关心FPGA留给我们的通信管脚就可以了。 module dac_top(clk, nrst, ncs, mosi, miso, sck, dac_clk, dacref_fudu, dacsin_output, dacref_clk);input clk, nrst, ncs;input mosi, sck;output miso;output dac_clk;output dacref_clk;output[11:0] dacref_fudu;output[11:0] dacsin_output;wire send_flag, rec_flag, sending_flag;wire[7:0] rec_data;wire[7:0] send_data;myspi U1(.clk(clk), .nrst(nrst), .ncs(ncs), .mosi(mosi), .miso(miso), .sck(sck), .rec_flag(rec_flag), .rec_data(rec_data), .send_flag(send_flag), .sending_flag(sending_flag), .send_data(send_data));dac_reg_rw_spi U2(.clk(clk), .nrst(nrst), .rec_flag(rec_flag), .rec_data(rec_data), .send_flag(send_flag), .sending_flag(sending_flag), .send_data(send_data),.dac_clk(dac_clk),.dacref_fudu(dacref_fudu),.dacsin_output(dacsin_output),.dacref_clk(dacref_clk));endmodule

四. ModelSim的功能验证

module dac_top_test;// Inputsreg clk;reg nrst;reg ncs;reg mosi;reg sck;// Outputswire miso;wire dac_clk;wire[11:0] dacref_fudu;wire[11:0] dacsin_output;// Instantiate the Unit Under Test (UUT)dac_top uut (.clk(clk), .nrst(nrst), .ncs(ncs), .mosi(mosi), .miso(miso), .sck(sck),.dac_clk(dac_clk),.dacref_fudu(dacref_fudu),.dacsin_output(dacsin_output));initial begin// Initialize Inputsclk = 0;nrst = 0;ncs = 1;mosi = 0;sck = 0;// Wait 100 ns for global reset to finish#100;nrst = 1;#20;ncs = 0;#100; mosi = 0; //先发送高位 00100011 写入频率控制字#100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 1; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 1; #100; sck = 1;#100; sck = 0; mosi = 1; #100; sck = 1;#100; sck = 0;//#100; mosi = 0; //发送 00001111#100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 1; #100; sck = 1;#100; sck = 0; mosi = 1; #100; sck = 1;#100; sck = 0; mosi = 1; #100; sck = 1;#100; sck = 0; mosi = 1; #100; sck = 1;#100; sck = 0;//#100; mosi = 1; //发送 11111110#100; sck = 1;#100; sck = 0; mosi = 1; #100; sck = 1;#100; sck = 0; mosi = 1; #100; sck = 1;#100; sck = 0; mosi = 1; #100; sck = 1;#100; sck = 0; mosi = 1; #100; sck = 1;#100; sck = 0; mosi = 1; #100; sck = 1;#100; sck = 0; mosi = 1; #100; sck = 1;#100; sck = 0; mosi = 1; #100; sck = 1;#100; sck = 0;//#100; mosi = 0; //发送 00000001#100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 1; #100; sck = 1;#100; sck = 0; //#100;#100 sck = 1; #100 sck = 0;#100 sck = 1; #100 sck = 0; #100 sck = 1; #100 sck = 0;#100 sck = 1; #100 sck = 0;#100 sck = 1; #100 sck = 0;#100 sck = 1; #100 sck = 0;#100 sck = 1; #100 sck = 0;#100 sck = 1; #100 sck = 0;//#100;#100 sck = 1; #100 sck = 0;#100 sck = 1; #100 sck = 0; #100 sck = 1; #100 sck = 0;#100 sck = 1; #100 sck = 0;#100 sck = 1; #100 sck = 0;#100 sck = 1; #100 sck = 0;#100 sck = 1; #100 sck = 0;#100 sck = 1; #100 sck = 0;//#100; mosi = 1; //发送 11100001 启动dac控制模块#100; sck = 1;#100; sck = 0; mosi = 1; #100; sck = 1;#100; sck = 0; mosi = 1; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 1; #100; sck = 1;#100; sck = 0; //#50000; mosi = 0; //延时50000个时间单元后再次修改频率控制字#100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 1; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 1; #100; sck = 1;#100; sck = 0;//#100; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 1; #100; sck = 1;#100; sck = 0;//#100; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0;//#100; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0;//#100; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0; mosi = 0; #100; sck = 1;#100; sck = 0;endalways #5 clk=~clk; //sck必须为clk的频率的十分之一或低于十分之一endmodule
最终的实物图~~




 

转载于:https://www.cnblogs.com/xhyzjiji/p/3712758.html

总结

以上是生活随笔为你收集整理的如何让FPGA中的SPI与其他模块互动起来的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。