首页 文章

VHDL - 如何有效地将整数转换为ascii或8位slv

提问于
浏览
-1

我试图通过串行输出不同的(非常数)值 . 串行通信工作正常,但似乎没有一种优雅的,可综合的方法将任何大小和值的任何整数/自然/ std_logic_vector / unsigned / signed类型转换为基于ASCII表的8位std_logic_vectors数组 . 这是非常奇怪的,因为我想要做的并不罕见 .

我能做到这一点的一种方法是使用大型查找表或if-elsif-else语句的长嵌套链,但这看起来非常低效且不优雅 .

这不是sysnthesize:

eight_bit_result <= std_logic_vector(to_unsigned(character'pos(some_integer), 8));

ISE 14.7因某些头文件导致的模糊错误而中断 . 即使它确实有效,它也不适用于0-255之外的值 . 这样做的正确方法是什么?

编辑:

我写了一个快速而脏的函数来覆盖整数值0-9999 . 它不需要时钟进程,也不需要额外的实体等 . 到目前为止提出的答案似乎过于复杂 .

function get_ascii_array_from_int(i : integer range 0 to 9999) return char_array is
        variable result : char_array(0 to 3) := (x"30", x"30", x"30", x"30"); -- 0000
    begin
        if i >= 0 then
            if i < 1000 then
                result(0) := x"30"; -- 0
                result(1 to 3) := get_ascii_array_from_int_hundreds(i);
            elsif i < 2000 then
                result(0) := x"31"; -- 1
                result(1 to 3) := get_ascii_array_from_int_hundreds(i-1000);
            elsif i < 3000 then
                result(0) := x"32"; -- 2
                result(1 to 3) := get_ascii_array_from_int_hundreds(i-2000);
            elsif i < 4000 then
                result(0) := x"33"; -- 3
                result(1 to 3) := get_ascii_array_from_int_hundreds(i-3000);
            elsif i < 5000 then
                result(0) := x"34"; -- 4
                result(1 to 3) := get_ascii_array_from_int_hundreds(i-4000);
            elsif i < 6000 then
                result(0) := x"35"; -- 5
                result(1 to 3) := get_ascii_array_from_int_hundreds(i-5000);
            elsif i < 7000 then
                result(0) := x"36"; -- 6
                result(1 to 3) := get_ascii_array_from_int_hundreds(i-6000);
            elsif i < 8000 then
                result(0) := x"37"; -- 7
                result(1 to 3) := get_ascii_array_from_int_hundreds(i-7000);
            elsif i < 9000 then
                result(0) := x"38"; -- 8
                result(1 to 3) := get_ascii_array_from_int_hundreds(i-8000);
            else
                result(0) := x"39"; -- 9
                result(1 to 3) := get_ascii_array_from_int_hundreds(i-9000);
            end if;
        else
            result := (x"6e", x"65", x"67", x"23"); -- "neg#" 
        end if;

        return result;

    end get_ascii_array_from_int;

您可能已经猜到还有其他三种方法:get_ascii_array_from_int_hundreds get_ascii_array_from_int_tens get_ascii_array_from_int_ones

说出你对这个函数的看法,但请记住,当我需要它时,它会产生正确的结果,而不是几个周期之后,并且简单明了 . 我可以轻松扩展它以覆盖负数和更大的数字 .

2 回答

  • 0

    这是十进制输出的绝对要求吗?如果你想要效率,十六进制输出是你要走的路 . 要克服十六进制输出,只需将整数分成4位组,然后将每个组转换为ASCII字符0-F .

    将int转换为十进制ASCII表示是一项计算繁重的操作,因为它需要很多分区 .

    但如果这是你需要的,那么更有效的方法之一就是创建一个状态机,每个时钟周期计算一位数 . 状态机需要在每个时钟周期执行以下操作:

    • 将整数X除以10并将结果存储回X.

    • 计算余数 .

    • 通过将x '30'添加到余数来生成ASCII数字 .

    状态机必须运行10个时钟周期才能将32位整数转换为ASCII十进制 .

  • 0

    您需要设计一个如本文所述的小电路,并将其用于BCD转换器的整数,请参见第2页上的值0到9999的示例,这将满足您的需要 .

    M. Benedek,"Developing Large Binary to BCD Conversion Structures",第三届IEEE计算机算术研讨会论文集,南卫理公会大学,德克萨斯州达拉斯,1975年11月19日至20日http://www.acsel-lab.com/arithmetic/arith3/papers/ARITH3_Benedek.pdf

相关问题