高级会员
- 积分
- 635
- 金钱
- 635
- 注册时间
- 2017-3-6
- 在线时间
- 64 小时
|
3金钱
该问题基于DS18B20应用的例程,如下图所示,复位之后,最开始的状态为初始化状态(cur_state = init),然后执行always @(*) 和下一个always块,因为init_done = 0,所以当前状态一直为init态,并在后一个always块中执行相应的代码,当里面的代码执行完毕后,将init_done拉高,这时候第一个always块执行,跳转到下一个状态rom_skip,这个转态会在下一个时钟周期赋给当前状态cur_state,同时在后一个always块中执行rom_skip的代码,此时的st_done依旧是1,而FPGA的代码又是并行执行的,那我是不是可以认为在always @(*)中会执行:rom_skip: begin
if(st_done) next_state <= wr_byte....语句呢,如果这样的话,在后一个always块中,会不会接着执行下一个状态,但是当前状态,又没有执行完。
刚接触FPGA并不是很懂,权且当记录了,如果有人愿意指点一二,感激不尽,谢谢。
写的可能有点乱,勿喷。
//state jump
always @( posedge clk_1us or negedge rst_n ) begin
if( !rst_n )
cur_state <= init;
else
cur_state <= next_state;
end
//combination logic state judgment transition condition
always @( * ) begin
case( cur_state )
init: begin
if( init_done )
next_state <= rom_skip;
else
next_state <= init;
end
rom_skip: begin
if( st_done )
next_state <= wr_byte;
else
next_state <= rom_skip;
end
wr_byte: begin
if( st_done )
case( cmd_cnt )
4'd1: next_state <= temp_convert;
4'd2: next_state <= delay;
4'd3: next_state <= rd_temp;
4'd4: next_state <= rd_byte;
default:
next_state <= temp_convert;
endcase
else
next_state <= wr_byte;
end
temp_convert: begin
if( st_done )
next_state <= wr_byte;
else
next_state <= temp_convert;
end
delay: begin
if( st_done )
next_state <= init;
else
next_state <= delay;
end
rd_temp: begin
if( st_done )
next_state <= wr_byte;
else
next_state <= rd_temp;
end
rd_byte: begin
if( st_done )
next_state <= init;
else
next_state <= rd_byte;
end
default:
next_state <= init;
endcase
end
//整个操作步骤为初始化、发送跳过ROM操作指令、发送温度转换指令、再初始化、再发送ROM、发送读取指令
always @( posedge clk_1us or negedge rst_n ) begin
if( !rst_n ) begin
flow_cnt <= 4'b0;
init_done <= 1'b0;
cnt_1us_en <= 1'b1;
dq_out <= 1'bZ;
st_done <= 1'b0;
rd_data <=16'b0;
rd_cnt <= 5'd0;
wr_cnt <= 4'b0;
cmd_cnt <= 4'b0;
end
else begin
st_done <= 1'b0;
case( next_state )
init: begin
init_done <= 1'b0;
case( flow_cnt )
4'd0:
flow_cnt <= flow_cnt + 1'b1;
4'd1: begin
cnt_1us_en <= 1'b1;
if( cnt_1us < 20'd500 )
dq_out <= 1'b0;
else begin
cnt_1us_en <= 1'b0;
dq_out <= 1'bZ;
flow_cnt <= flow_cnt + 1'b1;
end
end
4'd2: begin
cnt_1us_en <= 1'b1;
if( cnt_1us < 20'd30 )
dq_out <=1'bZ;
else
flow_cnt <= flow_cnt + 1'b1;
end
4'd3: begin
if( !dq )
flow_cnt <= flow_cnt + 1'b1;
else
flow_cnt <= flow_cnt;
end
4'd4:begin
if( cnt_1us == 20'd500 ) begin
cnt_1us_en <= 1'b0;
init_done <= 1'b1;
flow_cnt <= 4'd0;
end
else
flow_cnt <= flow_cnt;
end
default:
flow_cnt <= 4'd0;
endcase
end
rom_skip: begin
wr_data <= ROM_SKIP_CMD;
flow_cnt<= 4'd0;
st_done <= 1'b1;
end
wr_byte: begin
if( wr_cnt <= 4'd7 ) begin
case( flow_cnt )
4'd0: begin
dq_out <= 1'b0;
cnt_1us_en <= 1'b1;
flow_cnt <= flow_cnt + 1'b1;
end
4'd1: begin
flow_cnt <= flow_cnt + 1'b1;
end
4'd2: begin
if( cnt_1us < 20'd60 )
dq_out <= wr_data[wr_cnt];
else if( cnt_1us < 20'd63 )
dq_out <= 1'bZ;//release bus
else
flow_cnt <= flow_cnt + 1'b1;
end
4'd3: begin
flow_cnt <= 4'b0;
cnt_1us_en <= 1'b0;
wr_cnt <= wr_cnt + 1'b1;
end
default:
flow_cnt <= 4'b0;
endcase
end
else begin
st_done <= 1'b1;
wr_cnt <= 4'b0;
cmd_cnt <= ( cmd_cnt == 4'd4 )? 4'd1 : ( cmd_cnt + 1'b1 );
end
end
temp_convert: begin
wr_data <= CONVERT_CMD;
st_done <= 1'b1;
end
delay: begin
cnt_1us_en <= 1'b1;
if( cnt_1us == 20'd500000 ) begin
st_done <= 1'b1;
cnt_1us_en <= 1'b0;
end
end
rd_temp: begin
wr_data <= READ_TEMP;
bit_width <= 5'd16;
st_done <= 1'b1;
end
rd_byte: begin
if( rd_cnt < bit_width ) begin
case( flow_cnt )
4'd0: begin
cnt_1us_en <= 1'b1;
dq_out <= 1'b0;
flow_cnt <= flow_cnt + 1'b1;
end
4'd1: begin
dq_out <= 1'bZ;
if( cnt_1us <= 20'd14 ) begin
rd_data <= { dq, rd_data[15:1] };
flow_cnt<= flow_cnt + 1'b1;
end
end
4'd2: begin
if( cnt_1us <= 20'd64 )
dq_out <= 1'bZ;
else begin
flow_cnt <= 4'd0;
rd_cnt <= rd_cnt + 1'b1;
cnt_1us_en <= 1'b0;
end
end
default:
flow_cnt <= 4'd0;
endcase
end
else begin
st_done <= 1'b1;
org_data<=rd_data;
rd_cnt <=5'b0;
end
end
default:;
endcase
end
end
|
最佳答案
查看完整内容[请看2#楼]
已解决,是自己程序看漏了一行,每次进入具体执行状态执行的always块时,第一句就进行了st_done清零工作,自己的失误
|