Files
XC3S400/main.vhdl
2023-05-29 11:00:35 -03:00

418 lines
15 KiB
VHDL
Raw Permalink Blame History

----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 20:27:12 06/22/2022
-- Design Name:
-- Module Name: main - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity main is
Port ( CLK : in STD_LOGIC;
LEDS : out STD_LOGIC_VECTOR (7 downto 0);
BUT : in STD_LOGIC_VECTOR (3 downto 0);
SW : in STD_LOGIC_VECTOR (7 downto 0);
SEVSEG_SEGMENTS: out STD_LOGIC_VECTOR (7 downto 0);
SEVSEG_DIGITS: out STD_LOGIC_VECTOR (3 downto 0);
GPIO: out STD_LOGIC_VECTOR (15 downto 0)
);
end main;
architecture Behavioral of main is
signal cont100k: std_logic_vector (15 downto 0);
signal clk100k: std_logic;
signal contaux: std_logic_vector (31 downto 0);
signal clk745ms, clk1490ms, clkcpu: std_logic;
signal cont115200: std_logic_vector (7 downto 0);
signal SEVSEG_UINT16: std_logic_vector (15 downto 0);
signal DATABUS: std_logic_vector (7 downto 0);
signal ADDRBUS: std_logic_vector (7 downto 0);
signal INSTRUCTION_REGISTER: std_logic_vector (31 downto 0) := "11111111111111111111111111111111";
signal INSTRUCTION_STEP: std_logic_vector (7 downto 0) := "00000000";
signal PROGRAM_COUNTER: std_logic_vector (7 downto 0) := "00000000";
--control signals
signal ALU_LOAD1: std_logic := '0';
signal ALU_LOAD2: std_logic := '0';
signal ALU_OE: std_logic := '0';
signal REGISTERS_OE: std_logic_vector (15 downto 0) := "0000000000000000";
signal REGISTERS_WR: std_logic_vector (15 downto 0) := "0000000000000000";
--signal PC_OE: std_logic;
--signal PC_WR: std_logic;
--signal PC_INC: std_logic;
signal UART_TX_LOAD: std_logic := '0';
signal UART_TX_CLK: std_logic := '0';
--flags
signal FLAG_CARRY: std_logic := '0';
signal FLAG_ZERO: std_logic := '0';
--fake flash memory
type fakeflash_t is array (255 downto 0) of std_logic_vector (31 downto 0);
signal program: fakeflash_t;
component SEVSEG
Port ( UINT16 : in STD_LOGIC_VECTOR (15 downto 0);
CLK : in STD_LOGIC;
SEGMENTS : out STD_LOGIC_VECTOR (7 downto 0);
DIGITS : out STD_LOGIC_VECTOR (3 downto 0)
);
end component;
component ALU_P379
Port ( ALU1 : in STD_LOGIC_VECTOR (7 downto 0);
LOAD1 : in STD_LOGIC;
ALU2 : in STD_LOGIC_VECTOR (7 downto 0);
LOAD2 : in STD_LOGIC;
OE : in STD_LOGIC;
OPCODE: in STD_LOGIC_VECTOR (7 downto 0);
CARRY : out STD_LOGIC;
ZERO : out STD_LOGIC;
OUTPUT : out STD_LOGIC_VECTOR (7 downto 0));
end component;
component REGISTERS
Port ( DATA : inout STD_LOGIC_VECTOR (7 downto 0);
OE : in STD_LOGIC_VECTOR (15 downto 0);
WR : in STD_LOGIC_VECTOR (15 downto 0);
RESET: in STD_LOGIC);
end component;
--component PROGRAM_COUNTER
-- Port ( PCIN : in STD_LOGIC_VECTOR (7 downto 0);
-- PCOUT : out STD_LOGIC_VECTOR (7 downto 0);
-- OE : in STD_LOGIC;
-- WR : in STD_LOGIC;
-- INC : in STD_LOGIC;
-- RESET : in STD_LOGIC);
--end component;
component UART_TX
Port ( DATA : in STD_LOGIC_VECTOR (7 downto 0);
LOAD : in STD_LOGIC;
CLK : in STD_LOGIC;
BUSY : out STD_LOGIC;
TX_PIN : out STD_LOGIC);
end component;
begin
SEVSEG0: SEVSEG port map ( UINT16 => SEVSEG_UINT16,
CLK => contaux(12),
SEGMENTS => SEVSEG_SEGMENTS,
DIGITS => SEVSEG_DIGITS
);
ALU0: ALU_P379 port map ( ALU1 => DATABUS,
LOAD1 => ALU_LOAD1,
ALU2 => DATABUS,
LOAD2 => ALU_LOAD2,
OE => ALU_OE,
OPCODE => INSTRUCTION_REGISTER (23 downto 16),
CARRY => FLAG_CARRY,
ZERO => FLAG_ZERO,
OUTPUT => DATABUS
);
REGISTERS0: REGISTERS port map ( DATA => DATABUS,
OE => REGISTERS_OE,
WR => REGISTERS_WR,
RESET => '0' --comes from POR
);
--PC0: PROGRAM_COUNTER port map ( PCIN => DATABUS,
-- PCOUT => ADDRBUS,
-- OE => '0', --comes from control logic
-- WR => '0', --comes from control logic
-- INC => '0', --comes from control logic
-- RESET => '0' --comes from POR
-- );
UART_TX0: UART_TX port map ( DATA => DATABUS,
LOAD => UART_TX_LOAD,
CLK => UART_TX_CLK,
BUSY => GPIO(1),
TX_PIN => GPIO(0)
);
--begin fake flash memory
program(0) <= "0000" & "0001" & "00000010" & "01001000" & "00000000"; --MOV R2, 48
program(1) <= "0011" & "0000" & "00000010" & "00000110" & "00000000"; --TX R2
program(2) <= "0000" & "0001" & "00000010" & "01100101" & "00000000"; --MOV R2, 65
program(3) <= "0011" & "0000" & "00000010" & "00000110" & "00000000"; --TX R2
program(4) <= "0000" & "0001" & "00000010" & "01101100" & "00000000"; --MOV R2, 6C
program(5) <= "0011" & "0000" & "00000010" & "00000110" & "00000000"; --TX R2
program(6) <= "0000" & "0001" & "00000010" & "01101100" & "00000000"; --MOV R2, 6C
program(7) <= "0011" & "0000" & "00000010" & "00000110" & "00000000"; --TX R2
program(8) <= "0000" & "0001" & "00000010" & "01101111" & "00000000"; --MOV R2, 6F
program(9) <= "0011" & "0000" & "00000010" & "00000110" & "00000000"; --TX R2
program(10) <= "0000" & "0001" & "00000010" & "00100000" & "00000000"; --MOV R2, 20
program(11) <= "0011" & "0000" & "00000010" & "00000110" & "00000000"; --TX R2
program(12) <= "0000" & "0001" & "00000010" & "01110111" & "00000000"; --MOV R2, 77
program(13) <= "0011" & "0000" & "00000010" & "00000110" & "00000000"; --TX R2
program(14) <= "0000" & "0001" & "00000010" & "01101111" & "00000000"; --MOV R2, 6F
program(15) <= "0011" & "0000" & "00000010" & "00000110" & "00000000"; --TX R2
program(16) <= "0000" & "0001" & "00000010" & "01110010" & "00000000"; --MOV R2, 72
program(17) <= "0011" & "0000" & "00000010" & "00000110" & "00000000"; --TX R2
program(18) <= "0000" & "0001" & "00000010" & "01101100" & "00000000"; --MOV R2, 6C
program(19) <= "0011" & "0000" & "00000010" & "00000110" & "00000000"; --TX R2
program(20) <= "0000" & "0001" & "00000010" & "01100100" & "00000000"; --MOV R2, 64
program(21) <= "0011" & "0000" & "00000010" & "00000110" & "00000000"; --TX R2
program(22) <= "0000" & "0001" & "00000010" & "00001101" & "00000000"; --MOV R2, 0D
program(23) <= "0011" & "0000" & "00000010" & "00000110" & "00000000"; --TX R2
program(24) <= "0000" & "0001" & "00000010" & "00001010" & "00000000"; --MOV R2, 0A
program(25) <= "0011" & "0000" & "00000010" & "00000110" & "00000000"; --TX R2
program(26) <= "0000" & "0001" & "00000000" & "11111010" & "00000000"; --MOV R0, FA
program(27) <= "0000" & "0001" & "00000001" & "00000110" & "00000000"; --MOV R1, 06
program(28) <= "0001" & "0000" & "00000000" & "00000000" & "00000001"; --ALU ADD R0, R1
program(29) <= "0000" & "0001" & "00001110" & "00000000" & "00000000"; --MOV R14, 00
program(30) <= "0010" & "0010" & "00001110" & "00000000" & "00000000"; --JZ R14
program(31) <= "0000" & "0001" & "00001111" & "00011111" & "00000000"; --MOV R15, 1F
program(32) <= "0010" & "0000" & "00001111" & "00000000" & "00000000"; --JMP R15
--end fake flash memory
--SEVSEG_UINT16 <= ADDRBUS & DATABUS;
SEVSEG_UINT16 <= INSTRUCTION_STEP & DATABUS;
DATABUS <= "ZZZZZZZZ";
LEDS <= "ZZZZZZZZ";
SEVSEG_SEGMENTS <= "ZZZZZZZZ";
SEVSEG_DIGITS <= "ZZZZ";
SEVSEG_UINT16 <= "ZZZZ" & "ZZZZ" & "ZZZZ" & "ZZZZ";
GPIO <= "ZZZZZZZZZZZZZZZZ";
CLK100k <= cont100k(7);
clk745ms <= contaux(23);
clk1490ms <= contaux(24);
clkcpu <= contaux(22);
UART_TX_CLK <= cont115200(7);
LEDS <= INSTRUCTION_REGISTER(31 downto 24);
--begin control logic
--end control logic
process (clkcpu)
begin
if(clkcpu'event and clkcpu = '1') then
INSTRUCTION_STEP <= INSTRUCTION_STEP + "00000001";
case INSTRUCTION_REGISTER (31 downto 24) is
when "00000000" =>
--MOV R, R
case INSTRUCTION_STEP is
when "00000000" =>
REGISTERS_OE(to_integer(unsigned(INSTRUCTION_REGISTER(15 downto 8)))) <= '1';
when "00000001" =>
REGISTERS_WR(to_integer(unsigned(INSTRUCTION_REGISTER(23 downto 16)))) <= '1';
when "00000010" =>
REGISTERS_OE(to_integer(unsigned(INSTRUCTION_REGISTER(15 downto 8)))) <= '0';
REGISTERS_WR(to_integer(unsigned(INSTRUCTION_REGISTER(23 downto 16)))) <= '0';
when "00000011" =>
--Coloca PC no AB
ADDRBUS <= PROGRAM_COUNTER;
when others =>
--Carrega fakeflash no IR, zera step e incrementa PC
INSTRUCTION_REGISTER <= program(to_integer(unsigned(ADDRBUS)));
INSTRUCTION_STEP <= "00000000";
PROGRAM_COUNTER <= PROGRAM_COUNTER + "00000001";
end case;
when "00000001" =>
--MOV R, K
case INSTRUCTION_STEP is
when "00000000" =>
DATABUS <= INSTRUCTION_REGISTER(15 downto 8);
when "00000001" =>
REGISTERS_WR(to_integer(unsigned(INSTRUCTION_REGISTER(23 downto 16)))) <= '1';
when "00000010" =>
REGISTERS_WR(to_integer(unsigned(INSTRUCTION_REGISTER(23 downto 16)))) <= '0';
DATABUS <= "ZZZZZZZZ";
when "00000011" =>
--Coloca PC no AB
ADDRBUS <= PROGRAM_COUNTER;
when others =>
--Carrega fakeflash no IR, zera step e incrementa PC
INSTRUCTION_REGISTER <= program(to_integer(unsigned(ADDRBUS)));
INSTRUCTION_STEP <= "00000000";
PROGRAM_COUNTER <= PROGRAM_COUNTER + "00000001";
end case;
when "00010000" =>
--ALU OP R, R
case INSTRUCTION_STEP is
when "00000000" =>
REGISTERS_OE(to_integer(unsigned(INSTRUCTION_REGISTER(15 downto 8)))) <= '1';
when "00000001" =>
ALU_LOAD1 <= '1';
when "00000010" =>
REGISTERS_OE(to_integer(unsigned(INSTRUCTION_REGISTER(15 downto 8)))) <= '0';
ALU_LOAD1 <= '0';
when "00000011" =>
REGISTERS_OE(to_integer(unsigned(INSTRUCTION_REGISTER(7 downto 0)))) <= '1';
when "00000100" =>
ALU_LOAD2 <= '1';
when "00000101" =>
REGISTERS_OE(to_integer(unsigned(INSTRUCTION_REGISTER(7 downto 0)))) <= '0';
ALU_LOAD2 <= '0';
when "00000110" =>
ALU_OE <= '1';
when "00000111" =>
REGISTERS_WR(to_integer(unsigned(INSTRUCTION_REGISTER(15 downto 8)))) <= '1';
when "00001000" =>
REGISTERS_WR(to_integer(unsigned(INSTRUCTION_REGISTER(15 downto 8)))) <= '0';
ALU_OE <= '0';
when "00001001" =>
--Coloca PC no AB
ADDRBUS <= PROGRAM_COUNTER;
when others =>
--Carrega fakeflash no IR, zera step e incrementa PC
INSTRUCTION_REGISTER <= program(to_integer(unsigned(ADDRBUS)));
INSTRUCTION_STEP <= "00000000";
PROGRAM_COUNTER <= PROGRAM_COUNTER + "00000001";
end case;
when "00100000" =>
--JMP R
case INSTRUCTION_STEP is
when "00000000" =>
REGISTERS_OE(to_integer(unsigned(INSTRUCTION_REGISTER(23 downto 16)))) <= '1';
when "00000001" =>
PROGRAM_COUNTER <= DATABUS;
when "00000010" =>
REGISTERS_OE(to_integer(unsigned(INSTRUCTION_REGISTER(23 downto 16)))) <= '0';
when "00000011" =>
--Coloca PC no AB
ADDRBUS <= PROGRAM_COUNTER;
when others =>
--Carrega fakeflash no IR, zera step e incrementa PC
INSTRUCTION_REGISTER <= program(to_integer(unsigned(ADDRBUS)));
INSTRUCTION_STEP <= "00000000";
PROGRAM_COUNTER <= PROGRAM_COUNTER + "00000001";
end case;
when "00100001" =>
--JC R
case INSTRUCTION_STEP is
when "00000000" =>
REGISTERS_OE(to_integer(unsigned(INSTRUCTION_REGISTER(23 downto 16)))) <= '1';
when "00000001" =>
if(FLAG_CARRY = '1') then
PROGRAM_COUNTER <= DATABUS;
end if;
when "00000010" =>
REGISTERS_OE(to_integer(unsigned(INSTRUCTION_REGISTER(23 downto 16)))) <= '0';
when "00000011" =>
--Coloca PC no AB
ADDRBUS <= PROGRAM_COUNTER;
when others =>
--Carrega fakeflash no IR, zera step e incrementa PC
INSTRUCTION_REGISTER <= program(to_integer(unsigned(ADDRBUS)));
INSTRUCTION_STEP <= "00000000";
PROGRAM_COUNTER <= PROGRAM_COUNTER + "00000001";
end case;
when "00100010" =>
--JZ R
case INSTRUCTION_STEP is
when "00000000" =>
REGISTERS_OE(to_integer(unsigned(INSTRUCTION_REGISTER(23 downto 16)))) <= '1';
when "00000001" =>
if(FLAG_ZERO = '1') then
PROGRAM_COUNTER <= DATABUS;
end if;
when "00000010" =>
REGISTERS_OE(to_integer(unsigned(INSTRUCTION_REGISTER(23 downto 16)))) <= '0';
when "00000011" =>
--Coloca PC no AB
ADDRBUS <= PROGRAM_COUNTER;
when others =>
--Carrega fakeflash no IR, zera step e incrementa PC
INSTRUCTION_REGISTER <= program(to_integer(unsigned(ADDRBUS)));
INSTRUCTION_STEP <= "00000000";
PROGRAM_COUNTER <= PROGRAM_COUNTER + "00000001";
end case;
when "00110000" =>
--TX R
case INSTRUCTION_STEP is
when "00000000" =>
REGISTERS_OE(to_integer(unsigned(INSTRUCTION_REGISTER(23 downto 16)))) <= '1';
when "00000001" =>
UART_TX_LOAD <= '1';
when "00000010" =>
REGISTERS_OE(to_integer(unsigned(INSTRUCTION_REGISTER(23 downto 16)))) <= '0';
UART_TX_LOAD <= '0';
when "00000011" =>
--Coloca PC no AB
ADDRBUS <= PROGRAM_COUNTER;
when others =>
--Carrega fakeflash no IR, zera step e incrementa PC
INSTRUCTION_REGISTER <= program(to_integer(unsigned(ADDRBUS)));
INSTRUCTION_STEP <= "00000000";
PROGRAM_COUNTER <= PROGRAM_COUNTER + "00000001";
end case;
when others =>
--Busca primeira instru<72><75>o
case INSTRUCTION_STEP is
when "00000000" =>
--Coloca PC no AB
ADDRBUS <= PROGRAM_COUNTER;
when others =>
--Carrega fakeflash no IR, zera step e incrementa PC
INSTRUCTION_REGISTER <= program(to_integer(unsigned(ADDRBUS)));
INSTRUCTION_STEP <= "00000000";
PROGRAM_COUNTER <= PROGRAM_COUNTER + "00000001";
end case;
end case;
end if;
end process;
process (CLK)
begin
if(CLK'event and CLK = '1') then
--CLK 25MHz
contaux <= contaux + "00000000000000000000000000000001";
if (cont100k = "0000000000000000") then
cont100k <= "0000000011111001";
else
cont100k <= cont100k - "0000000000000001";
end if;
if (cont115200 = "00000000") then
cont115200 <= "11011000";
else
cont115200 <= cont115200 - "00000001";
end if;
end if;
end process;
process (BUT(3))
begin
if(BUT(3) = '1') then
DATABUS <= SW;
else
DATABUS <= "ZZZZZZZZ";
end if;
end process;
end Behavioral;