在VHDL中将8位二进制数转换为BCD

2024-03-06

该算法众所周知,您进行 8 次左移,并在每次移位后检查个位、数十位或数百位(每个 4 位)。如果它们超过 4 个,则将 3 个添加到该组中,依此类推...

这是一个基于流程的解决方案,但不起作用。它会编译,但输出不是我想要的。有什么想法可能是什么问题吗?

library ieee ;
use ieee.std_logic_1164.all ;
use ieee.std_logic_unsigned.all ;

entity hex2bcd is
    port ( hex_in  : in  std_logic_vector (7 downto 0) ;
           bcd_hun : out std_logic_vector (3 downto 0) ;
           bcd_ten : out std_logic_vector (3 downto 0) ;
           bcd_uni : out std_logic_vector (3 downto 0) ) ;
end hex2bcd ;

architecture arc_hex2bcd of hex2bcd is
begin
    process ( hex_in )
        variable hex_src : std_logic_vector (7 downto 0) ;
        variable bcd     : std_logic_vector (11 downto 0) ;
    begin
        hex_src := hex_in ;
        bcd     := (others => '0') ;

        for i in 0 to 7 loop
            bcd := bcd(11 downto 1) & hex_src(7) ; -- shift bcd + 1 new entry
            hex_src := hex_src(7 downto 1) & '0' ; -- shift src + pad with 0

            if bcd(3 downto 0) > "0100" then
                bcd(3 downto 0) := bcd(3 downto 0) + "0011" ;
            end if ;
            if bcd(7 downto 4) > "0100" then
                bcd(7 downto 4) := bcd(7 downto 4) + "0011" ;
            end if ;
            if bcd(11 downto 8) > "0100" then
                bcd(11 downto 8) := bcd(11 downto 8) + "0011" ;
            end if ;
        end loop ;

        bcd_hun <= bcd(11 downto 8) ;
        bcd_ten <= bcd(7  downto 4) ;
        bcd_uni <= bcd(3  downto 0) ;

    end process ;
end arc_hex2bcd ;

评论变得太长了。

考虑以下框图:

这表示一个展开的循环(for i in 0 to 7 loop)并表明,LS BCD 数字在 i = 2 之前没有发生加 +3,中间 BCD 数字在 i = 5 之前没有发生加 +3,并且 MS BCD 数字上没有发生调整,其部分包括静态“0”值。

这给了我们总共 7 个 add3 模块(由封闭的 if 语句和条件 add +3 表示)。

这在 VHDL 中得到了演示:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity bin8bcd is
    port (
        bin:    in  std_logic_vector (7 downto 0);
        bcd:    out std_logic_vector (11 downto 0)
    );
end entity;

architecture struct of bin8bcd is
    procedure add3 (signal bin: in  std_logic_vector (3 downto 0); 
                    signal bcd: out std_logic_vector (3 downto 0)) is
    variable is_gt_4:  std_logic;
    begin
        is_gt_4 := bin(3) or (bin(2) and (bin(1) or bin(0)));

        if is_gt_4 = '1' then
        -- if to_integer(unsigned (bin)) > 4 then
            bcd <= std_logic_vector(unsigned(bin) + "0011");
        else
            bcd <= bin;
        end if;
    end procedure;

    signal U0bin,U1bin,U2bin,U3bin,U4bin,U5bin,U6bin:
                std_logic_vector (3 downto 0);

    signal U0bcd,U1bcd,U2bcd,U3bcd,U4bcd,U5bcd,U6bcd:
                std_logic_vector (3 downto 0);       
begin
    U0bin <= '0' & bin (7 downto 5);
    U1bin <= U0bcd(2 downto 0) & bin(4);
    U2bin <= U1bcd(2 downto 0) & bin(3);
    U3bin <= U2bcd(2 downto 0) & bin(2);
    U4bin <= U3bcd(2 downto 0) & bin(1);

    U5bin <= '0' & U0bcd(3) & U1bcd(3) & U2bcd(3);
    U6bin <= U5bcd(2 downto 0) & U3bcd(3);

U0: add3(U0bin,U0bcd);

U1: add3(U1bin,U1bcd);

U2: add3(U2bin,U2bcd);

U3: add3(U3bin,U3bcd);

U4: add3(U4bin,U4bcd);

U5: add3(U5bin,U5bcd);

U6: add3(U6bin,U6bcd);

OUTP:
    bcd <= '0' & '0' & U5bcd(3) & U6bcd & U4bcd & bin(0);

end architecture;

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity bin8bcd_tb is
end entity;

architecture foo of bin8bcd_tb is
    signal bin: std_logic_vector (7 downto 0) := (others => '0');
    -- (initialized to prevent those annoying metavalue reports)

    signal bcd: std_logic_vector (11 downto 0);

begin

DUT:
    entity work.bin8bcd
        port map (
            bin => bin,
            bcd => bcd
        );

STIMULUS:
    process

    begin
        for i in 0 to 255 loop
            bin <= std_logic_vector(to_unsigned(i,8));
            wait for 1 ns;
        end loop;
        wait for 1 ns;
        wait;
    end process;
end architecture;

当运行附带的测试台时,会产生:

如果您滚动浏览整个波形,您会发现从 001 到 255 的所有 bcd 输出都存在并被考虑(没有孔),任何地方都没有“X”或“U”。

从显示 i = 7 的框图中我们可以看出,在最后一次移位之后没有发生 add +3。

另请注意,bcd 的 LSB 始终是 bin 的 LSB,并且 bcd(11) 和 bcd(10) 始终为“0”。

add3 可以手动优化,使用逻辑运算符创建 3 的增量,以消除报告从 bin 派生的元值的任何可能性(并且会有很多元值)。

据我所知,这代表了 8 位二进制到 12 位 BCD 转换的最优化表示。

之前我编写了一个 C 程序来为 espresso(术语最小化器)提供输入:

/*
 * binbcd.c   - generates input to espresso for 8 bit binary
 *         to 12 bit bcd.
 *
 */
#include <stdlib.h>
#include <stdio.h>


int main (argc, argv)
int argc;
char **argv;
{
int binary;
int bit;
char bcd_buff[4];
int digit;
int bcd;

    printf(".i 8\n");
    printf(".o 12\n");

    for (binary = 0; binary < 256; binary++)  {
        for ( bit = 7; bit >= 0; bit--) {
            if ((1 << bit) & binary)
                printf("1");
            else
                printf("0");
        }

        digit = snprintf(bcd_buff,4,"%03d",binary); /* leading zeros */

        if (digit != 3) {
            fprintf(stderr,"%s: binary to string conversion failure, digit = %d\n",
                argv[0],digit);
            exit (-1);
        }

        printf (" ");  /* input to output space */

        for ( digit = 0; digit <= 2; digit++) {
            bcd = bcd_buff[digit] - 0x30;
            for (bit = 3; bit >= 0; bit--) {
                if ((1 << bit) & bcd) 
                    printf("1");
                else
                    printf("0"); 
            }
        }
        /* printf(" %03d",binary); */
        printf("\n");
    }

    printf (".e\n");
    exit (0);

然后开始研究中间术语,这将直接引导您了解上面框图中所表示的内容。

当然,您可以使用实际的组件 add3 以及使用嵌套的生成语句来连接所有内容。

如果不限制 if 语句(对于 LS BCD 数字,2

您希望辅助嵌套生成语句为缩短的结构表示提供相同的约束。

add3 的逻辑运算符版本显示在 PDF 第 5 页上大学讲座幻灯片 https://web.archive.org/web/20120131075956/http://edda.csie.dyu.edu.tw/course/fpga/Binary2BCD.pdf对于使用 double dabble 的二进制到 BCD 转换,其中前勾用于表示否定符号,“+”表示 OR,Adjacency 表示 AND。

add3 看起来像:

procedure add3 (signal bin: in  std_logic_vector (3 downto 0); 
                signal bcd: out std_logic_vector (3 downto 0)) is

begin

    bcd(3) <=  bin(3) or 
              (bin(2) and bin(0)) or 
              (bin(2) and bin(1));

    bcd(2) <= (bin(3) and bin(0)) or
              (bin(2) and not bin(1) and not bin(0));

    bcd(1) <= (bin(3) and not bin(0)) or
              (not bin(2) and bin(1)) or
              (bin(1) and bin(0));

    bcd(0) <= (bin(3) and not bin(0)) or
              (not bin(3) and not bin(2) and bin(0)) or
              (bin(2) and bin(1) and not bin(0));

end procedure;

请注意,这将允许从上下文子句中删除程序包 numeric_std (或等效程序)。

如果您以相同的顺序(在本例中从左到右)在 AND 项中写入信号,则重复的 AND 项会很好地显示,就像使用浓缩咖啡一样。在 FPGA 实现中使用中间 AND 术语没有任何价值,这些术语都按原样适合 LUT。

add3 的浓缩咖啡输入: .i 4 .o 4 0000 0000 0001 0001 0010 0010 0011 0011 0100 0100 0101 1000 0110 1001 0111 1010 1000 1011 1001 1100 1010 ---- 1011 ---- 1100 ---- 1101 ---- 1110 ---- 1111 ---- .e

浓缩咖啡的输出(espresso -eonset): .i 4 .o 4 .p 8 -100 0100 00-1 0001 --11 0010 -01- 0010 -110 1001 -1-1 1000 1--1 1100 1--0 1011 .e

当您考虑二进制到 BCD 转换的组合“深度”时,对于 FPGA 来说,它是 6 个 LUT(第 6 个是后续内容的输入)。如果转换发生在一个时钟内,这可能会将时钟速度限制在 100 MHz 以下。

通过流水线或使用顺序逻辑(时钟循环),您可以在 6 个时钟周期内以最快的速度运行 FPGA。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在VHDL中将8位二进制数转换为BCD 的相关文章

  • VHDL - FSM 未启动(仅在时序仿真中)

    我正在写我的硕士论文 而且我对 VHDL 还很陌生 但我仍然必须实现一些复杂的东西 这是我必须编写的最简单的结构之一 但我仍然遇到了一些问题 它是一个 FSM 采用低电平有效同步信号 用于对 DAC 进行编程 实现 24 位移位寄存器 这只
  • 在 VHDL 中使用 SB_RGBA_DRV 原语

    我在使用为 Lattice ICE40UP fpga 提供的 SB RGBA DRV 原语时遇到问题 技术库提供了一个 verilog 示例 我可以使用它 但是当我尝试在 VHDL 中使用它时 P R 失败 输出以下消息 错误 非法连接 S
  • 高效的按位运算,用于计数位或查找最右|最左的位

    给定一个 unsigned int 我必须执行以下操作 计算设置为 1 的位数 找到最左边1位的索引 找到最右边1位的索引 操作不应依赖于体系结构 我已经使用按位移位完成了此操作 但我必须迭代几乎所有位 es 32 例如 计算 1 unsi
  • 将 VarBinary RTF blob 转换为 MS SQL 中的文本

    我正在使用 SQL Server 2008 Column Datatype VarBinary RTF 文件被压缩并保存到此 varbinary 列 现在如何使用 SQL 访问和查看 RTF 文件中的数据 它返回这个 弰巎楛 etc 此处尝
  • 如何从 Spartan 6 写入 Nexys 3 FPGA 板上的 Micron 外部蜂窝 RAM?

    我到处都查过了 数据表 Xilinx 网站 digilent 等等 但什么也没找到 我能够使用 Adept 工具来验证我的蜂窝 RAM 是否正常运行 但我找不到任何库存 VHDL 代码作为控制器来写入数据和从中读取数据 帮助 找到了此链接
  • 爱国者导弹浮动指向误差

    从计算机系统 程序员的角度http csapp cs cmu edu http csapp cs cmu edu 练习题2 51 我们在问题 2 46 中看到 爱国者导弹软件近似为 0 1 因为 x 0 000110011001100110
  • VHDL (Xilinx) 中的错误:无法链接设计

    为什么我在 VHDL 中遇到错误 另外 有时 无法执行流程 因为之前的流程失败了 非常感谢 永久解决方案1 在win 10上 找出 installation directory Xilinx 14 x ISE DS ISE gnu MinG
  • 使用带有 1 字节变量的 Python struct.unpack

    我该如何使用struct unpack 或 Python 中可用的其他一些函数可以轻松转换one字节变量到Python整数 现在 它是以一种相当蹩脚的方式完成的 file open telemetry dat rb read magic f
  • C++读取二进制文件

    我想了解如何在 C 中读取二进制文件 我的代码 int main ifstream ifd input png ios binary ios ate int size ifd tellg ifd seekg 0 ios beg vector
  • 如何创建二进制补丁?

    为二进制文件制作补丁的最佳方法是什么 我希望用户能够简单地应用 一个简单的patch应用程序会很好 在文件上运行 diff 只是给出Binary files differ 查看bsdiff and bspatch website http
  • 在Windows中比较2个二进制文件的工具[关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我需要一个工具来比较两个二进制文件 文件相当大 我在互联网上找到的一些免费软件或试用工具不方便用于大文件
  • 删除最低位

    给定一个二进制数 删除最低位的最快方法是什么 01001001010 gt 01001001000 它将在代码中用于迭代变量的位 伪代码如下 while bits 0 index getIndexOfLowestOrderBit bits
  • 设计用于初始化的VHDL状态机

    如何最明智地设计用于初始化芯片的 VHDL 状态机 我当前的设计是 伪代码 案例状态 当 s0 gt VHDL CODE FOR WRITING VALUE TO REGISTER状态 s1 当 s1 gt VHDL CODE FOR WR
  • 获取 BLOB 的二进制内容

    我知道 为了将 BLOB 对象转换为 Javascript 中的可读格式 URL 我应该使用 createObjectURL 方法 对吧 例子 var blob new Blob Example type text plain url wi
  • 替代位置基础系统(十六进制、八进制、二进制)如何工作?如何将它们转换为十进制?

    我以前在编程课上没有学过这一点 但现在我需要知道它 有哪些学习这些数字以及如何转换它们的好资源 我几乎会像记住乘法表一样记住这些 在我们日常的十进制系统中 基数或radix http en wikipedia org wiki Radix
  • 二进制增量存储

    我正在寻找一种二进制增量存储解决方案来版本化大型二进制文件 数字音频工作站文件 使用 DAW 文件时 与用于存储原始数据 波形 的大量数据相比 大多数更改 尤其是在混音结束时 都非常小 如果我们的 DAW 文件有一个版本控制系统 让我们可以
  • 二进制浮点加法算法

    我试图理解二进制级别的 IEEE 754 浮点加法 我遵循了一些在网上找到的示例算法 并且大量测试用例与经过验证的软件实现相匹配 我的算法目前只处理正数 但是 我没有得到与此测试用例的匹配 0000100011110011011001001
  • VHDL 中的 if 语句

    我有一个关于 VHDL 中 if 语句的问题 请参见下面的示例 signal SEQ bit vector 5 downto 0 signal output bit if SEQ 000001 and CNT RESULT 111111 t
  • 从一种数字系统转换为另一种数字系统后会有多少位数字

    主要问题 有多少位数字 让我解释 我有一个二进制数 11000000 十进制数是192 转换为十进制后 它有多少位 以十进制表示 在我的示例中 它是 3 位数字 但是 这不是问题 我在互联网上搜索并找到了一种用于整数部分的算法和一种用于小数
  • 在 C++ 中分割大文件

    我正在尝试编写一个程序 该程序接受一个大文件 任何类型 并将其分成许多较小的 块 我想我已经有了基本的想法 但由于某种原因我无法创建超过 12 kb 的块大小 我知道谷歌等上有一些解决方案 但我更感兴趣的是了解这个限制的根源是什么 然后实际

随机推荐

  • 如果 main 方法位于 java 文件的“非公共类”内部怎么办?

    我有一个包含多个类的java文件 其中一个类是公共的 如果 main 方法位于非公共类内部 我无法运行该 java 文件 这是为什么 并且也没有编译错误 如果是这样 我该如何使用该 main 方法 实际上 您可以在非公共类中执行 main
  • Android - Play 商店 - 更改订阅的到期日期

    我想更改订阅的到期日期在我的 Play 商店中使用Play 商店 API 我有一个移动应用程序 您可以在其中购买续订的 Play 商店订阅 或者您可以从应用程序中的促销活动中免费获得一些时间 这里的主要问题是如果您已从 Play 商店购买了
  • 并行组合进度条和进程

    我在将要并行运行的进程与进度条的创建结合起来时遇到问题 我的流程代码是 pred pnn lt function x nn xlst lt split x 1 nrow x pred lt foreach i xlst packages c
  • 如何知道进程因“内存不足”错误而结束?

    我有一个 C 程序 它在单独的进程中运行另一个程序 该程序执行大量计算 我如何知道其他进程是否因 内存不足 错误而崩溃 I use QProcess and QLocalSocket 您无法获取 QProcess 执行的正在运行的进程崩溃的
  • 将 CSV 文件导入 PostgreSQL

    使用 MySQL Administrator GUI 工具 我将从 sql 转储文件检索的一些数据表导出到 csv 文件 然后 我尝试使用 postgres COPY 命令将这些 CSV 文件导入到 PostgreSQL 数据库中 我尝试过
  • Opencv TypeError:点不是 numpy 数组,也不是标量

    基本上 我有这段代码可以检测背景的变化并将其装箱 当我运行代码时 我收到此错误 Traceback most recent call last File cam2 py line 28 in
  • 是否可以使用 selenium 禁用 chrome 中的文件下载

    使用 ChromeDriver 和 Selenium 访问某些页面时 会自动下载特定文件 由于文件下载 代码不再继续进行 是否可以使用创建 ChromeDriver 时设置的任何 ChromeOptions 或首选项来禁用文件下载 尝试了以
  • 扩展 form.is_valid()

    我正在学习 Django 我偶然发现了一些我需要帮助的东西 forms py class UserForm forms ModelForm password1 forms CharField widget forms PasswordInp
  • 静态与动态绑定逻辑

    我有以下代码 import java lang public class Program public static void main String args B a new A a p 10 a p 10 0 class B publi
  • 在 Python 中将嵌套 JSON 转换为 CSV 文件

    我知道这个问题已经被问过很多次了 我尝试了多种解决方案 但无法解决我的问题 我有一个大的嵌套 JSON 文件 1 4GB 我想将其扁平化 然后将其转换为 CSV 文件 JSON结构是这样的 company number 12345678 d
  • 将已弃用的 preg_replace /e 替换为 preg_replace_callback [重复]

    这个问题在这里已经有答案了 result preg replace lt gt a zA Z0 9 0 1 a zA Z0 9 1 2 iseU CallFunction 1 2 3 4 5 result 上面的代码在升级到 PHP 5 5
  • Chrome devtool本地存储信息未及时更新

    Chrome版本 103 0 5060 134 arm64 Before LocalStorage和SessionStorage跟随页面js运行实时更新 Now 需要手动切换devtools选项卡或者点击devtools左上角刷新按钮来查看
  • 正则表达式类型之间的差异

    我正在读 GNU find的手册页并偶然发现了这个开关 regextype type Changes the regular expression syntax understood by regex and iregex tests wh
  • MsiOpenProduct 是从已安装产品读取属性的正确方法吗?

    给定 MSI 产品代码 我想从已安装的产品中获取升级代码 以及其他属性 我通过调用 MsiOpenProduct 方法 然后调用 MsiGetProductProperty 来尝试此操作 一个 缩写 示例如下所示 MSIHANDLE han
  • Node.js/Express.js 将 POST 请求转发到另一个域

    我的 express js 应用程序在域上有一条路由example1 com router post messages add req res gt let message new Message message title req bod
  • 在上传到服务器之前使用 Canvas 调整 Iphone 图像的大小

    在上传到我们的服务器之前 我们使用 Canvas 在 Iphone IPAD 上调整图像大小 在 iPhone 4S 和 5 上 当使用前置摄像头以横向模式拍摄照片时 调整大小效果很好 当以肖像模式拍摄时 图像会被压缩约 1 4 但当使用后
  • 通过js获取WebView中的位置

    我正在尝试创建 WebView 它将通过 js 获取 GPS 本地化 但是当我单击应该显示本地化的按钮时 在android 4 1 1 模拟器 中 错误代码2 无法启动地理定位服务 在 android 4 1 2 phone 中什么也没有发
  • 如何在 ASP.NET Core 中获取 SignalR Hub 上下文?

    我正在尝试使用以下命令获取集线器的上下文 var hubContext GlobalHost ConnectionManager GetHubContext
  • 如何获取“未过滤”的数组项?

    假设我有一个数组 我通过调用来过滤它myItems filter filterFunction1 并从中获取一些物品 然后我想运行另一个过滤功能filterFunction2与未被选中的其余项目filterFunction1 是否可以获取调
  • 在VHDL中将8位二进制数转换为BCD

    该算法众所周知 您进行 8 次左移 并在每次移位后检查个位 数十位或数百位 每个 4 位 如果它们超过 4 个 则将 3 个添加到该组中 依此类推 这是一个基于流程的解决方案 但不起作用 它会编译 但输出不是我想要的 有什么想法可能是什么问