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

 找回密码
 注册

手机号码,快捷登录

手机号码,快捷登录

搜帖子
查看: 4857|回复: 18

[求助] 请问在VHDL构造体内部可以将signal赋值给整数吗?

[复制链接]
发表于 2021-10-19 16:36:29 | 显示全部楼层 |阅读模式

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

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

×


需求是根据输入信号ctl控制一个常量BAUD_CLK_TICKS 的选择。(原来BAUD_CLK_TICKS是输入端口定义了generic,现在需要这个参数可变,因此使用了case语句控制)

因为后续模块使用到BAUD_CLK_TICKS 这个信号,因此在case语句里定义了signal格式,但是在接下来的process中不知道该怎么处理了

有没有大神指点下,万分感谢!

    process(ctl)
    begin
        case ctl is
            when "0000" => BAUD_CLK_TICKS <= conv_std_logic_vector(10416, 14);
            when "0001" => BAUD_CLK_TICKS <= conv_std_logic_vector(6944, 14);
            when "0010" => BAUD_CLK_TICKS <= conv_std_logic_vector(5208, 14);
            when "0011" => BAUD_CLK_TICKS <= conv_std_logic_vector(2604, 14);
            when "0100" => BAUD_CLK_TICKS <= conv_std_logic_vector(1736, 14);
            when "0101" => BAUD_CLK_TICKS <= conv_std_logic_vector(868, 14);
            when "0110" => BAUD_CLK_TICKS <= conv_std_logic_vector(434, 14);
            when "0111" => BAUD_CLK_TICKS <= conv_std_logic_vector(217, 14);
            when "1000" => BAUD_CLK_TICKS <= conv_std_logic_vector(108, 14);
            when OTHERS  => BAUD_CLK_TICKS <= conv_std_logic_vector(868, 14); --默认波特速率为115.2K
        end case;
    end process;



    baud_rate_generator: process(clk)
        variable baud_count: integer range 0 to (BAUD_CLK_TICKS) - 1) := (BAUD_CLK_TICKS - 1);
    begin
        if rising_edge(clk) then
            if (reset = '1') then
                baud_rate_clk <= '0';
                baud_count := (BAUD_CLK_TICKS - 1);
            else
                if (baud_count = 0) then
                    baud_rate_clk <= '1';
                    baud_count := (BAUD_CLK_TICKS - 1);
                else
                    baud_rate_clk <= '0';
                    baud_count := baud_count - 1;
                end if;
            end if;
        end if;
    end process baud_rate_generator;


发表于 2021-10-19 19:31:08 | 显示全部楼层
小伙,不错啊,有前途,这是打算用BASYS3的拨码开关来配置UART的波特率?
回复 支持 反对

使用道具 举报

发表于 2021-10-19 20:07:55 | 显示全部楼层
回答你的问题吧。

请问在VHDL构造体内部可以将signal赋值给整数吗?

1)这不是signal赋值给整数的问题,你遇到的是将std_logic_vector数据类型赋值给integer数据类型的问题。
2)不能直接赋值。
2)VHDL赋值操作要求运算符两边的操作数的类型相同。
3)你一定要这么干的话,需要使用CONV_INTEGER这个函数将std_logic_vector类型转换为integer类型,注意:要使用CONV_INTEGER函数,你需要在文件头部声明IEEE.Std_Logic_Unsigned.all程序包。

一点儿建议:

1)纯粹的语法问题,桌上放本语法书,看明白一段或看不明白一段了,马上敲一段代码,运行工具的语法检查,根据错误提示,再查阅语法书,效率超乎你想象。
2)希望你仅将你这个设计用于熟悉语法。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-10-19 20:50:12 | 显示全部楼层


   
innovation 发表于 2021-10-19 19:31
小伙,不错啊,有前途,这是打算用BASYS3的拨码开关来配置UART的波特率?


是的,但是基础语法这块有点摸不着头脑,所以来求助了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-10-19 21:08:45 | 显示全部楼层


   
innovation 发表于 2021-10-19 20:07
回答你的问题吧。

请问在VHDL构造体内部可以将signal赋值给整数吗?



这样修改语法通过了,感谢指点!

baud_rate_clk_generator: process(clk)
        variable BAUD_CLK_TICKS_int : integer range 0 to 2**14-1 := conv_integer(unsigned(BAUD_CLK_TICKS));
        variable baud_count: integer range 0 to (BAUD_CLK_TICKS_int - 1) := (BAUD_CLK_TICKS_int - 1);
    begin
        if rising_edge(clk) then
            if (reset = '1') then
                baud_rate_clk <= '0';
                baud_count := (BAUD_CLK_TICKS_int - 1);
            else
                if (baud_count = 0) then
                    baud_rate_clk <= '1';
                    baud_count := (BAUD_CLK_TICKS_int - 1);
                else
                    baud_rate_clk <= '0';
                    baud_count := baud_count - 1;
                end if;
            end if;
        end if;
    end process baud_rate_clk_generator;

回复 支持 反对

使用道具 举报

发表于 2021-10-20 09:18:44 | 显示全部楼层
这是在维护  传家宝 模块吗?    VHDL 的繁琐, 简直令人发指。
回复 支持 反对

使用道具 举报

发表于 2021-10-20 12:52:41 | 显示全部楼层
本帖最后由 innovation 于 2021-10-20 15:23 编辑


   
come_on_sn 发表于 2021-10-19 21:08
这样修改语法通过了,感谢指点!

baud_rate_clk_generator: process(clk)


这。。。不对呀。看来我忘了提醒你“VHDL(或verilog)代码会分为可综合和不可综合两种”。你这个综合会报error和warining。
不可综合的代码指:语法正确,能RTL行为仿真(这个危害最大,你仿真认为你的设计是正确的,但上板不对),但综合器在综合时忽略并且生成对应电路



   
variable BAUD_CLK_TICKS_int : integer range 0 to 2**14-1 := conv_integer(unsigned(BAUD_CLK_TICKS));
        variable baud_count: integer range 0 to (BAUD_CLK_TICKS_int - 1) := (BAUD_CLK_TICKS_int - 1);


这两句中对variable赋初值会被综合器忽略(这就是不可综合的代码),所以你的BAUD_CLK_TICKS这个信号根本没有传递进你这段计数器代码!这个问题综合器会warning


   
integer range 0 to (BAUD_CLK_TICKS_int - 1)


对整数类型的signal(或variable)指定范围时,range 0 to 。。。,to后面必须是一个常数,这个综合器在综合时报error








回复 支持 反对

使用道具 举报

发表于 2021-10-20 13:00:34 | 显示全部楼层


   
come_on_sn 发表于 2021-10-19 21:08
这样修改语法通过了,感谢指点!

baud_rate_clk_generator: process(clk)


我本人不会像你这样写。但你明确问道“请问在VHDL构造体内部可以将signal赋值给整数吗?”,所以我仅就语法问题给出答案,并提醒你这仅是语法角度的答案。

答案的本意是希望你将你最开始贴出的代码中:


   
baud_count := (BAUD_CLK_TICKS - 1);

这一句修改为:baud_count := CONV_INTEGER(BAUD_CLK_TICKS - 1);
回复 支持 反对

使用道具 举报

发表于 2021-10-20 13:32:39 | 显示全部楼层
本帖最后由 innovation 于 2021-10-20 13:55 编辑


   
come_on_sn 发表于 2021-10-19 21:08
这样修改语法通过了,感谢指点!

baud_rate_clk_generator: process(clk)


帮你把代码微调一下,你和你最开始贴出的代码比对:


   

        

                
  1. process(Ctl, BAUD_CLK_TICKS)
  2. begin
  3.    case Ctl is
  4.       when B"0000" => BAUD_CLK_TICKS <= CONV_STD_LOGIC_VECTOR(10416 - 1, 14); -- 减1在这里完成不需要消耗任何电路资源
  5.       when B"0001" => BAUD_CLK_TICKS <= CONV_STD_LOGIC_VECTOR(  6944 - 1, 14);
  6.       when B"0010" => BAUD_CLK_TICKS <= CONV_STD_LOGIC_VECTOR(  5208 - 1, 14);
  7.       when B"0011" => BAUD_CLK_TICKS <= CONV_STD_LOGIC_VECTOR(  2604 - 1, 14);
  8.       when B"0100" => BAUD_CLK_TICKS <= CONV_STD_LOGIC_VECTOR(  1736 - 1, 14);
  9.       when B"0101" => BAUD_CLK_TICKS <= CONV_STD_LOGIC_VECTOR(    868 - 1, 14);
  10.       when B"0110" => BAUD_CLK_TICKS <= CONV_STD_LOGIC_VECTOR(    434 - 1, 14);
  11.       when B"0111" => BAUD_CLK_TICKS <= CONV_STD_LOGIC_VECTOR(    217 - 1, 14);
  12.       when B"1000" => BAUD_CLK_TICKS <= CONV_STD_LOGIC_VECTOR(    108 - 1, 14);
  13.       when Others   => BAUD_CLK_TICKS <= CONV_STD_LOGIC_VECTOR(    868 - 1, 14);
  14.    end case;
  15. end process;

  16.         

   

    复制代码


   

        

                
  1. process(Clk)
  2. variable baud_count       : std_logic_vector(13 downto 0) := CONV_STD_LOGIC_VECTOR(868 - 1, 14);--定义为与BAUD_CLK_TICKS相同的数据类型
  3. begin
  4.    if rising_edge(Clk) then
  5.       if Reset = '1' then
  6.          baud_rate_clk     <= '0';
  7.          baud_count        := BAUD_CLK_TICKS;
  8.       else
  9.          if baud_count = 0 then
  10.             baud_rate_clk  <= '1';
  11.             baud_count     := BAUD_CLK_TICKS;
  12.          else
  13.             baud_rate_clk  <= '0';
  14.             baud_count     := baud_count - 1;
  15.          end if;
  16.       end if;
  17.    end if;
            

   

    复制代码
Tips:这个代码软件思维偏重,硬件电路思维偏弱,资源消耗和运行速度不好,基于Xilinx FPGA的话,优化空间很大。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-10-20 16:59:31 | 显示全部楼层


   
y23angchen 发表于 2021-10-20 09:18
这是在维护  传家宝 模块吗?    VHDL 的繁琐, 简直令人发指。


确实比较繁琐,尤其是模块间调用时
回复 支持 反对

使用道具 举报

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

本版积分规则

关闭

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


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

GMT+8, 2025-8-22 04:24 , Processed in 0.017036 second(s), 3 queries , Gzip On, Redis On.

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