【文章內容簡介】
測試模塊搭建 micro module: 微處理器部分可以采用 ZYE1502D 實驗箱上有的 AT89C51 單片機,或者編寫 Testbench 實現(xiàn)。為了仿真方便,在仿真時采用 Testbench 搭建。該micro 模型給出了微處理器與 IIC接口通訊的仿真程序。該模型能產生相應的讀寫信號,地址信號,并行數(shù)據(jù)信號,并能接收從器件的應答信號,來調節(jié)發(fā)送或接收數(shù)據(jù)的速度。在這個程序中,為了保證 IIC接口的正確性,可以進行完整的測試,寫操作 時輸入的地址信號和數(shù)據(jù)信號的數(shù)據(jù)由于較少,直接寫入程序中。讀操作時,將讀數(shù)對比可以驗證程序的正確性。該程序通過調用四個任務實現(xiàn)上述功能, write,monitor_iic_rdy, read_data, kill_time。 iic_slave module: 該 iic_slave 模型提供了一個 IIC 存儲器。該從模型能夠偵測起始和終止命令,在地址控制字時序后產生 ACK,在數(shù)據(jù)讀之后置 IIC總線三態(tài)。另外它通過比較“ Slave Data Receive on Write”和“ Slave Data Transmitted on Read”的信息,實現(xiàn)仿真時數(shù)據(jù)正確性的檢查。 clk_rst module:clk_rst 模塊給測試平臺提供時鐘和復位信號 。編輯clk_period參數(shù)更改時鐘頻率,改變 reset_time參數(shù)就能改變復位信號的有效時間。 iic_tb, iic_tb 是測試臺的頂層文件。它將 IIC 接口模型 iic 和測試程序的模型 clk_rst、 micro、 iic_slave 實例化,并連接起來。其主要程序: i2c I2C(.data(data),.addr(addr),.rst_l(rst_l),.clock(clock),.cs_l(cs_l), .ack_l(ack_l),.rd_wr_l(rd_wr_l),.scl_pin(scl_pin),.sda_pin(sda_pin))。 clk_rst CLK(.clk(clock),.rst_l(rst_l))。 micro MICRO(.clk(clock),.rst_l(rst_l),.data(data),.addr(addr),.cs_l(cs_l), .ack_l(ack_l),.rd_wr_l(rd_wr_l))。 i2c_slave SEP(.sda(sda_pin),.scl(scl_pin))。 時序仿真 做功能仿真時,在 Modelsim 中建立工程,把 IIC 的所有 verilog hdl 文件,以及 Testbench 用到的 verilog 文件加入到工程中,然后編譯仿真。仿真波形如圖 , 所示。 圖 iic_rst 仿真圖 圖 功能仿真波形 由輸出結果可只,微處理器發(fā)送寫地址 10100000,響應后寫入數(shù)據(jù) 55H,響應后重新發(fā)啟動信號,發(fā)送讀地址 10100001,響應后讀出數(shù)據(jù),進行 比較。同樣操作,寫入數(shù)據(jù) AAH 并讀出比較,結果兩次數(shù)據(jù)讀回均正確無誤。 結束語 本課題設計了基于 FPGA 的 IIC 接口的數(shù)個模塊,時鐘模塊、接收模塊、發(fā)送模塊、時序控制模塊和輸出緩沖模塊,其中時序控制模塊是設計的重點和難點。每個模塊都通過了功能仿真和時序仿真,仿真結果表明,各個模塊均完成了相應的邏輯功能。 整個設計都采用了同步方式,而且沒有使用特定公司的技術和 IP 核,這使得設計可以廣泛地重用,但也存在著可改進之處: 需要提高 Verilog HDL 語言代碼的效率,要力求用最簡潔,可綜合的描述方 式描述模塊的 結構和功能,以使得芯片面積、功耗減小。 在基于 FPGA 的器件上,進行邏輯綜合過程中,許多約束條件是相互矛盾的,這需要反復設定條件,以求電路結構得到優(yōu)化。 基于 Verilog HDL 語言的可移植性,及不依賴器件的特性,設計者能在更抽象的層次上把握和描述系統(tǒng)結構和功能特性,使設計更具靈活性。由于 FPGA 器件的快速發(fā)展,其容量可以將各種外圍器件的接口集成到 FPGA 內部,這樣可以實現(xiàn)設計的小型化,低功耗,并且降低了設計的復雜度,而且利用 FPGA 在線可編程特點,可以增加系統(tǒng)設計的靈活度,提高了設計效率。 在課題期間,通過不斷地學習、探索和實踐,掌握了 Verilog HDL 設計技術及其FPGA 的應用,提高了實際的工作能力和創(chuàng)新能力。 最后感謝我的老師和同學們,在他們的監(jiān)督和幫助下讓我順利完成了本次的課程設計。 參考文獻 [1]蘇建志 ,王冰鋒 .IIC總線及其應用 .現(xiàn)代電子技術 ,2020,22. [2]趙輝 .IIC總線技術及其應用實例 .微型電腦應用 ,2020,31(4):61. [3]周立功 .IIC總線概要 .產品應用手冊 ,2020,3. [4]石宗義 .總線的時序分析及其模擬 [J].太原理工大學學報 ,2020,35(1):53. [5]朱明程 ,黃強 .FPGA 動態(tài)可重構邏輯設計初探 .半導體技術 ,2020,25(4):19. [6]褚振勇 .FPGA 設計及應用 [M].西安 :西安電子科技大學出版社 ,2020. [7]王毓銀 .數(shù)字電路邏輯設計 [M].北京 :高等教育出版社 ,1999. [8]李洪偉 .基于 QuartusII 的 FPGA/CPLD 設計 [M].北京 :電子工業(yè)出版社 ,2020. 附錄 1 時鐘分頻器程序 c l kr e s e ts c l _ c n t _ e n11111010 DE N AQP R EC L Rc l o c krs t _ ls c l _ c n t _ e ns c l _ t i c ks c l _ t i c k ~ re g 0c n t r module iic_clk(clock,rst_l,scl_t_en,scl_tick)。 //端口列表 input clock。//外部系統(tǒng)處理器時鐘 input rst_l。//外部復位信號 ,低有效 input scl_t_en。//來自時序控制器的計數(shù)使能信號 output scl_tick。//狀態(tài)機的工作時鐘 //registersamp。wires reg scl_tick。 reg [7:0] tr。//分頻計數(shù)值 //分頻 always@(posedge clock or negedge rst_l) if(!rst_l) tr= 1 839。b0。 else if(scl_t_en) tr= 1 839。b0。 else tr=839。b0。 always@(posedge clock or negedge rst_l) if(!rst_l) scl_tick= 1 139。b0。 else if(tr= =839。hFA) cl_tick= 1 139。b1。 else scl_tick= 1 139。b0。 endmodule 附錄 2 數(shù)據(jù)接收模塊程序 DE N AQP R EC L R=A [ 1 . . 0 ]B [ 1 . . 0 ]E Q U A L010011DE N AQP R EC L RD QP R EE N AC L Ra c k _ l ~ re g 0a l w a y s 0 ~ 1Eq u a l 02 39。 h 0 i i c _ g o ~ 0 i i c _ g o ~ 1i i c _ g o ~ re g 0w rd _ a d d [ 7 . . 0 ] ~ re g 0rs t _ lc l o c ks c l _ c n t _ e nc s _ li i c _ g oa c k _ ld a t a [ 7 . . 0 ]a d d r[ 1 . . 0 ]w rd _ a d d [ 7 . . 0 ]rd _ w r_ l `timescale 1 ns/100 ps module iic_wreg(data, addr, rst_l, clock, scl_t_en, rd_wr_l, cs_l, wrd_add,iic_go, ack_l)。 //端口列表 input [7:0] data。//處理器輸出的數(shù)據(jù)碼 input [1:0] addr。//處理器輸出的地址碼 input rst_l。//復位信號 input clock。//系統(tǒng)時鐘 input cs_l, scl_t_en。//系統(tǒng)使能信號 input rd_wr_l。//命令信號 output [7:0] wrd_add。//字地址 output iic_go。//iic 總線啟動信號 output ack_l。//反饋給處理器的響應信號 //寄存器型 reg [7:0] wrd_add。 reg iic_go。 reg ack_l。 //寄存器參數(shù) parameter w_add=239。b00。//地址寄存器 parameter d_add=239。b01。//數(shù)據(jù)寄存器 parameter s_add=239。b10。//狀態(tài)寄存器 always@(posedge clock or negedge rst_l) if(!rst_l) wrd_add = 1 839。b0。 else if(cs_lamp。amp。!rd_wr_lamp。amp。(addr= =w_add)) wrd_add = 1 data。 always@(posedge clock or negedge rst_l) if(!rst_l) iic_go= 1 139。b0。 else if(cs_lamp。amp。!rd_wr_lamp。amp。(addr= =w_add)) iic_go= 1 139。b1。//iic 總線的啟動信號 else if(scl_t_en) iic_go= 1 139。b0。 //反饋響應信號 always@(posedge clock or negedge rst_l) if(!rst_l) ack_l= 1 139。b1。 else if(cs_l) ack_l= 1 139。b0。 else ack_l= 1 139。b1。 endmodule 附錄 3 發(fā)送寄存器程序 `timescale 1 ns/100 ps module iic_rreg(wrd_add,iic_rdata,iic_rdy,iic_act,ack_err,addr,data_o)。 input [7:0] wrd_add。//iic word address input [7:0] iic_rdata。//iic read data input iic_rdy。//iic status bit input iic_act。//iic cycle active input ack_err。//ack error input [1:0] addr。//cpu address output [7:0] data_o。//muxed cpu data output //寄存器型 reg[7:0] data_o。//muxed cpu data output //參數(shù) Parameter w_add=239。b00。//字地址寄存器 parameter d_add=239。b01。//數(shù)據(jù)寄存器 parameter s_add=239。b10。//狀態(tài)寄存器 //數(shù)據(jù)多用輸出 always@(addr or wrd_add or ack_err or iic_rdata or iic_rdy) case(addr) w_add::data_o= 1 wrd_add。 d_add::data_o= 1 iic_rdata。 s_add:data_o= 1{iic_rdy,ack_err,539。b0,iic_act}。 default:data_o= 1{iic_rdy,ack_err,539。b0,iic_act}。 endcase endmodule