練習(xí)九.利用狀態(tài)機(jī)的嵌套實(shí)現(xiàn)層次結(jié)構(gòu)化設(shè)計(jì)目的:1.運(yùn)用主狀態(tài)機(jī)與子狀態(tài)機(jī)產(chǎn)生層次化的邏輯設(shè)計(jì);
?。?在結(jié)構(gòu)化設(shè)計(jì)中靈活使用任務(wù)(task)結(jié)構(gòu)。
在上一節(jié),我們學(xué)習(xí)了如何使用狀態(tài)機(jī)的實(shí)例。實(shí)際上,單個(gè)有限狀態(tài)機(jī)控制整個(gè)邏輯電路的運(yùn)轉(zhuǎn)在實(shí)際設(shè)計(jì)中是不多見(jiàn),往往是狀態(tài)機(jī)套用狀態(tài)機(jī),從而形成樹(shù)狀的控制核心。這一點(diǎn)也與我們提倡的層次化、結(jié)構(gòu)化的自頂而下的設(shè)計(jì)方法相符,下面我們就將提供一個(gè)這樣的示例以供大家學(xué)習(xí)。
該例是一個(gè)簡(jiǎn)化的EPROM的串行寫入器。事實(shí)上,它是一個(gè)EPROM讀寫器設(shè)計(jì)中實(shí)現(xiàn)寫功能的部分經(jīng)刪節(jié)得到的,去除了EPROM的啟動(dòng)、結(jié)束和EPROM控制字的寫入等功能,只具備這樣一個(gè)雛形。工作的步驟是:1.地址的串行寫入;2.數(shù)據(jù)的串行寫入;3.給信號(hào)源應(yīng)答,信號(hào)源給出下一個(gè)操作對(duì)象;4.結(jié)束寫操作。通過(guò)移位令并行數(shù)據(jù)得以一位一位輸出。
模塊源代碼:
module writing(reset,clk,address,data,sda,ack);
? input reset,clk;
? input[7:0] data,address;
? output sda,ack; //sda負(fù)責(zé)串行數(shù)據(jù)輸出;
? //ack是一個(gè)對(duì)象操作完畢后,模塊給出的應(yīng)答信號(hào)。
? reg link_write; //link_write 決定何時(shí)輸出。
? reg[3:0] state; //主狀態(tài)機(jī)的狀態(tài)字。
? reg[4:0] sh8out_state; //從狀態(tài)機(jī)的狀態(tài)字。
? reg[7:0] sh8out_buf;??? //輸入數(shù)據(jù)緩沖。
? reg finish_F;?????????? //用以判斷是否處理完一個(gè)操作對(duì)象。
? reg ack;
? parameter
??? idle=0,addr_write=1,data_write=2,stop_ack=3;
? parameter
??? bit0=1,bit1=2,bit2=3,bit3=4,bit4=5,bit5=6,bit6=7,bit7=8;
? assign?? sda = link_write? sh8out_buf[7] : 1'bz;
? always @(posedge clk)
??? begin
??????? if(!reset)?????????????? //復(fù)位。
????????? begin
???????????? link_write<= 0;
???????????? state??? <= idle;
???????????? finish_F <= 0;
???????????? sh8out_state<=idle;
?????????????????? ack<= 0;
???????????? sh8out_buf<=0;
????????? end
??????? else
????????? case(state)
????????? idle:??????????????????????
??????????? begin
??????????????? link_write? <= 0;
?????????????? state??? <= idle;
?????????????? finish_F <= 0;
?????????????? sh8out_state<=idle;
???????????????????? ack<= 0;
?????????????? sh8out_buf<=address;?
????????????? state??? <= addr_write;
??????????? end
????????? addr_write:???????? //地址的輸入。
??????????? begin
??????????????? if(finish_F==0)
????????????????? begin? shift8_out; end
??????????????? else
????????????????? begin
???????????????????? sh8out_state <= idle;
???????????????????? sh8out_buf?? <= data;
??????????????????????????? state <= data_write;
???????????????????????? finish_F <= 0;
????????????????? end
??????????? end
????????? data_write:?????? //數(shù)據(jù)的寫入。
??????????? begin
??????????????? if(finish_F==0)
????????????????? begin? shift8_out; end
??????????????? else
????????????????? begin
????????????????????? link_write <= 0;
?????????????????????????? state <= stop_ack;
??????????????????????? finish_F <= 0;?
???????????????????????????? ack <= 1;
????????????????? end
??????????? end????
????????? stop_ack:???????????? //完成應(yīng)答。
??????????? begin
????????????????? ack <= 0;
????????????? state <= idle;
??????????? end
?????????
????????? endcase??????
??? end??????????????????????????
task shift8_out;??????????????? //串行寫入。
? begin
???? case(sh8out_state)
???? idle:
?????? begin
?????????? link_write? <= 1;
????????? sh8out_state <= bit0;
??????? end
???? bit0:
?????? begin
?????????? link_write <= 1;
???????? sh8out_state <= bit1;????????????????????????????????
?????????? sh8out_buf <= sh8out_buf<<1;
?????? end
???? bit1:
?????? begin
???????? sh8out_state<=bit2;
???????? sh8out_buf<=sh8out_buf<<1;
?????? end
???? bit2:
?????? begin
???????? sh8out_state<=bit3;
???????? sh8out_buf<=sh8out_buf<<1;
?????? end
???? bit3:
?????? begin
???????? sh8out_state<=bit4;
???????? sh8out_buf<=sh8out_buf<<1;
?????? end
???? bit4:
?????? begin
???????? sh8out_state<=bit5;
???????? sh8out_buf<=sh8out_buf<<1;
?????? end
????
???? bit5:
?????? begin
???????? sh8out_state<=bit6;
???????? sh8out_buf<=sh8out_buf<<1;
?????? end
???? bit6:
?????? begin
???????? sh8out_state<=bit7;
???????? sh8out_buf<=sh8out_buf<<1;
?????? end
???? bit7:
?????? begin
???????? link_write<= 0;
???????? finish_F<=finish_F+1;???????????????????????????????
?????? end?
??????
???? endcase
? end
endtask
endmodule?????????
測(cè)試模塊源代碼:
`timescale 1ns/100ps
`define clk_cycle 50
module writingTop;
? reg reset,clk;
? reg[7:0] data,address;
? wire ack,sda;
? always #`clk_cycle? clk = ~clk;
? initial
??? begin
??????????? clk=0;
??????????? reset=1;
??????????? data=0;
??????????? address=0;
??????????? #(2*`clk_cycle) reset=0;
??????????? #(2*`clk_cycle) reset=1;
?????? #(100*`clk_cycle) $stop;
??? end
? always @(posedge ack)????? //接收到應(yīng)答信號(hào)后,給出下一個(gè)處理對(duì)象。
??? begin
??????????? data=data+1;
??????????? address=address+1;
??? end????????
? writing writing(.reset(reset),.clk(clk),.data(data),
????????????????? .address(address),.ack(ack),.sda(sda));?
endmodule???????
仿真波形:[[wysiwyg_imageupload:252:height=174,width=496]]
練習(xí):仿照上例,編寫一個(gè)實(shí)現(xiàn)EPROM內(nèi)數(shù)據(jù)串行讀取的模塊。編寫測(cè)試模塊,給出仿真波形。
利用狀態(tài)機(jī)的狀態(tài)機(jī)實(shí)現(xiàn)層次結(jié)構(gòu)化設(shè)計(jì)
- 狀態(tài)機(jī)(27117)
- FGPA(15865)
相關(guān)推薦
狀態(tài)機(jī)編程實(shí)例-狀態(tài)表法
上篇文章,使用嵌套switch-case法的狀態(tài)機(jī)編程,實(shí)現(xiàn)了一個(gè)炸彈拆除小游戲。本篇,繼續(xù)介紹狀態(tài)機(jī)編程的第二種方法:狀態(tài)表法,來(lái)實(shí)現(xiàn)炸彈拆除小游戲的狀態(tài)機(jī)編程。
2023-06-20 09:05:05
1190


SaberRD狀態(tài)機(jī)建模工具介紹(一)什么是狀態(tài)機(jī)建模
狀態(tài)機(jī)建模是使用狀態(tài)圖和方程式的手段,創(chuàng)建基于混合信號(hào)的有限狀態(tài)機(jī)模型的一種建模工具。
2023-12-05 09:51:02
430


Spring狀態(tài)機(jī)的實(shí)現(xiàn)原理和使用方法
說(shuō)起 Spring 狀態(tài)機(jī),大家很容易聯(lián)想到這個(gè)狀態(tài)機(jī)和設(shè)計(jì)模式中狀態(tài)模式的區(qū)別是啥呢?沒(méi)錯(cuò),Spring 狀態(tài)機(jī)就是狀態(tài)模式的一種實(shí)現(xiàn),在介紹 Spring 狀態(tài)機(jī)之前,讓我們來(lái)看看設(shè)計(jì)模式中的狀態(tài)模式。
2023-12-26 09:39:02
664


Verilog狀態(tài)機(jī)+設(shè)計(jì)實(shí)例
在verilog中狀態(tài)機(jī)的一種很常用的邏輯結(jié)構(gòu),學(xué)習(xí)和理解狀態(tài)機(jī)的運(yùn)行規(guī)律能夠幫助我們更好地書(shū)寫代碼,同時(shí)作為一種思想方法,在別的代碼設(shè)計(jì)中也會(huì)有所幫助。 一、簡(jiǎn)介 在使用過(guò)程中我們常說(shuō)
2024-02-12 19:07:39
1818


狀態(tài)機(jī)
控制狀態(tài)機(jī)控制狀態(tài)機(jī)的初始化和狀態(tài)轉(zhuǎn)換的最佳方法是使用枚麗型輸入控件。一般使用自定義類型的枚麗變量。使用子定義類型的枚麗變量可以是控件和實(shí)例乊間存在關(guān)聯(lián),使得添加或刪除狀態(tài)時(shí)所有的枚麗型輸入控件副本自動(dòng)更新。
2014-02-13 12:39:31
評(píng)論