在线咨询 切换到宽版
eetop公众号 创芯大讲堂 创芯人才网

 找回密码
 注册

手机号码,快捷登录

手机号码,快捷登录

搜帖子
查看: 3040|回复: 8

[求助] 求助大虾,状态机为什么没有跳变

[复制链接]
发表于 2010-7-29 09:23:18 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

×
今天写了一个spi的发送程序,是在发送信息之前发送4个字节的操作码,用的是状态机,但是为什么next_state就没有跳到第一个状态cmd_send里面去?请教大家
`timescale 1 ns / 1 ns
module spi(rst ,clk ,wr ,rd ,datain ,spics ,spido);
input rst;
input clk;
input wr;
input rd;
input [7:0]datain;
output spics;
output spido;
reg spics;
reg spido;
reg [8:0]spistate;
reg [8:0]next_state;
reg receive;
reg [7:0]dsend;
reg [3:0]cnt;
reg [8:0]state_cnt;
reg [7:0] send_cmd;
reg [7:0] receive_cmd;
reg [7:0] ad1, ad2, ad3;
reg [7:0] adr1, adr2, adr3;
parameter idle = 9'b000000001;
parameter cmd_send = 9'b000000010;
parameter a1 = 9'b000000100;
parameter a2 = 9'b000001000;
parameter a3 = 9'b000010000;
parameter cmd_receive = 9'b000100000;
parameter ar1 = 9'b001000000;
parameter ar2 = 9'b010000000;
parameter ar3 = 9'b100000000;
parameter send = 9'b100000001;
[email=always@(posedge]always@(posedge[/email] clk or negedge rst)
     if(wr == 1 && rd == 0)
        spics <= 0;
     else if(wr == 0 && rd == 1)
          begin
               receive <= 1;
               spics <= 0;
          end
     else spics <= 1;
         
[email=always@(posedge]always@(posedge[/email] clk or negedge rst)
begin
     if(!rst)
          spistate <= idle;
     else
          next_state <= spistate;
end
[url=]//always@(spistate[/url] or cnt or wr or rd)
[email=always@(posedge]always@(posedge[/email] clk or negedge rst)
begin
     next_state = idle;
     case(spistate)
         idle:     begin
                        if(wr == 1 && rd == 0) next_state = cmd_send;
                   else if(wr == 0 && rd == 1) next_state = cmd_receive;
                   else next_state = idle;
                   end
         cmd_send:   next_state = send;
         a1:         next_state = send;
         a2:         next_state = send;
         a3:         next_state = send;
         cmd_receive:next_state = send;
         ar1:        next_state = send;
         ar2:        next_state = send;
         ar3:        next_state = send;
         send:       if(cnt == 4'b0111) next_state = state_cnt;
         default:    next_state = idle;
    endcase
end
[email=always@(posedge]always@(posedge[/email] clk or negedge rst)
begin
     if(!rst)
     begin
          state_cnt <= 9'b0000000001;
          cnt <= 0;
          dsend <= 0;
          spics <= 0;
          spido <= 0;
     end
     else case(next_state)
               idle:      if(wr == 1 && rd == 0)  dsend <= 8'h82;
                          else if(wr == 0 && rd == 1) dsend <= 0;
               cmd_send:  begin
                               //send_cmd <= 8'h82;
                               state_cnt <= state_cnt<<1;
                          end
               a1:        begin
                               ad1 <= 8'h2c;
                               state_cnt <= state_cnt<<1;
                          end
               a2:        begin
                               ad2 <= 8'h00;
                               state_cnt <= state_cnt + 1;
                          end
               a3:        begin
                               ad3 <= 8'h03;
                               state_cnt <= state_cnt + 1;
                          end
            cmd_receive:  begin
                               receive_cmd <= 8'h0B;
                               state_cnt <= state_cnt + 1;
                          end
               ar1:       begin
                               adr1 <= 8'h2c;
                               state_cnt <= state_cnt + 1;
                          end
               ar2:       begin
                               adr2 <= 8'h00;
                               state_cnt <= state_cnt + 1;
                          end
               ar3:       begin
                               adr3 <= 8'h03;
                               state_cnt <= state_cnt + 1;
                          end
               send:      if(cnt == 4'b0111)
                             cnt <= 0;
                          else
                              begin
                                   spido <= dsend[7];
                                   dsend <= dsend<<1;
                                   cnt <= cnt + 1;
                              end
         endcase
end                           
endmodule

                               
登录/注册后可看大图
发表于 2010-7-29 10:29:02 | 显示全部楼层
把begin
     if(!rst)
          spistate <= idle;
     else
          next_state <= spistate;
end
改为
begin
     if(!rst)
          spistate <= idle;
     else
           spistate<= next_state;
end
回复 支持 反对

使用道具 举报

发表于 2010-7-29 11:24:46 | 显示全部楼层
把begin
     if(!rst)
          spistate <= idle;
     else
          next_state <= spistate;
end
改为
begin
     if(!rst)
          spistate <= idle;
     else
           spistate<= next_state;
end
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-7-29 12:54:17 | 显示全部楼层
2# allenyey
这样啊,但是一般教材上的三段式状态机,就是把现状态赋给下一状态,这是为什么呢?
回复 支持 反对

使用道具 举报

发表于 2010-7-29 13:48:30 | 显示全部楼层
看不懂
回复 支持 反对

使用道具 举报

发表于 2010-7-29 16:53:28 | 显示全部楼层


   
2# allenyey  
这样啊,但是一般教材上的三段式状态机,就是把现状态赋给下一状态,这是为什么呢?
xychzkhf 发表于 2010-7-29 12:54



理解不够,你得和下一段程序-状态跳转那个合起来理解
回复 支持 反对

使用道具 举报

发表于 2010-7-29 22:55:53 | 显示全部楼层
你的状态机写错了哦,用边沿触发需要用<=赋值,并且case语句需要用default,否则就是latch
回复 支持 反对

使用道具 举报

发表于 2010-7-31 08:29:01 | 显示全部楼层
好,谢谢!
回复 支持 反对

使用道具 举报

发表于 2010-8-13 21:49:34 | 显示全部楼层
学习了。。。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /1 下一条


手机版| 小黑屋| 关于我们| 联系我们| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2025-9-12 14:57 , Processed in 0.023944 second(s), 5 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表