quartus 编译仿真
quartus吧
全部回复
仅看楼主
level 1
module spi_slave_test(nreset,SDI,CS,DO,SDO,sck,WE,DI,AD);
input nreset;
input SDI;
input CS;
input [7:0] DO;
input sck;
output SDO;
output WE;
output [7:0] DI;
output [15:0] AD;
wire SDO;
reg WE;
reg [15:0] AD;
reg [7:0] DI;
reg [15:0] ADbuf;
reg [7:0] DIbuf;
reg [7:0] DObuf;
reg SDIbuf;
reg SDO_link;
reg [6:0] state; //7个主状态
reg [8:0] sh8in_state; //任务,8位读写指令的子状态
reg [9:0] sh8in_data; //任务,写操作时8位数据的子状态
reg [9:0] sh8out_data; //任务,读操作时8位数据的子状态
reg [16:0] sh16in_WR; //任务,写操作时16位地址的子状态
reg [17:0] sh16in_RD; //任务,读操作时16位地址的子状态
assign SDO = SDO_link?DObuf[7]:1'bz;
//----state的7个状态
parameter
ready = 7'b0000001,
comp = 7'b0000010,
WR_AD = 7'b0000100,
WR_data = 7'b0001000,
RD_AD = 7'b0010000,
RD_data = 7'b0100000,
S_END = 7'b1000000;
//----主程序
always @ (posedge sck)
if(!nreset) //复位时的初始化
begin
WE <= 1'b1;
SDIbuf <= 0;
ADbuf <= 0;
DIbuf <= 0;
DObuf <= 0;
SDO_link <= 0;
end
else
begin
if(!CS)
case (state) //----主状态,7个状态
ready:
begin
shift8in; //--任务,输入8位读写指令
state <= comp;
end
comp: //判定是执行写操作还是读操作
if(DIbuf == 8'b00000010)
begin
state <= WR_AD;
DIbuf <= 8'b00000000;
end
else if(DIbuf == 8'b00000011)
begin
state <= RD_AD;
DIbuf <= 8'b00000000;
end
WR_AD:
begin
shift16in_WR; // --任务,向外设写操作时,从SDI读入16位地址,为串并转换
state <= WR_data;
end
WR_data:
begin
shift8in_data; //--任务,向外设写操作时,从SDI读入8位data,为串并转换
if(!WE)
begin
AD <= ADbuf;
DI <= DIbuf;
ADbuf <= ADbuf + 16'b1;
DIbuf <= 8'b00000000;
end
else if(CS)
state <= S_END;
else
state <= WR_data;
end
RD_AD:
begin
shift16in_RD; //--任务,从外设读操作时,从SDI读入16位起始地址,为串并转换
state <= RD_data;
end
RD_data:
begin
shift8out_data; //--任务,从外设读操作时,从DO读入一个8位数据,为并串转换
2013年03月25日 05点03分 1
level 1
if(CS)
state <= S_END;
else
begin
AD <= ADbuf;
ADbuf <= ADbuf + 16'b1;
DObuf <= 8'b00000000;
state <= RD_data;
end
end
S_END:
begin
WE <= 1'b1;
SDIbuf <= 0;
ADbuf <= 0;
DIbuf <= 0;
DObuf <= 0;
SDO_link <= 0;
end
endcase
else
begin
WE <= 1'b1;
SDIbuf <= 0;
ADbuf <= 0;
DIbuf <= 0;
DObuf <= 0;
SDO_link <= 0;
end
end
//----任务,输入8位读或写指令
task shift8in;
begin
case(sh8in_state)
08:
if(sck)
begin
SDIbuf <= SDI;
sh8in_state <= 00;
end
else
sh8in_state <= 08;
00:
if(sck)
begin
DIbuf[7] <= SDIbuf;
SDIbuf <= SDI;
sh8in_state <= 01;
end
else
sh8in_state <= 00;
01:
if(sck)
begin
DIbuf[6] <= SDIbuf;
SDIbuf <= SDI;
sh8in_state <= 02;
end
else
sh8in_state <= 01;
02:
if(sck)
begin
DIbuf[5] <= SDIbuf;
SDIbuf <= SDI;
sh8in_state <= 03;
end
else
sh8in_state <= 02;
03:
if(sck)
begin
DIbuf[4] <= SDIbuf;
SDIbuf <= SDI;
sh8in_state <= 04;
end
else
sh8in_state <= 03;
04:
if(sck)
begin
DIbuf[3] <= SDIbuf;
SDIbuf <= SDI;
sh8in_state <= 05;
end
else
sh8in_state <= 04;
05:
if(sck)
begin
DIbuf[2] <= SDIbuf;
SDIbuf <= SDI;
sh8in_state <= 06;
end
else
sh8in_state <= 05;
06:
if(sck)
begin
DIbuf[1] <= SDIbuf;
SDIbuf <= SDI;
sh8in_state <= 07;
end
else
sh8in_state <= 06;
07:
if(sck)
begin
DIbuf[0] <= SDIbuf;
end
else
sh8in_state <= 07;
default:
begin
sh8in_state <= 08;
end
endcase
end
endtask
//----向外设写操作时,从SDI读入16位地址,为串并转换
task shift16in_WR;
begin
case (sh16in_WR)
16:
if(sck)
begin
SDIbuf <= SDI;
sh16in_WR <= 00;
end
else
sh16in_WR <= 16;
2013年03月25日 05点03分 2
level 1
00:
if(sck)
begin
ADbuf[15] <= SDIbuf;
SDIbuf <= SDI;
sh16in_WR <= 01;
end
else
sh16in_WR <= 00;
01:
if(sck)
begin
ADbuf[14] <= SDIbuf;
SDIbuf <= SDI;
sh16in_WR <= 02;
end
else
sh16in_WR <= 01;
02:
if(sck)
begin
ADbuf[13] <= SDIbuf;
SDIbuf <= SDI;
sh16in_WR <= 03;
end
else
sh16in_WR <= 02;
03:
if(sck)
begin
ADbuf[12] <= SDIbuf;
SDIbuf <= SDI;
sh16in_WR <= 04;
end
else
sh16in_WR <= 03;
04:
if(sck)
begin
ADbuf[11] <= SDIbuf;
SDIbuf <= SDI;
sh16in_WR <= 05;
end
else
sh16in_WR <= 04;
05:
if(sck)
begin
ADbuf[10] <= SDIbuf;
SDIbuf <= SDI;
sh16in_WR <= 06;
end
else
sh16in_WR <= 05;
06:
if(sck)
begin
ADbuf[9] <= SDIbuf;
SDIbuf <= SDI;
sh16in_WR <= 07;
end
else
sh16in_WR <= 06;
07:
if(sck)
begin
ADbuf[8] <= SDIbuf;
SDIbuf <= SDI;
sh16in_WR <= 08;
end
else
sh16in_WR <= 07;
08:
if(sck)
begin
ADbuf[7] <= SDIbuf;
SDIbuf <= SDI;
sh16in_WR <= 09;
end
else
sh16in_WR <= 08;
09:
if(sck)
begin
ADbuf[6] <= SDIbuf;
SDIbuf <= SDI;
sh16in_WR <= 10;
end
else
sh16in_WR <= 09;
10:
if(sck)
begin
ADbuf[5] <= SDIbuf;
SDIbuf <= SDI;
sh16in_WR <= 11;
end
else
sh16in_WR <= 10;
11:
if(sck)
begin
ADbuf[4] <= SDIbuf;
SDIbuf <= SDI;
sh16in_WR <= 12;
end
else
sh16in_WR <= 11;
12:
if(sck)
begin
ADbuf[3] <= SDIbuf;
SDIbuf <= SDI;
sh16in_WR <= 13;
end
else
sh16in_WR <= 12;
13:
if(sck)
begin
ADbuf[2] <= SDIbuf;
SDIbuf <= SDI;
sh16in_WR <= 14;
end
else
sh16in_WR <= 13;
14:
if(sck)
begin
ADbuf[1] <= SDIbuf;
SDIbuf <= SDI;
sh16in_WR <= 15;
end
else
sh16in_WR <= 14;
15:
if(sck)
begin
ADbuf[0] <= SDIbuf;
end
else
sh16in_WR <= 15;
default:
begin
sh16in_WR <= 16;
end
endcase
end
endtask
2013年03月25日 05点03分 3
1