Verilog设计练习进阶(9)-------利用状态机的嵌套实现层次结构化设计
说明:此程序有错,所以放在也是错误的,不过不影响状态机的学习。module verilog_prj(reset,clk,address,data,sda,ack);
input reset,clk;
input data,address;
output sda,ack;//sda 负责串行数据输出;
//ack是一个对象操作完毕后,模块给出的应答信号。
reg link_write;//link_write决定何时输出。
reg state;//主状态机的状态字。
reg sh8out_state;//从状态机的状态字。
reg 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 : 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)
beginshift8_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)
beginshift8_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 1 ns/ 1 ps
`define clk_cycle 50
module verilog_prj_vlg_tst();
// test vector input registers
reg address;
reg clk;
reg data;
reg reset;
// wires
wire ack;
wire sda;
// assign statements (if any)
verilog_prj i1 (
// port map - connection between master ports and signals/registers
.ack(ack),
.address(address),
.clk(clk),
.data(data),
.reset(reset),
.sda(sda)
);
always #`clk_cycleclk = ~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
endmodule
页:
[1]