利用狀態(tài)機(jī)的狀態(tài)機(jī)實(shí)現(xiàn)層次結(jié)構(gòu)化設(shè)計(jì)
練習(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的串行寫(xiě)入器。事實(shí)上,它是一個(gè)EPROM讀寫(xiě)器設(shè)計(jì)中實(shí)現(xiàn)寫(xiě)功能的部分經(jīng)刪節(jié)得到的,去除了EPROM的啟動(dòng)、結(jié)束和EPROM控制字的寫(xiě)入等功能,只具備這樣一個(gè)雛形。工作的步驟是:1.地址的串行寫(xiě)入;2.數(shù)據(jù)的串行寫(xiě)入;3.給信號(hào)源應(yīng)答,信號(hào)源給出下一個(gè)操作對(duì)象;4.結(jié)束寫(xiě)操作。通過(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] : 1bz;
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ù)的寫(xiě)入。
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; //串行寫(xiě)入。
begin
case(sh8out_state)
idle:
begin
link_write = 1;
sh8out_state = bit0;
end
bit0:
begin
link_write = 1;
sh8out_state = bit1;
sh8out_buf = sh8out_buf1;
end
bit1:
begin
sh8out_state=bit2;
sh8out_buf=sh8out_buf1;
end
bit2:
begin
sh8out_state=bit3;
sh8out_buf=sh8out_buf1;
end
bit3:
begin
sh8out_state=bit4;
sh8out_buf=sh8out_buf1;
end
bit4:
begin
sh8out_state=bit5;
sh8out_buf=sh8out_buf1;
end
bit5:
begin
sh8out_state=bit6;
sh8out_buf=sh8out_buf1;
end
bit6:
begin
sh8out_state=bit7;
sh8out_buf=sh8out_buf1;
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í):仿照上例,編寫(xiě)一個(gè)實(shí)現(xiàn)EPROM內(nèi)數(shù)據(jù)串行讀取的模塊。編寫(xiě)測(cè)試模塊,給出仿真波形。
評(píng)論