一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

【接口時(shí)序】2、Verilog實(shí)現(xiàn)流水燈及與C語言的對比

 星海邊陲的天才 2019-10-17

一、 軟件平臺與硬件平臺

  軟件平臺:

  1、操作系統(tǒng):Windows-8.1

  2、開發(fā)套件:ISE14.7

  3、仿真工具:ModelSim-10.4-SE

  硬件平臺:

  1、FPGA型號:XC6SLX45-2CSG324

二、 原理介紹

  我的開發(fā)板上有4個(gè)LED燈,原理圖如下:

  

  由原理圖可知僅當(dāng)FPGA的對應(yīng)管腳輸入低電平時(shí)LED才會(huì)亮,流水燈的效果可以輪流讓四個(gè)對應(yīng)管腳輸出低電平來產(chǎn)生。

三、 目標(biāo)任務(wù)

  編寫四個(gè)LED流水的Verilog代碼并用ModelSim進(jìn)行仿真,仿真通過以后下載到開發(fā)板進(jìn)行測試,要求開發(fā)板上每個(gè)LED亮的時(shí)間為1s。

四、 設(shè)計(jì)思路與Verilog代碼編寫

  由于每個(gè)LED亮的時(shí)間為1s,所以首先很自然想到產(chǎn)生一個(gè)1s的時(shí)鐘用來驅(qū)動(dòng)后續(xù)邏輯,有了這個(gè)1s的時(shí)鐘以后,就可以在這個(gè)1s時(shí)鐘的節(jié)拍下對LED的輸出進(jìn)行以移位操作來產(chǎn)生流水燈的效果。

   1、1s時(shí)鐘的分頻邏輯

   由于主時(shí)鐘是50MHz,周期為20ns,所以可以利用50MHz主時(shí)鐘驅(qū)動(dòng)一個(gè)計(jì)數(shù)器,當(dāng)計(jì)數(shù)器的值每次到達(dá)24999999時(shí),消耗的時(shí)間為25000000*20ns=0.5s,這時(shí)把分頻器的輸出反轉(zhuǎn),并把計(jì)數(shù)值清0,這樣分頻器的輸出就會(huì)每隔0.5s翻轉(zhuǎn)一次,產(chǎn)生了一個(gè)1s的時(shí)鐘。

  Verilog代碼如下:

復(fù)制代碼
//////////////////////////////////////////////////////////////////// 功能:產(chǎn)生1s的時(shí)鐘//////////////////////////////////////////////////////////////////always @(posedge I_clk or negedge I_rst_n)beginif(!I_rst_n)beginR_cnt_ls        <= 32'd0 ; R_clk_ls_reg    <= 1'b1  ;end else if(R_cnt_ls == 32'd24_999_999)beginR_cnt_ls        <= 32'd0          ;R_clk_ls_reg    <= ~R_clk_ls_reg  ;  endelseR_cnt_ls <= R_cnt_ls + 1'b1 ;          endassign W_clk_ls = R_clk_ls_reg ;
復(fù)制代碼

  2、移位邏輯

  有了1s的時(shí)鐘信號以后,就在這個(gè)1s時(shí)鐘信號的驅(qū)動(dòng)下對輸出的LED寄存器進(jìn)行移位操作產(chǎn)生流水效果。

  Verilog代碼如下:

復(fù)制代碼
//////////////////////////////////////////////////////////////////// 功能:對輸出寄存器進(jìn)行移位產(chǎn)生流水效果//////////////////////////////////////////////////////////////////always @(posedge W_clk_ls or negedge I_rst_n)beginif(!I_rst_n) 
        R_led_out_reg <= 4'b0001 ; else if(R_led_out_reg == 4'b1000)R_led_out_reg <= 4'b0001 ;else    
        R_led_out_reg <= R_led_out_reg << 1 ;             
endassign O_led_out = ~R_led_out_reg ;
復(fù)制代碼

五、 ModelSim仿真

  寫好邏輯以后,為了確定時(shí)序是正確的,最好寫一個(gè)測試文件對功能進(jìn)行仿真,為了加快仿真速度,修改分頻邏輯計(jì)數(shù)器的計(jì)數(shù)值為24,然后編寫測試文件,測試文件中激勵(lì)產(chǎn)生的Verilog代碼如下:

復(fù)制代碼
initial begin// Initialize InputsI_clk = 0;
    I_rst_n = 0;// Wait 100 ns for global reset to finish#100;
    I_rst_n = 1;    // Add stimulus hereendalways #10 I_clk = ~I_clk ;
復(fù)制代碼

  仿真的時(shí)序圖如下圖所示:

可以看到時(shí)序完全正確,接下來就是綁定管腳,生成bit文件下載到開發(fā)板測試了。

六、 進(jìn)一步思考——C語言流水燈與Verilog流水燈區(qū)別

  看完網(wǎng)上《Verilog那些事》系列博文以后,作者提出了一種“仿順序操作”方法,其實(shí)以前自己寫代碼的時(shí)候無形之中一直在用這種思想,但是一直沒有提煉出來,看完作者的介紹以后才發(fā)現(xiàn)確實(shí)是有那個(gè)“仿順序”的味道。詳細(xì)的博文請參考博客園博主akuei2的系列博文。這里我在總結(jié)一遍,給以后留個(gè)印象。

  C語言實(shí)現(xiàn)流水燈的大致代碼框架如下:

    while(1)

    {

      1、讓第1個(gè)LED亮,其他的滅;

      2、延時(shí)1s

      3、讓第2個(gè)LED亮,其他的滅

      4、延時(shí)1s

      5、讓第3個(gè)LED亮,其他的滅;

      6、延時(shí)1s

      7、讓第4個(gè)LED亮,其他的滅

      8、延時(shí)1s

      }

  在while(1)里面代碼是一行一行的執(zhí)行,最后一行執(zhí)行完畢以后在回到第一行重新開始新一輪的執(zhí)行。就這樣產(chǎn)生了流水的效果。

  看到這里,有人應(yīng)該突然明白了吧,這不正好就是Verilog中的一個(gè)狀態(tài)機(jī)么。對應(yīng)的Verilog代碼也可以寫出來了 

  always @(posedge I_clk)

  begin

         case(R_state)

                第1個(gè)狀態(tài):讓第1個(gè)LED亮,其他的滅,下一狀態(tài)是第2個(gè)狀態(tài);

                第2個(gè)狀態(tài):延時(shí)1s,下一狀態(tài)是第3個(gè)狀態(tài);

                第3個(gè)狀態(tài):讓第2個(gè)LED亮,其他的滅,下一狀態(tài)是第4個(gè)狀態(tài);

                第4個(gè)狀態(tài):延時(shí)1s,下一狀態(tài)是第5個(gè)狀態(tài);

                第5個(gè)狀態(tài):讓第3個(gè)LED亮,其他的滅,下一狀態(tài)是第6個(gè)狀態(tài);

                第6個(gè)狀態(tài):延時(shí)1s,下一狀態(tài)是第7個(gè)狀態(tài);

                第7個(gè)狀態(tài):讓第4個(gè)LED亮,其他的滅,下一狀態(tài)是第8個(gè)狀態(tài);

                第8個(gè)狀態(tài):延時(shí)1s,下一狀態(tài)是第1個(gè)狀態(tài);

                default          : ;

         endcase

  end

  具體的代碼如下:

復(fù)制代碼
//////////////////////////////////////////////////////////////////// 功能:“仿順序操作”//////////////////////////////////////////////////////////////////always @(posedge I_clk or negedge I_rst_n)beginif(!I_rst_n)beginR_state  <= 3'b000 ; R_cnt_ls <= 32'd0  ;endelsebegin    case(R_state)
                C_S0:beginR_led_out_reg <= 4'b0001 ;R_state       <= C_S1    ;  endC_S1:beginif(R_cnt_ls == C_CNT_1S)beginR_cnt_ls <= 32'd0 ;R_state  <= C_S2  ;endelseR_cnt_ls <= R_cnt_ls + 1'b1 ;                endC_S2:beginR_led_out_reg <= 4'b0010 ;R_state       <= C_S3    ;  endC_S3:beginif(R_cnt_ls == C_CNT_1S)beginR_cnt_ls <= 32'd0 ;R_state  <= C_S4  ;endelseR_cnt_ls <= R_cnt_ls + 1'b1 ;                endC_S4:beginR_led_out_reg <= 4'b0100 ;R_state       <= C_S5    ;  endC_S5:beginif(R_cnt_ls == C_CNT_1S)beginR_cnt_ls <= 32'd0 ;R_state  <= C_S6  ;endelseR_cnt_ls <= R_cnt_ls + 1'b1 ;                endC_S6:beginR_led_out_reg <= 4'b1000 ;R_state <= C_S7 ;  endC_S7:beginif(R_cnt_ls == C_CNT_1S)beginR_cnt_ls <= 32'd0 ;R_state  <= C_S0  ;endelseR_cnt_ls <= R_cnt_ls + 1'b1 ;                end default: R_state <= 3'b000 ;                                                                               endcase end                  endassign O_led_out = ~R_led_out_reg ;
復(fù)制代碼

  時(shí)序圖如下圖:

  時(shí)序圖仍然正確,實(shí)現(xiàn)了流水燈的效果

七、 總結(jié)

  1、所謂的“仿順序操作”實(shí)際上就是一個(gè)狀態(tài)機(jī),通過狀態(tài)的跳變實(shí)現(xiàn)“順序執(zhí)行”的效果。這種思想在后面寫接口時(shí)序的時(shí)候還是挺管用的,今后可以多多琢磨琢磨。

  2、 C語言的while(1)和Verilog語言的always @(posedge I_clk)有類似的地方,只要CPU的時(shí)鐘存在,它們就一直執(zhí)行下去。書上都說C語言是一種串行語言,Verilog是一種并行語言,實(shí)際上這里也能有體會(huì):C語言里只能有1個(gè)while(1)語句,進(jìn)入while(1)以后CPU就出不來了,而Verilog中可以有多個(gè)always @(posedge I_clk)語句,并且每個(gè)always @(posedge I_clk)同時(shí)運(yùn)行的,這就是兩種語言最大的區(qū)別吧。

八、 附錄

  1、分頻1s產(chǎn)生流水燈的完整代碼

復(fù)制代碼
module led_work_top
(input           I_clk       ,input           I_rst_n     ,output  [3:0]   O_led_out
);reg  [31:0]  R_cnt_ls      ;wire         W_clk_ls      ;reg          R_clk_ls_reg  ;reg  [3:0]   R_led_out_reg ;//////////////////////////////////////////////////////////////////// 功能:產(chǎn)生1s的時(shí)鐘//////////////////////////////////////////////////////////////////always @(posedge I_clk or negedge I_rst_n)beginif(!I_rst_n)beginR_cnt_ls        <= 32'd0 ; R_clk_ls_reg    <= 1'b1  ;end else if(R_cnt_ls == 32'd24_999_999)beginR_cnt_ls        <= 32'd0          ;R_clk_ls_reg    <= ~R_clk_ls_reg  ;  endelseR_cnt_ls <= R_cnt_ls + 1'b1 ;          endassign W_clk_ls = R_clk_ls_reg ;//////////////////////////////////////////////////////////////////// 功能:對輸出寄存器進(jìn)行移位產(chǎn)生流水效果//////////////////////////////////////////////////////////////////always @(posedge W_clk_ls or negedge I_rst_n)beginif(!I_rst_n) 
        R_led_out_reg <= 4'b0001 ; else if(R_led_out_reg == 4'b1000)R_led_out_reg <= 4'b0001 ;else    
        R_led_out_reg <= R_led_out_reg << 1 ;             
endassign O_led_out = ~R_led_out_reg ;endmodule
復(fù)制代碼

  2、 “仿順序操作”產(chǎn)生流水燈完整代碼

復(fù)制代碼
module led_work_top
(input           I_clk         ,input           I_rst_n       ,output  [3:0]   O_led_out     
);                                
                                  
reg  [31:0]  R_cnt_ls             ;reg  [3:0]   R_led_out_reg        ;reg  [2:0]   R_state              ;parameter    C_CNT_1S =   32'd49_999_999  ;          parameter    C_S0     =   3'b000  , C_S1     =   3'b001  , C_S2     =   3'b010  , C_S3     =   3'b011  , C_S4     =   3'b100  , C_S5     =   3'b101  , C_S6     =   3'b110  , C_S7     =   3'b111  ;//////////////////////////////////////////////////////////////////// 功能:仿順序操作//////////////////////////////////////////////////////////////////always @(posedge I_clk or negedge I_rst_n)beginif(!I_rst_n)beginR_state  <= 3'b000 ; R_cnt_ls <= 32'd0  ;endelsebegin    case(R_state)
                C_S0:beginR_led_out_reg <= 4'b0001 ;R_state       <= C_S1    ;  endC_S1:beginif(R_cnt_ls == C_CNT_1S)beginR_cnt_ls <= 32'd0 ;R_state  <= C_S2  ;endelseR_cnt_ls <= R_cnt_ls + 1'b1 ;                endC_S2:beginR_led_out_reg <= 4'b0010 ;R_state       <= C_S3    ;  endC_S3:beginif(R_cnt_ls == C_CNT_1S)beginR_cnt_ls <= 32'd0 ;R_state  <= C_S4  ;endelseR_cnt_ls <= R_cnt_ls + 1'b1 ;                endC_S4:beginR_led_out_reg <= 4'b0100 ;R_state       <= C_S5    ;  endC_S5:beginif(R_cnt_ls == C_CNT_1S)beginR_cnt_ls <= 32'd0 ;R_state  <= C_S6  ;endelseR_cnt_ls <= R_cnt_ls + 1'b1 ;                endC_S6:beginR_led_out_reg <= 4'b1000 ;R_state <= C_S7 ;  endC_S7:beginif(R_cnt_ls == C_CNT_1S)beginR_cnt_ls <= 32'd0 ;R_state  <= C_S0  ;endelseR_cnt_ls <= R_cnt_ls + 1'b1 ;                end default: R_state <= 3'b000 ;                                                                               endcase end                  endassign O_led_out = ~R_led_out_reg ;endmodule
復(fù)制代碼

  3、測試記錄文件完整代碼

復(fù)制代碼
module tb_led_work_top;// Inputsreg I_clk;reg I_rst_n;// Outputswire [3:0] O_led_out;// Instantiate the Unit Under Test (UUT)led_work_top U_led_work_top (
        .I_clk(I_clk), 
        .I_rst_n(I_rst_n), 
        .O_led_out(O_led_out)
    );initial begin// Initialize InputsI_clk = 0;
        I_rst_n = 0;// Wait 100 ns for global reset to finish#100;
        I_rst_n = 1;        // Add stimulus hereendalways #5 I_clk = ~I_clk ;      
endmodule
復(fù)制代碼

歡迎關(guān)注我的公眾號:FPGA之禪

https://www.cnblogs.com/liujinggang/p/9463589.html

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    91久久精品在这里色伊人| 国产无摭挡又爽又色又刺激| 亚洲一区二区三区日韩91| 日韩夫妻午夜性生活视频| 精品人妻一区二区四区| 国产综合香蕉五月婷在线| 久久碰国产一区二区三区| 国产一级特黄在线观看| 亚洲男人的天堂就去爱| 九九热这里只有精品哦| 久久综合九色综合欧美| 免费黄片视频美女一区| 伊人久久五月天综合网| 国产日本欧美韩国在线| 日本一二三区不卡免费 | 日韩中文字幕狠狠人妻| 五月激情婷婷丁香六月网| 国产精品一区二区有码| 国产在线成人免费高清观看av| 国产av大片一区二区三区| 午夜久久精品福利视频| 绝望的校花花间淫事2| 扒开腿狂躁女人爽出白浆av| 这里只有九九热精品视频| 人妻少妇av中文字幕乱码高清| 国产亚洲成av人在线观看| 国产精品欧美激情在线| 深夜福利亚洲高清性感| 我想看亚洲一级黄色录像| 亚洲国产综合久久天堂| 午夜福利直播在线视频| 91精品国产综合久久不卡| 精品少妇一区二区三区四区| 欧美日韩黑人免费观看| 精品一区二区三区不卡少妇av| 午夜视频成人在线免费| 国产日本欧美特黄在线观看| 国产一区在线免费国产一区| 国产级别精品一区二区视频 | 国产成人精品视频一区二区三区| 日本精品中文字幕人妻|