本帖最后由 fpgaw 于 2010-11-18 16:07 编辑
module bus_fsm(clk,ale,rd,wr,cs,data);
input clk,ale,rd,wr,cs;//cs由P2口译码得到
inout [7:0] data; //双向地址/数据总线
reg [7:0] address_reg,//地址寄存器
data_reg1, //数据寄存器1,2
data_reg2,
data_temp; //输入/输出数据暂存
reg [15:0] result; //计算结果寄存器
reg wr1,rd1;//WR RD信号延迟一个周期,供检测用
wire [7:0] data_hold;//输入数据线
reg [3:0] state; //状态机
parameter waiting_write=4'b0000,
data_in =4'b0001,
data_done =4'b0010,
waiting_read =4'b0100,
data_out =4'b1000;
assign data =!rd ? data_temp : 8'hzz, //RD为低时将TEMP中内容送入总线
data_hold =!wr ? data : data_hold;//WR为低时锁存总线上的数据
always@(negedge ale)
begin
if(!cs)
address_reg<=data;//CS有效时,ALE下降沿锁存8位地址
else
address_reg<=8'hff; //片选无效,置1
end
always@(posedge clk)
begin
case(state)
waiting_write:
begin
if(wr1&&!wr) //WR出现下降沿时,锁存数据
begin
data_temp <=data_hold;
state <=data_in;
end
else
state<=waiting_write;//WR没有下降沿,等待
wr1<=wr;
end
data_in:
begin
if(address_reg==8'hf0)
begin
data_reg1 <=data_temp;//锁存第一个数据
state <=waiting_write; //等待写入第二个数据
end
else if(address_reg==8'hf1)
begin
data_reg2 <=data_temp;
state <=data_done;//两个数据锁存完毕
end
else
begin
data_reg1 <=8'h00; //地址错误,
data_reg2 <=8'h00; //寄存器清零,转等待写入状态
state <=waiting_write;
end
end
data_done:
begin
result <=data_reg1*data_reg2;//计算结果送RESULT
state <=waiting_read;
end
waiting_read:
begin
if(rd1&&!rd)
state <=data_out; //RD出现下降沿,转入下一状态
else //否则,等待读信号
state <=waiting_read;
rd1<=rd;
end
data_out:
begin
if(address_reg==8'hf2)
begin
data_temp <=result [7:0]; //读低8位,
state <=waiting_read; //等待读高8位
end
else if(address_reg==8'hf3)
begin
data_temp <=result [15:0];
state <=waiting_write;//数据读完,转等待写数据
end
else
state <=waiting_read; //地址错误,继续等待
end
default:
state <=waiting_write;
endcase
end
endmodule |