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

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 1402|回复: 7

[原创] vhdl状态机如何实现,在两个状态 执行同一个动作?

[复制链接]
发表于 2022-5-24 05:05:38 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 american007 于 2022-5-26 10:46 编辑

  请教大家,vhdl状态机如何实现,在两个状态 执行同一个动作,类似下面

process(resetn, clk,spot_poll_up)-----third  segment
    begin   
        if(resetn = '0')then
            cnt  <= (others => '0');        
        elsif(rising_edge(clk))then
            case pr_state is
              when  idle_st =>   
                             ................                 
              when  function1_cmd1_st =>  
                             ................            

              when  function1_cmd2_st =>
                             ................  
               
              when  function1_cmd3_st =>
                  cnt  <= cnt + 1;

---------------------------------------------------
              when  function2_cmd1_st =>  
                             ................           

              when  function2_cmd2_st =>
                             ................  
               
              when  function2_cmd3_st =>
                  cnt  <= cnt + 1;
---------------------------------------------------
              when others =>         
                    
            end case ;
        end if ;
    end process;

想实现类似下面的效果   when  function1_cmd2_st and function2_cmd2_st=>
  请教大家,vhdl状态机如何实现,在两个状态 执行同一个动作,类似下面

process(resetn, clk,spot_poll_up)-----third  segment
    begin   
        if(resetn = '0')then
            cnt  <= (others => '0');        
        elsif(rising_edge(clk))then
            case pr_state is
              when  idle_st =>   
                             ................                 
              when  function1_cmd1_st =>  
                             ................            

              when  function1_cmd2_st =>
                             
                          cnt  <= cnt + 1;  
              when  function1_cmd3_st =>
                          ................  

---------------------------------------------------
              when  function2_cmd1_st =>  
                             ................           

              when  function2_cmd2_st =>
                         cnt  <= cnt + 1;

               
              when  function2_cmd3_st =>
                             ................  
---------------------------------------------------
              when others =>         
                    
            end case ;
        end if ;
    end process;


想实现类似下面的效果   when  function1_cmd2_st    or    function2_cmd2_st=>
                                                   cnt  <= cnt +1;
即:  在function1_cmd2_st  或  function2_cmd2_st  两个状态,都分别会去执行cnt +1 这个操作,从形式上,把  cnt  <= cnt +1; 写在一个位置,而不是两个位置




发表于 2022-5-24 16:44:44 | 显示全部楼层


想要实现在function1_cmd2_st和function2_cmd2_st都去执行cnt +1 这个操作

这本身没有问题,无论是语法还是逻辑上都是允许的。

从你贴出的代码片段来看,确实有语法问题,case语句的分支不能重复,你的"when  function1_cmd2_st =>"和"when  function2_cmd2_st =>"分别都写了两次,这个在语法上是不允许的。
 楼主| 发表于 2022-5-26 10:27:00 | 显示全部楼层


innovation 发表于 2022-5-24 16:44
这本身没有问题,无论是语法还是逻辑上都是允许的。

从你贴出的代码片段来看,确实有语法问题,case语句的 ...


sorry,原来的代码我写错了,我已经在一楼改过来了,一共有六个状态,这六个状态都不重复,原来写错了


发表于 2022-5-26 16:39:56 | 显示全部楼层
when  ( function1_cmd2_st    or    function2_cmd2_st ) =>
                                                   cnt  <= cnt +1;

把判断条件括起来,应该是可以的。
 楼主| 发表于 2022-5-29 15:48:58 | 显示全部楼层
本帖最后由 american007 于 2022-5-29 15:51 编辑

# -- Loading package std_logic_arith
# -- Loading package STD_LOGIC_UNSIGNED
# -- Compiling entity ifbox_core
# -- Compiling architecture Behavioral of ifbox_core
# ** Error: ./example.vhd(20): No feasible entries for infix operator "or".
# ** Error: ./example.vhd(20): Type error resolving infix expression "or" as type states.
# ** Warning: ./example.vhd(20): (vcom-1937) Choice in CASE statement alternative must be locally static.
#
# ** Error: ./example.vhd(48): VHDL Compiler exiting
# End time: 15:47:20 on May 29,2022, Elapsed time: 0:00:00
# Errors: 3, Warnings: 1
# ** Error: D:/modeltech64_10.4/win64/vcom failed.

仿真出错了,不行,应该写成啥样呢 ?
发表于 2022-5-29 17:11:35 | 显示全部楼层


american007 发表于 2022-5-29 15:48
# -- Loading package std_logic_arith
# -- Loading package STD_LOGIC_UNSIGNED
# -- Compiling entity i ...



# ** Error: ./example.vhd(20): No feasible entries for infix operator "or".
# ** Error: ./example.vhd(20): Type error resolving infix expression "or" as type states.
# ** Warning: ./example.vhd(20): (vcom-1937) Choice in CASE statement alternative must be locally static.

那看来是不行了!综合工具对RTL代码中表达式的处理方式分为两种:
1)综合器直接计算表达式的“结果”,并由综合器本身使用“结果”;
2)综合器利用电路实现表达式

看来VHDL语言限制case语句中,when "表达式" =>....  表达式须满足综合器能直接计算出结果,即:Choice in CASE statement alternative must be locally static.。我之前测试时是这样的:

image.png
测试发现when后面的表达式不加括号,要报错,加括号后正常。所以比较草率的认为问题出在表达式的写法上。我测试通过的代码,when后面的表达式满足综合器在综合阶段直接计算出结果的条件:Choice in CASE statement alternative must be locally static.


而你的设计中,function1_cmd2_st,function2_cmd2_st是通过type定义的,可以理解为一个代码编写时的助记符,实际生成电路时,根据选择的状态机编码风格,function1_cmd2_st,function2_cmd2_st可能会由不同的方式表示,综合器还真就是在编译阶段无法计算出(function1_cmd2_st or function2_cmd2_st)这个表达式的结果是'0'还是'1',故而只能报错了。




发表于 2022-5-29 17:45:44 | 显示全部楼层


american007 发表于 2022-5-29 15:48
# -- Loading package std_logic_arith
# -- Loading package STD_LOGIC_UNSIGNED
# -- Compiling entity i ...


两个状态控制cnt + 1,看来case语句是不行了。如果坚持要实现cnt + 1只写一次,那可以考虑改为if...else...的写法:
process(resetn, clk)
  begin
    if resetn = '0' then
       cnt  <= (others => '0');
    elsif rising_edge(clk) then
       if (pr_state = function1_cmd2_st) or (pr_state = function2_cmd2_st) then
          cnt <= cnt + 1;
       end if;
    end if;
  end process;
 楼主| 发表于 2022-5-29 21:48:02 | 显示全部楼层


innovation 发表于 2022-5-29 17:45
两个状态控制cnt + 1,看来case语句是不行了。如果坚持要实现cnt + 1只写一次,那可以考虑改为if...else. ...


非常感谢
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

×

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

GMT+8, 2024-5-4 12:01 , Processed in 0.026939 second(s), 8 queries , Gzip On, Redis On.

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