418 lines
15 KiB
VHDL
418 lines
15 KiB
VHDL
----------------------------------------------------------------------------------
|
||
-- 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; |