本帖最后由 1273687647 于 2018-1-9 09:00 编辑
先说一下老弟遇到的情况吧,用ACTEL的A3P250-1FG144芯片,在Libero11.1编译环境中编译的,其实是很简单的一个读取外置EEROM的SPI程序,每次上电时外部会恒定的给出mode=0(读模式)信号,芯片工作使能信号恒有效(EN_SPI=1),然后利用15.36MHZ的时钟,产生3.84MHZ的SCLK时钟,送给外部EEROM,片选信号SPI_CS每次低电平信号选片,并串转换的模块p2s、s2p没有写在帖子里(主要是和我遇到的问题没关系,就没写进来),即SPI_SI,SPI_SO不用考虑,遇到的问题和它们无关。
对于写的程序,在线的语法,仿真都没问题,可是什么我下载到Acte的A3P250-IFG144芯片上时,程序经常会莫名奇妙的死循环在状态机“DELAY_2>DELAY_3>DELAY_3>DELAY_3”,中间直接跳过CYC_3,而且一直不停的在“DELAY_2>DELAY_3>DELAY_3>DELAY_3”循环。
FPGA的资源我只用了13%,在线仿真的逻辑和时序都是没问题的,到时为什么会一直在状态机“DELAY_2>DELAY_3>DELAY_3>DELAY_3”死循环呢??想尽了办法,困扰了几天,实在不知道小弟的程序哪里有问题,请各位大神帮我看看,指点一下,小弟万分感谢!!程序如下:
SPI_ctrl(clk, //15.36MHZ
rst,
mode,
EN_SPI,
radd_ROM,
SPI_Dout,
SPI_CS,
SPI_SCLK,
op_code,
D_fromROM,
D_fromROM_ready
);
input clk,rst;
input mode;
input EN_SPI;
input[15:0] radd_ROM;
input[7:0] SPI_Dout;
output SPI_SCLK;
output SPI_CS;
output[23:0] op_code;
output[7:0] D_fromROM;
output D_fromROM_ready;
parameter READ_CNT=8’d32;
parameter SPI_READ=8’b0000_0011;
parameter IDLE=4’b0000,
Initial_1=4’b0001,
CYC_1=4’b0010,
DELAY_1=4’b0011,
CYC_2=4’b0100,
DELAY_2=4’b0101,
CYC_3=4’b0110,
DELAY_3=4’b0111,
JUDGE_1=4’b1000,
SPI_rdBack=4’b1001;
reg[3:0] state;
reg[7:0] SCLK_cnt;
Always@( posedge rst or posedge clk) begin
if (rst) begin
SPI_SCLK<=1’b0;
SPI_CS<=1’b1;
op_code<=24’b0;
D_fromROM<=8’b0;
D_fromROM_ready<=1’b0;
SCLK_cnt<=8’d0;
state<=IDLE;
end
else if ( EN_SPI==1‘b1’) begin
case(state)
IDLE: begin
if(mode==1’b0) begin
state<=Initial_1;
end
else begin
state<=IDLE;
end
end
Initial_1:begin
op_code<={SPI_READ,radd_ROM};
SCLK_cnt<=READ_CNT;
state<=CYC_1;
end
CYC_1:begin
SPI_CS<=1’b0;
state<=DELAY_1;
end
DELAY_1:begin
SPI_CS<=1’b0;
state<=CYC_2;
end
CYC_2:begin
SPI_SCLK<=1’b1;
state<=DELAY_2;
end
DELAY_2:begin
SPI_SCLK<=1’b1;
SCLK_cnt<=SCLK_cnt-8’d1;
state<=CYC_3;
end
CYC_3:begin
SPI_SCLK<=1’b0;
state<=DELAY_3;
end
DELAY_3:begin
SPI_SCLK<=1’b0;
if(SCLK_cnt==8’d0) begin
D_fromROM<=SPI_Dout;
state<=JUDGE_1;
end
else begin
state<=CYC_2;
end
end
JUDGE_1:begin
SPI_CS<=1’b1;
if(op_code[23:16]==SPI_READ) begin
D_fromROM_ready<=1’b1;
state<=SPI_rdBack;
end
else begin
state<=IDLE;
end
end
SPI_rdBack:begin
D_fromROM_ready<=1’b0;
state<=IDLE;
end
default:begin
state<=IDLE;
end
endcase
end
else begin
SPI_SCLK<=1’b0;
SPI_CS<=1’b1;
op_code<=24’b0;
D_fromROM<=8’b0;
D_fromROM_ready<=1’b0;
SCLK_cnt<=8’d0;
state<=IDLE;
end
end
|