練習九.利用狀態機的嵌套實現層次結構化設計目的:1.運用主狀態機與子狀態機產生層次化的邏輯設計;
2.在結構化設計中靈活使用任務(task)結構。
在上一節,我們學習了如何使用狀態機的實例。實際上,單個有限狀態機控制整個邏輯電路的運轉在實際設計中是不多見,往往是狀態機套用狀態機,從而形成樹狀的控制核心。這一點也與我們提倡的層次化、結構化的自頂而下的設計方法相符,下面我們就將提供一個這樣的示例以供大家學習。
該例是一個簡化的EPROM的串行寫入器。事實上,它是一個EPROM讀寫器設計中實現寫功能的部分經刪節得到的,去除了EPROM的啟動、結束和EPROM控制字的寫入等功能,只具備這樣一個雛形。工作的步驟是:1.地址的串行寫入;2.數據的串行寫入;3.給信號源應答,信號源給出下一個操作對象;4.結束寫操作。通過移位令并行數據得以一位一位輸出。
模塊源代碼:
module writing(reset,clk,address,data,sda,ack);
? input reset,clk;
? input[7:0] data,address;
? output sda,ack; //sda負責串行數據輸出;
? //ack是一個對象操作完畢后,模塊給出的應答信號。
? reg link_write; //link_write 決定何時輸出。
? reg[3:0] state; //主狀態機的狀態字。
? reg[4:0] sh8out_state; //從狀態機的狀態字。
? reg[7:0] sh8out_buf;??? //輸入數據緩沖。
? reg finish_F;?????????? //用以判斷是否處理完一個操作對象。
? 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)?????????????? //復位。
????????? 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:?????? //數據的寫入。
??????????? 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:???????????? //完成應答。
??????????? 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?????????
測試模塊源代碼:
`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)????? //接收到應答信號后,給出下一個處理對象。
??? 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]]
練習:仿照上例,編寫一個實現EPROM內數據串行讀取的模塊。編寫測試模塊,給出仿真波形。
利用狀態機的狀態機實現層次結構化設計
- 狀態機(27117)
- FGPA(15865)
相關推薦
狀態機編程實例-狀態表法
上篇文章,使用嵌套switch-case法的狀態機編程,實現了一個炸彈拆除小游戲。本篇,繼續介紹狀態機編程的第二種方法:狀態表法,來實現炸彈拆除小游戲的狀態機編程。
2023-06-20 09:05:05
1190


Spring狀態機的實現原理和使用方法
說起 Spring 狀態機,大家很容易聯想到這個狀態機和設計模式中狀態模式的區別是啥呢?沒錯,Spring 狀態機就是狀態模式的一種實現,在介紹 Spring 狀態機之前,讓我們來看看設計模式中的狀態模式。
2023-12-26 09:39:02
664


Verilog狀態機+設計實例
在verilog中狀態機的一種很常用的邏輯結構,學習和理解狀態機的運行規律能夠幫助我們更好地書寫代碼,同時作為一種思想方法,在別的代碼設計中也會有所幫助。 一、簡介 在使用過程中我們常說
2024-02-12 19:07:39
1818


狀態機
控制狀態機控制狀態機的初始化和狀態轉換的最佳方法是使用枚麗型輸入控件。一般使用自定義類型的枚麗變量。使用子定義類型的枚麗變量可以是控件和實例乊間存在關聯,使得添加或刪除狀態時所有的枚麗型輸入控件副本自動更新。
2014-02-13 12:39:31
評論