如何让FPGA中的SPI与其他模块互动起来
生活随笔
收集整理的這篇文章主要介紹了
如何让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与其他模块互动起来的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 反射和动态代理实现上下文切入AOP效果
- 下一篇: 【PHP ThinkPHP框架】小bug