VHDL 코스에서 개발하는 마이크로 포서를 인스턴스화하는 앱이 있으며 FPGA의 LCD 디스플레이에도 데이터가 표시됩니다.마이크로 프로세서에서 데이터 가져 오기 VHDL Spartan 3A
마이크로와 LCD를 별도로 테스트했으며 작동합니다.
이제는 마이크로폰 (피보나치 시리즈를 생성하는 프로그램)의 데이터를 LCD에 표시하는 것이지만 일련의 용어를 표시 할 수는 없습니다.
을 Heres전체 코드,하지만 난 문제가 될 수있는 부분은 마이크로의 인스턴스에 다음 생각 나는 (그 sensitity 목록 DATO_VALIDO을 가지고 있으며, 재설정 과정)
그것을 데이터를 얻을 때 용어를 바로 처리 할 수도 있지만 LCD에 표시 할 때 올바른 순서로 표시되지 않습니다.
의사 코드는 다음과 같습니다
if DATO_VALID is '1' then
get value of ACC
convert Bin2BCD
convert BCD2ASCII
print on LCD
end
는 내가하고 싶은 그들은,이 신호는 ASCII로 변환되면 개의 다른 신호의 모든 용어를 저장하는 것입니다 : DT1, UT1, DT2, UT2, 등,
마침내 주 상태 머신에는 값을 보유하는 각 신호에 대한 상태가 있으며 용어를 표시해야합니다.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use work.bin_to_bcd_package.all; -- Paquete con la definicion de la funcion "to_bcd" y puertos de mp4
entity lcd1_3A is
port(
clk, reset : in std_logic;
LCD_DB : out std_logic_vector(7 downto 0);
LCD_E, LCD_RS, LCD_RW : out std_logic;
LED : out std_logic_vector(7 downto 0));
end lcd1_3A;
architecture behavior of lcd1_3A is
------------------------------------------------------------------------
-- Señales para la secuencia de Transmision (estados)
------------------------------------------------------------------------
type tx_sequence is (high_setup, high_hold, oneus, low_setup, low_hold, fortyus, done);
signal tx_state : tx_sequence := done;
signal tx_byte : std_logic_vector(7 downto 0);
signal tx_init : std_logic := '0';
signal SF_D : std_logic_vector(3 downto 0); -- 4 Data std_logic
signal SF_CE0 : std_logic;
------------------------------------------------------------------------
-- Señales para la secuencia de Inicalizacion (estados)
------------------------------------------------------------------------
type init_sequence is (idle, fifteenms, one, two, three, four, five, six, seven, eight, done);
signal init_state : init_sequence := idle; -- El estado inicial es idle
signal init_init, init_done : std_logic := '0'; --
signal i : integer range 0 to 750000 := 0; -- Numero de ciclos para generar una duracion de 15ms
signal i2 : integer range 0 to 2000 := 0; -- Numero de ciclos para generar una duracion de 40us
signal i3 : integer range 0 to 82000 := 0; -- Numero de ciclos para generar una duracion de 1.64ms
signal cTerminos : integer range 0 to 8 := 0;
signal SF_D0, SF_D1 : std_logic_vector(3 downto 0);
signal LCD_E0, LCD_E1 : std_logic;
signal mux : std_logic;
------------------------------------------------------------------------
-- Señales para la Maquina de estados principal (8 estados), 4 caracteres
------------------------------------------------------------------------
type display_state is (init, function_set, entry_set, set_display, clr_display, pause, set_addr,
decenasT1, unidadesT1, decenasT2, unidadesT2, decenasT3, unidadesT3,
decenasT4, unidadesT4, decenasT5, unidadesT5, decenasT6, unidadesT6,
decenasT7, unidadesT7, decenasT8, unidadesT8, done);
signal cur_state : display_state := init;
------------
--
------------
constant ram_addr_std_logics:integer:=5;-- Numero de std_logics para las direcciones del mp4
constant ram_width:integer:=4;-- Tamaño de palabra de la memoria de programa mp4
signal ACC: std_logic_vector (ram_width-1 downto 0);--salida del dato
signal BANDERAS: std_logic_vector (2 downto 0);--registro de banderas ZVC
signal DATO_VALIDO: std_logic;
signal dT1,uT1,dT2,uT2,dT3,uT3,dT4,uT4,
dT5,uT5,dT6,uT6,dT7,uT7,dT8,uT8 : std_logic_vector (7 downto 0) := "01000000";
signal otro : std_logic_vector (7 downto 0);
begin
------------------------------------------------------------------------
-- Instanciacion del microprocesador de 4 std_logics
------------------------------------------------------------------------
microprocesador: mp4 GENERIC MAP(ram_addr_std_logics, ram_width) PORT MAP(clk, reset, ACC, BANDERAS, DATO_VALIDO);
process (DATO_VALIDO, reset)
variable convBCD : std_logic_vector(11 downto 0) := (others => '0');
begin
if (reset = '1') then
cTerminos <= 0;
elsif (DATO_VALIDO = '1' and DATO_VALIDO'event) then
cTerminos <= cTerminos + 1;
if(cTerminos < 3) then
case cTerminos is
when 1 =>
--convBCD := to_bcd("000"&BANDERAS(0)&ACC);
--dT1 <= x"3"&convBCD(7 downto 4);
--uT1 <= x"3"&convBCD(3 downto 0);
dT1 <= x"30";
uT1 <= x"3"&ACC;
when 2 =>
-- convBCD := to_bcd("000"&BANDERAS(0)&ACC);
-- dT2 <= x"3"&convBCD(7 downto 4);
-- uT2 <= x"3"&convBCD(3 downto 0);
dT2 <= x"30";
uT2 <= x"3"&ACC;
when 3 =>
-- convBCD := to_bcd("000"&BANDERAS(0)&ACC);
-- dT3 <= x"3"&convBCD(7 downto 4);
-- uT3 <= x"3"&convBCD(3 downto 0);
dT3 <= x"30";
uT3 <= x"3"&ACC;
when 4 =>
-- convBCD := to_bcd("000"&BANDERAS(0)&ACC);
-- dT4 <= x"3"&convBCD(7 downto 4);
-- uT4 <= x"3"&convBCD(3 downto 0);
dT4 <= x"30";
uT4 <= x"3"&ACC;
when 5 =>
-- convBCD := to_bcd("000"&BANDERAS(0)&ACC);
-- dT5 <= x"3"&convBCD(7 downto 4);
-- uT5 <= x"3"&convBCD(3 downto 0);
dT5 <= x"30";
uT5 <= x"3"&ACC;
when 6 =>
-- convBCD := to_bcd("000"&BANDERAS(0)&ACC);
-- dT6 <= x"3"&convBCD(7 downto 4);
-- uT6 <= x"3"&convBCD(3 downto 0);
dT6 <= x"30";
uT6 <= x"3"&ACC;
when 7 =>
convBCD := to_bcd("000"&BANDERAS(0)&ACC);
dT7 <= x"3"&convBCD(7 downto 4);
uT7 <= x"3"&convBCD(3 downto 0);
when 8 =>
convBCD := to_bcd("000"&BANDERAS(0)&ACC);
dT8 <= x"3"&convBCD(7 downto 4);
uT8 <= x"3"&convBCD(3 downto 0);
when others =>
otro <= x"FF";
end case;
end if;
end if;
end process;
LCD_DB(7 downto 4) <= SF_D;
LCD_DB(3 downto 0) <= "1111";
LED <= tx_byte; -- El byte enviado al Data Display RAM del LCD se visualiza en los LEDs
SF_CE0 <= '1'; -- Deshabilita la memoria intel strataflash, StrataFlash disabled. Full access to LCD
LCD_RW <= '0'; -- Habilita la señal de escritura
-- Establece cuando transmitir un comando/dato y cuando no
with cur_state select
tx_init <= '0' when init | pause | done, -- Estados en los que NO se transmite
'1' when others; -- Transmite
-- Selecciona el bus
with cur_state select
mux <= '1' when init, -- El mux vale 1, unicamente en el estado de init
'0' when others;
-- Establece el valor de la señal init_init
with cur_state select
init_init <= '1' when init,
'0' when others;
-- Establece el valor del puerto LCD_RS (register select)
with cur_state select
LCD_RS <= '0' when function_set|entry_set|set_display|clr_display|set_addr,
'1' when others;
-- Que dato se esta transmitiendo al LCD
with cur_state select
tx_byte <= "00101000" when function_set, -- 0x28, configure the display for operation on the Spartan-3E Starter Kit board.
"00000110" when entry_set, -- 0x06, set the display to automatically increment the address pointer
"00001100" when set_display, -- 0x0C, to turn the display on and disables the cursor and blinking
"00000001" when clr_display, -- 0x01, clear the display and return the cursor to the home position, the top-left corner
"10000000" when set_addr, -- 0x80, set the initial DD RAM address
dT1 when decenasT1,
uT1 when unidadesT1,
dT2 when decenasT2,
uT2 when unidadesT2,
dT3 when decenasT3,
uT3 when unidadesT3,
dT4 when decenasT4,
uT4 when unidadesT4,
dT5 when decenasT5,
uT5 when unidadesT5,
dT6 when decenasT6,
uT6 when unidadesT6,
dT7 when decenasT7,
uT7 when unidadesT7,
dT8 when decenasT8,
uT8 when unidadesT8,
"00000000" when others;
------------------------------------------------------------------------
-- Maquina de estados principal (8 estados), 4 caracteres
------------------------------------------------------------------------
display: process(clk, reset)
begin
if(reset='1') then
cur_state <= function_set;
elsif(clk='1' and clk'event) then
case cur_state is
--Permanece en el estado de init, hasta que init_done = '1'
when init =>
if(init_done = '1') then
cur_state <= function_set;
else
cur_state <= init;
end if;
-- Todos los estados, excepto pause, utilizan el proceso transmit state machine
-- Todos los estados, excepto pause, permanecen en el estado actual por una duracion de 40us
when function_set =>
if(i2 = 2000) then
cur_state <= entry_set;
else
cur_state <= function_set;
end if;
when entry_set =>
if(i2 = 2000) then
cur_state <= set_display;
else
cur_state <= entry_set;
end if;
when set_display =>
if(i2 = 2000) then
cur_state <= clr_display;
else
cur_state <= set_display;
end if;
when clr_display =>
i3 <= 0;
if(i2 = 2000) then
cur_state <= pause;
else
cur_state <= clr_display;
end if;
-- pause, permanece en el estado actual por una duracion de 1.64ms
when pause =>
if(i3 = 82000) then
cur_state <= set_addr;
i3 <= 0;
else
cur_state <= pause;
i3 <= i3 + 1;
end if;
when set_addr =>
if(i2 = 2000) then
cur_state <= decenasT1;
else
cur_state <= set_addr;
end if;
when decenasT1 =>
if(i2 = 2000) then
cur_state <= unidadesT1;
else
cur_state <= decenasT1;
end if;
when unidadesT1 =>
if(i2 = 2000) then
cur_state <= decenasT2;
else
cur_state <= unidadesT1;
end if;
when decenasT2 =>
if(i2 = 2000) then
cur_state <= unidadesT2;
else
cur_state <= decenasT2;
end if;
when unidadesT2 =>
if(i2 = 2000) then
cur_state <= decenasT3;
else
cur_state <= unidadesT2;
end if;
when decenasT3 =>
if(i2 = 2000) then
cur_state <= unidadesT3;
else
cur_state <= decenasT3;
end if;
when unidadesT3 =>
if(i2 = 2000) then
cur_state <= decenasT4;
else
cur_state <= unidadesT3;
end if;
when decenasT4 =>
if(i2 = 2000) then
cur_state <= unidadesT4;
else
cur_state <= decenasT4;
end if;
when unidadesT4 =>
if(i2 = 2000) then
cur_state <= decenasT5;
else
cur_state <= unidadesT4;
end if;
when decenasT5 =>
if(i2 = 2000) then
cur_state <= unidadesT5;
else
cur_state <= decenasT5;
end if;
when unidadesT5 =>
if(i2 = 2000) then
cur_state <= decenasT6;
else
cur_state <= unidadesT5;
end if;
when decenasT6 =>
if(i2 = 2000) then
cur_state <= unidadesT6;
else
cur_state <= decenasT6;
end if;
when unidadesT6 =>
if(i2 = 2000) then
cur_state <= decenasT7;
else
cur_state <= unidadesT6;
end if;
when decenasT7 =>
if(i2 = 2000) then
cur_state <= unidadesT7;
else
cur_state <= decenasT7;
end if;
when unidadesT7 =>
if(i2 = 2000) then
cur_state <= decenasT8;
else
cur_state <= unidadesT7;
end if;
when decenasT8 =>
if(i2 = 2000) then
cur_state <= unidadesT8;
else
cur_state <= decenasT8;
end if;
when unidadesT8 =>
if(i2 = 2000) then
cur_state <= done;
else
cur_state <= unidadesT8;
end if;
when done =>
cur_state <= done;
end case;
end if;
end process display;
-- mux <= '1' when init '0' when others;
with mux select
SF_D <= SF_D0 when '0', --transmit
SF_D1 when others; --initialize
with mux select
LCD_E <= LCD_E0 when '0', --transmit
LCD_E1 when others; --initialize
--specified by datasheet
transmit : process(clk, reset, tx_init)
begin
if(reset='1') then
tx_state <= done;
elsif(clk='1' and clk'event) then
case tx_state is
when high_setup => -- Permanece en este estado por 40ns
LCD_E0 <= '0';
SF_D0 <= tx_byte(7 downto 4);
if(i2 = 2) then
tx_state <= high_hold;
i2 <= 0;
else
tx_state <= high_setup;
i2 <= i2 + 1;
end if;
when high_hold => -- Permanece en este estado por 240ns
LCD_E0 <= '1';
SF_D0 <= tx_byte(7 downto 4);
if(i2 = 12) then
tx_state <= oneus;
i2 <= 0;
else
tx_state <= high_hold;
i2 <= i2 + 1;
end if;
when oneus => -- Permanece en este estado por 1us
LCD_E0 <= '0';
if(i2 = 50) then
tx_state <= low_setup;
i2 <= 0;
else
tx_state <= oneus;
i2 <= i2 + 1;
end if;
when low_setup => -- Permanece en este estado por 40ns
LCD_E0 <= '0';
SF_D0 <= tx_byte(3 downto 0);
if(i2 = 2) then
tx_state <= low_hold;
i2 <= 0;
else
tx_state <= low_setup;
i2 <= i2 + 1;
end if;
when low_hold => -- Permanece en este estado por 240ns
LCD_E0 <= '1';
SF_D0 <= tx_byte(3 downto 0);
if(i2 = 12) then
tx_state <= fortyus;
i2 <= 0;
else
tx_state <= low_hold;
i2 <= i2 + 1;
end if;
when fortyus => -- Permanece en este estado por 40us
LCD_E0 <= '0';
if(i2 = 2000) then
tx_state <= done;
i2 <= 0;
else
tx_state <= fortyus;
i2 <= i2 + 1;
end if;
when done =>
LCD_E0 <= '0';
if(tx_init = '1') then
tx_state <= high_setup;
i2 <= 0;
else
tx_state <= done;
i2 <= 0;
end if;
end case;
end if;
end process transmit;
------------------------------------------------------------------------
-- Maquina de estados para la secuencia de Inicalizacion (11 estados)
------------------------------------------------------------------------
--specified by datasheet
power_on_initialize: process(clk, reset, init_init) --power on initialization sequence
begin
if(reset='1') then
init_state <= idle;
init_done <= '0'; -- Bandera de que NO ha terminado la inicializacion
elsif(clk='1' and clk'event) then
case init_state is
when idle =>
init_done <= '0'; -- Bandera de que NO ha terminado la inicializacion
if(init_init = '1') then
init_state <= fifteenms;
i <= 0;
else
init_state <= idle;
i <= i + 1;
end if;
when fifteenms => -- Permanece en este estado por 15ms
init_done <= '0'; -- Bandera de que NO ha terminado la inicializacion
if(i = 750000) then
init_state <= one;
i <= 0;
else
init_state <= fifteenms;
i <= i + 1;
end if;
when one => -- Permanece en este estado por 240ns
SF_D1 <= "0011";
LCD_E1 <= '1';
init_done <= '0'; -- Bandera de que NO ha terminado la inicializacion
if(i = 11) then
init_state<=two;
i <= 0;
else
init_state<=one;
i <= i + 1;
end if;
when two =>
LCD_E1 <= '0'; -- Permanece en este estado por 1.64ms
init_done <= '0'; -- Bandera de que NO ha terminado la inicializacion
if(i = 205000) then
init_state<=three;
i <= 0;
else
init_state<=two;
i <= i + 1;
end if;
when three => -- Permanece en este estado por 240ns
SF_D1 <= "0011";
LCD_E1 <= '1';
init_done <= '0'; -- Bandera de que NO ha terminado la inicializacion
if(i = 11) then
init_state<=four;
i <= 0;
else
init_state<=three;
i <= i + 1;
end if;
when four => -- Permanece en este estado por 100us
LCD_E1 <= '0';
init_done <= '0'; -- Bandera de que NO ha terminado la inicializacion
if(i = 5000) then
init_state<=five;
i <= 0;
else
init_state<=four;
i <= i + 1;
end if;
when five => -- Permanece en este estado por 240ns
SF_D1 <= "0011";
LCD_E1 <= '1';
init_done <= '0'; -- Bandera de que NO ha terminado la inicializacion
if(i = 11) then
init_state<=six;
i <= 0;
else
init_state<=five;
i <= i + 1;
end if;
when six => -- Permanece en este estado por 40us
LCD_E1 <= '0';
init_done <= '0'; -- Bandera de que NO ha terminado la inicializacion
if(i = 2000) then
init_state<=seven;
i <= 0;
else
init_state<=six;
i <= i + 1;
end if;
when seven => -- Permanece en este estado por 240ns
SF_D1 <= "0010";
LCD_E1 <= '1';
init_done <= '0'; -- Bandera de que NO ha terminado la inicializacion
if(i = 11) then
init_state<=eight;
i <= 0;
else
init_state<=seven;
i <= i + 1;
end if;
when eight => -- Permanece en este estado por 40us
LCD_E1 <= '0';
init_done <= '0'; -- Bandera de que NO ha terminado la inicializacion
if(i = 2000) then
init_state<=done;
i <= 0;
else
init_state<=eight;
i <= i + 1;
end if;
when done =>
init_state <= done;
init_done <= '1'; -- Bandera que indica que TERMINO la inicializacion
end case;
end if;
end process power_on_initialize;
end behavior;
당신이 무슨 뜻인지 설명 할 수) : > 그것은 바로 조건을 처리 할 수 있지만 나는 에 표시 할 때> LCD 그들은에서 표시되지 않는 올바른 순서. 당신이받은 주문을 줄 수 있습니까?이렇게하면 문제를 더 잘 이해하는 데 도움이됩니다. – FarhadA