Комментарии стали слишком длинными.
Рассмотрим следующую блок-схему:
Это представляет собой развернутый цикл (for i in 0 to 7 loop
) и показывает, что добавление +3 не происходит до i = 2 для цифры BCD LS и добавление +3 не происходит до i = 5 для средней цифры BCD, а корректировка цифры MS BCD не происходит. , который частично состоит из статических нулевых значений.
Это дает нам в общей сложности 7 модулей add3 (представленных прилагаемым оператором if и условным добавлением +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 присутствуют и учитываются (без отверстий), нигде нет «X» или «U».
Из представления на блок-диаграмме, показывающего i = 7, мы видим, что после последнего сдвига не происходит добавления +3.
Также обратите внимание, что младший бит bcd всегда является младшим битом bin, и что bcd(11) и bcd(10) всегда равны «0».
add3 можно оптимизировать вручную для создания приращения на 3 с помощью логических операторов, чтобы избавиться от любой возможности сообщать о мета-значениях, полученных из bin (а их будет много).
Насколько я могу судить, это представляет собой наиболее оптимизированное представление преобразования 8-битного двоичного кода в 12-битный BCD.
Некоторое время назад я написал программу на C для ввода эспрессо (термин минимизатор):
/*
* 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 (2 ‹ i ‹ 7 для младшей двоично-десятичной цифры, 5 ‹ i ‹ 7 для средней двоично-десятичной цифры).
Вы бы хотели, чтобы вспомогательный вложенный оператор генерации предоставлял те же ограничения для укороченного структурного представления.
Версия add3 с логическим оператором показана на странице 5 в формате PDF на слайды университетских лекций для преобразования двоичного кода в двоично-десятичный с использованием двойного dabble, где галочка вперед используется для обозначения отрицания, "+" означает ИЛИ , а Смежность означает И.
Затем 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 в реализации FPGA, все они соответствуют 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
Если учесть комбинаторную «глубину» преобразования двоичного кода в двоично-десятичный, для FPGA это 6 LUT (6-й вход для чего-то следующего). Это, вероятно, ограничивает тактовую частоту чем-то около 100 МГц, если преобразование происходит за один такт.
Путем конвейерной обработки или использования последовательной логики (цикл с тактовой частотой) вы сможете запускать FPGA с максимальной скоростью при выполнении за 6 тактов.
person
Community
schedule
27.05.2014