usb 发表于 2010-6-27 23:19:45

状态机实现的与8051总线接口

本帖最后由 fpgaw 于 2010-11-18 16:07 编辑

module bus_fsm(clk,ale,rd,wr,cs,data);
input clk,ale,rd,wr,cs;//cs由P2口译码得到
inout data; //双向地址/数据总线
reg address_reg,//地址寄存器
    data_reg1,//数据寄存器1,2
    data_reg2,
    data_temp;//输入/输出数据暂存
reg result;//计算结果寄存器

reg wr1,rd1;//WR RD信号延迟一个周期,供检测用

wire data_hold;//输入数据线

reg 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 ; //读低8位,
   state <=waiting_read; //等待读高8位
   end
   else if(address_reg==8'hf3)
   begin
   data_temp <=result ;
   state <=waiting_write;//数据读完,转等待写数据
   end
   else
   state <=waiting_read; //地址错误,继续等待
end

default:
state    <=waiting_write;

endcase
end

endmodule
页: [1]
查看完整版本: 状态机实现的与8051总线接口