Hola hola!
Pues no es moco de pavo hacer una caculadora en VHDL si estás empezando con este lenguaje, pero bueno. Suerte y al toro.
Te paso una ayudita que he encontrado entre mis papelotes. Tómalo como una orientación, porque el sistema global utiliza una RAM y un microprocesador para almacenar los operandos y los resultados. Es muy complejo, la verdad. A ver si te ayuda:
Codigo:
-- Calculadora de operaciones básicas (8 bits)
-- Entrada: operandos: de 0-9. Entran a la FPGA desde un teclado
-- Operaciones: suma, resta, multiplicación
-- Salida: un display de leds de 7 segmentos.
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- --------------------------------------------
Entity miCalculador is
-- --------------------------------------------
Port ( CLK : In std_logic; -- reloj de la FPGA
key_clk : In std_logic; -- reloj del teclado
key_data : In std_logic; -- dato del teclado
nPSEN : In std_logic;
PC_D : In std_logic_vector (5 downto 0);
nWR : In std_logic;
ALE : In std_logic;
AH : In std_logic_vector (15 downto ;
AD : InOut std_logic_vector (7 downto 0);
AL : Out std_logic_vector (7 downto 0);
nCE : Out std_logic;
nRD : In std_logic;
nOE : Out std_logic;
AH_16 : Out std_logic;
RST : Out std_logic;
XTAL1 : Out std_logic;
LED : Out std_logic_vector (6 downto 0)
);
end miCalculador;
-- --------------------------------------------
Architecture Behavior of miCalculador is
-- --------------------------------------------
-- ------------------------------------------------------------
-- Registros para almacenar los operandos y los resultados (en una RAM o en un
-- micro)
-- ------------------------------------------------------------
component ScanReg is
port ( kbclk, kbdata, reset: in std_logic;
scancode: out std_logic_vector(7 downto 0);
done: out std_logic);
end component;
component Reg is
generic( N : positive := 8 );
port( D : in std_logic_vector( N-1 downto 0);
C, Clk, R : in std_logic;
Q : out std_logic_vector(N-1 downto 0));
end component;
-- -------------------------------------------------------------
-- Conversores que pasa la entrada desde el teclado
-- a datos manejables por la FPGA, y también al contrario, pasan
-- datos producidos por la FPGA a datos visualizables por el display de leds
-- -------------------------------------------------------------
component scanconversor is
port (scancode: in std_logic_vector(7 downto 0);
kind: out std_logic;
digit: out std_logic_vector(3 downto 0));
end component;
component hex2siete is
port(hex: in std_logic_vector(3 downto 0);
seg: out std_logic_vector(6 downto 0));
end component;
-- --------------------------------------------------------------
-- Otros componentes que vienen bien
-- --------------------------------------------------------------
component ibuf is -- El típico buffer
port(i: in std_logic;
o: out std_logic);
end component;
component bufg is -- temporiza una señal
port(i: in std_logic;
o: out std_logic);
end component;
-- --------------------------------------------------------------
-- señales que conectan con el diseño
-- --------------------------------------------------------------
signal ENLED : std_logic;
signal DOE : std_logic;
signal RSTi : std_logic;
signal Din : std_logic_vector (7 downto 0);
signal Dout : std_logic_vector (7 downto 0);
signal WR : std_logic;
signal RD : std_logic;
signal Out_temp : std_logic_vector( 7 downto 0 );
signal buf_key_clk : std_logic;
signal kbclk : std_logic;
signal kbdata : std_logic;
signal ttype : std_logic;
signal done : std_logic;
signal Hex_out, Hex_in : std_logic_vector( 3 downto 0 );
begin
AH_16 <= "0";
RSTi <= PC_D(0);
XTAL1 <= CLK;
nCE <= AH(15);
nOE <= not (not nRD or not nPSEN);
WR <= not nWR;
RD <= not nRD;
RST <= RSTi;
Dout <= "00" & done & ttype & Hex_in;
Din <= AD;
LATCH_ENABLE : process (CLK,RSTi)
begin
if RSTi="1" then AL <= (others=>"0") ;
elsif rising_edge(CLK) then
if ALE="1" then AL <= Din; end if;
end if;
end process;
TRI_STATE : process (AD, Dout, DOE)
begin
if DOE="1" then AD <= Dout;
else AD <= (others=>"Z") ;
end if;
end process;
-- ------------------------------------------------------------
-- Conexión entre las señales y los outputs de los puertos
-- ------------------------------------------------------------
LEDReg: Reg generic map (4)
port map ( Din(3 downto 0),
ENLED,
CLK, RSTi,
Hex_out
);
LEDCov: hex2siete port map (
Hex_out,
LED
);
-- ------------------------------------------------------------
-- amplifica las señales de entrada y las temporiza
-- ------------------------------------------------------------
Buffer_dclk : ibuf port map (
key_data,
kbdata
);
Buffer_kclk : ibuf port map (
key_clk,
buf_key_clk
);
Clock_Buffer : bufg port map (
buf_key_clk,
kbclk
);
-- -------------------------------------------------------------
-- Conexión entre las señales y los inputs de los puertos
-- -------------------------------------------------------------
Scan : ScanReg port map (
kbclk,
kbdata,
rsti,
Out_temp,
done
) ;
ScanConv : scanconversor port map (
Out_temp,
ttype,
Hex_in
) ;
-- -------------------------------------------------------------
-- decodificador
-- -------------------------------------------------------------
DECODE : process (AH,RD,WR)
begin
DOE <= "0";
ENLED <= "0";
if (AH(15 downto 12)= x"F" ) then
ENLED <= WR;
elsif (AH(15 downto 12)= x"E" ) then
DOE <= RD;
end if;
end process;
end Behavior;
El código para el componente registro:
Codigo:
entity Reg is
generic( N : positive := 8 );
port( D : in std_logic_vector( N-1 downto 0);
C, Clk, R : in std_logic;
Q : out std_logic_vector(N-1 downto 0));
end Reg;
architecture behavior of Reg is
begin
process( Clk, R )
begin
if ( R = "1" ) then Q <= (others => "0" );
elsif (rising_edge(Clk)) then if ( C = "1" ) then Q <= D; end if;
end if;
end process;
end behavior;
El código para el conversor
Codigo:
entity scanconversor is
port (scancode: in std_logic_vector(7 downto 0);
kind: out std_logic;
digit: out std_logic_vector(3 downto 0));
end entity;
architecture behavior of scanconversor is
begin
process(scancode)
begin
case scancode is
when x"45" => kind <= "0"; digit <= "0000"; --0
when x"16" => kind <= "0"; digit <= "0001"; --1
when x"1E" => kind <= "0"; digit <= "0010"; --2
when x"26" => kind <= "0"; digit <= "0011"; --3
when x"25" => kind <= "0"; digit <= "0100"; --4
when x"2E" => kind <= "0"; digit <= "0101"; --5
when x"36" => kind <= "0"; digit <= "0110"; --6
when x"3D" => kind <= "0"; digit <= "0111"; --7
when x"3E" => kind <= "0"; digit <= "1000"; --8
when x"46" => kind <= "0"; digit <= "1001"; --9
when x"3A" => kind <= "1"; digit <= "0110"; --M
when x"4D" => kind <= "1"; digit <= "0000"; -- P
when x"1B" => kind <= "1"; digit <= "1111"; -- S
when x"55" => kind <= "1"; digit <= "0001"; -- =
when others => kind <= "0"; digit<= "0000";
end case;
end process;
end architecture;
Codigo:
entity scanreg is
port (kbclk, kbdata, reset: in std_logic;
scancode: out std_logic_vector(7 downto 0);
done: out std_logic);
end entity;
architecture behavior of scanreg is
signal temp: std_logic_vector(10 downto 0);
signal count: std_logic_vector(6 downto 0);
begin
scancode <= temp(8 downto 1);
process(kbclk, reset)
begin
if (reset = "1") then
temp <= (others => "0");
count <= (others => "0");
done <= "0";
elsif(falling_edge(kbclk)) then
temp <= kbdata & temp(10 downto 1);
if (count = "100000" ) then
done <= "1";
count <= "0000000";
else
count <= count + "000001";
done <= "0";
end if;
end if;
end process;
end architecture;
Ufff... bueno, ya nos contarás. Suerte.
Bye!