Estoy implementando el método de doble dabble ( enlace ). Cada ciclo si un dígito BCD (decimal codificado en binario) es > 4 a continuación, agregue 3 a él. Independientemente de la adición, hay un desplazamiento a la izquierda, pero el desplazamiento a la izquierda es después de la adición.
Debido a que esto parece demasiado engorroso para ponerlo en una declaración, quiero dividirlo. AFAIK rompiendo una sola declaración se debe hacer con una variable como lo he hecho a continuación, pero creo que una señal también funcionará también. ¿Existe una guía general que diga que uno es mejor que el otro dentro de un proceso?
--this is a binary to BCD(binary coded decimal) converter
--it uses the double dabble algorithm from https://en.wikipedia.org/wiki/Double_dabble
--it takes a binary input of any length
--the length of the BCD is determined as 4*BCD_digits because every decimal digit in BCD takes 4 bits to encode
--it takes bin_len+1 cycles after go is asserted to convert
--first cycle pulls data, then the data is added and shifted bin_len times
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.numeric_std.all;
entity binBCD is
generic(
bin_len : integer; --length of binary input
BCD_digits : integer --number of decimal digits in BCD
);
port(
clk : in std_logic;
go : in std_logic; --pulse to start dd algorithm. if asserted while dd is running it will restart and the previous data will be lost
done : out std_logic; --pulse to signinfy data is valid
bin : in std_logic_vector(bin_len - 1 downto 0);
BCD : out std_logic_vector(BCD_digits*4 - 1 downto 0)
);
end entity binBCD;
architecture RTL of binBCD is
type reg_type is record
bin : unsigned(bin_len - 1 downto 0);
BCD : unsigned(BCD_digits*4 - 1 downto 0);
count : integer range 0 to bin_len;
end record;
signal r, r_next : reg_type;
begin
sequential : process(clk)
begin
if rising_edge(clk) then
r <= r_next;
if go = '1' then --register inputs
r.bin <= unsigned(bin);
r.BCD <= (others => '0');
elsif r_next.count = bin_len then --register outputs
BCD <= std_logic_vector(r_next.BCD);
end if;
end if;
end process;
combinational : process(r, go)
variable add3 : unsigned(BCD_digits*4 downto 0);
begin
done <= '0';
r_next.count <= r.count + 1;
if go = '1' then
r_next.count <= 1;
elsif r.count = 0 then
r_next.count <= 0; --count = 0 is waiting state (1 to bin_len is run)
elsif r.count = bin_len then
r_next.count <= 0;
done <= '1';
end if;
--if any decimal (four bit piece of BCD) is greater than 4 add 3
for i in BCD_digits - 1 downto 0 loop
add3(i*4 + 3 downto i*4) := r.BCD(i*4 + 3 downto i*4);
if unsigned(r.BCD(i*4 + 3 downto i*4)) > 4 then
add3(i*4 + 3 downto i*4) := unsigned(r.BCD(i*4 + 3 downto i*4)) + 3;
end if;
end loop;
--left shift the result of add3 (and msb of bin)
r_next.BCD <= add3(BCD_digits*4 - 2 downto 0) & r.bin(bin_len - 1);
--left shift bin (lsb doesn't matter, but i use '0')
r_next.bin <= r.bin(bin_len - 2 downto 0) & '0';
end process;
end architecture RTL;
Estoy preguntando específicamente sobre la variable add3, pero otros comentarios son bienvenidos.