feature/control_logic #1

Merged
Gabriel merged 8 commits from feature/control_logic into develop 2023-04-18 15:05:29 -03:00
5 changed files with 321 additions and 29 deletions

View File

@@ -11,12 +11,13 @@ entity ALU_P379 is
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 ALU_P379;
architecture Behavioral of ALU_P379 is
signal OUTPUT_ALL: std_logic_vector (7 downto 0);
signal OUTPUT_ALL: std_logic_vector (8 downto 0);
signal ALU1_REG: std_logic_vector (7 downto 0);
signal ALU2_REG: std_logic_vector (7 downto 0);
@@ -26,20 +27,26 @@ process(OPCODE)
begin
case OPCODE is
when "00000000" => output_all <= ALU1_REG + ALU2_REG;
when "00000001" => output_all <= ALU1_REG - ALU2_rEG;
when "00000010" => output_all <= ALU1_REG and ALU2_REG;
when "00000011" => output_all <= ALU1_REG nand ALU2_REG;
when "00000100" => output_all <= ALU1_REG or ALU2_REG;
when "00000101" => output_all <= ALU1_REG xor ALU2_REG;
when "00000111" => output_all <= not ALU1_REG;
when others => output_all <= "ZZZZZZZZ";
when "00000001" => output_all <= '0' & (ALU1_REG - ALU2_REG);
when "00000010" => output_all <= '0' & (ALU1_REG and ALU2_REG);
when "00000011" => output_all <= '0' & (ALU1_REG nand ALU2_REG);
when "00000100" => output_all <= '0' & (ALU1_REG or ALU2_REG);
when "00000101" => output_all <= '0' & (ALU1_REG xor ALU2_REG);
when "00000111" => output_all <= '0' & (not ALU1_REG);
when others => output_all <= "0ZZZZZZZZ";
end case;
end process;
process(OE)
begin
case OE is
when '1' => OUTPUT <= output_all;
when '1' =>
OUTPUT <= output_all (7 downto 0);
CARRY <= output_all(8);
case output_all is
when "000000000" => ZERO <= '1';
when others => ZERO <= '0';
end case;
when others => OUTPUT <= "ZZZZZZZZ";
end case;
end process;

View File

@@ -32,7 +32,8 @@ use IEEE.STD_LOGIC_1164.ALL;
entity Registers is
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));
WR : in STD_LOGIC_VECTOR (15 downto 0);
RESET : in STD_LOGIC);
end Registers;
architecture Behavioral of Registers is
@@ -42,20 +43,23 @@ signal regvalues: regarray_t;
begin
process(WR)
process(WR, RESET)
begin
for regindex in 15 downto 0 loop
if(WR(regindex)'event and WR(regindex) = '1') then
regvalues(regindex) <= DATA;
end if;
end loop;
if (RESET = '1') then
for regindex in 15 downto 0 loop
regvalues(regindex) <= "00000000";
end loop;
end if;
end process;
process(OE)
begin
if (OE = "0000000000000000") then
DATA <= "ZZZZZZZZ";
end if;
DATA <= "ZZZZZZZZ";
for regindex in 15 downto 0 loop
if(OE(regindex) = '1') then
DATA <= regvalues(regindex);

View File

@@ -35,6 +35,10 @@
<association xil_pn:name="Implementation" xil_pn:seqID="2"/>
</file>
<file xil_pn:name="Opcode descriptions.txt" xil_pn:type="FILE_USERDOC"/>
<file xil_pn:name="program_counter.vhdl" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="66"/>
<association xil_pn:name="Implementation" xil_pn:seqID="0"/>
</file>
</files>
<properties>

227
main.vhdl
View File

@@ -19,12 +19,12 @@
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.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;
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
@@ -52,7 +52,25 @@ 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 FLAG_CARRY: std_logic;
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;
--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);
@@ -74,15 +92,26 @@ component ALU_P379
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));
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;
begin
SEVSEG0: SEVSEG port map ( UINT16 => SEVSEG_UINT16,
@@ -92,29 +121,42 @@ SEVSEG0: SEVSEG port map ( UINT16 => SEVSEG_UINT16,
);
ALU0: ALU_P379 port map ( ALU1 => DATABUS,
LOAD1 => '0', --comes from control logic
LOAD1 => ALU_LOAD1,
ALU2 => DATABUS,
LOAD2 => '0', --comes from control logic
OE => '0', --comes from control logic
OPCODE => "00000000", --comes from control logic
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 => "0000000000000000", --comes from control logic
WR => "0000000000000000" --comes from control logic
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
-- );
--begin fake flash memory
program(0) <= "0000" & "0001" & "00000000" & "00001010" & "00000000"; --MOV R0, 0A
program(1) <= "0000" & "0001" & "00000001" & "00000111" & "00000000"; --MOV R1, 07
program(0) <= "0000" & "0001" & "00000000" & "11111010" & "00000000"; --MOV R0, FA
program(1) <= "0000" & "0001" & "00000001" & "00000110" & "00000000"; --MOV R1, 06
program(2) <= "0001" & "0000" & "00000000" & "00000000" & "00000001"; --ALU ADD R0, R1
program(3) <= "0000" & "0001" & "00001111" & "00000100" & "00000000"; --MOV R15, 4
program(4) <= "0010" & "0000" & "00001111" & "00000000" & "00000000"; --JMP R15
program(3) <= "0000" & "0001" & "00001110" & "00000000" & "00000000"; --MOV R14, 00
program(4) <= "0010" & "0010" & "00001110" & "00000000" & "00000000"; --JZ R14
program(5) <= "0000" & "0001" & "00001111" & "00000101" & "00000000"; --MOV R15, 05
program(6) <= "0010" & "0000" & "00001111" & "00000000" & "00000000"; --JMP R15
--end fake flash memory
SEVSEG_UINT16 <= ADDRBUS & DATABUS;
--SEVSEG_UINT16 <= ADDRBUS & DATABUS;
SEVSEG_UINT16 <= INSTRUCTION_STEP & DATABUS;
DATABUS <= "ZZZZZZZZ";
LEDS <= "ZZZZZZZZ";
SEVSEG_SEGMENTS <= "ZZZZZZZZ";
@@ -123,6 +165,161 @@ SEVSEG_UINT16 <= "ZZZZ" & "ZZZZ" & "ZZZZ" & "ZZZZ";
CLK100k <= cont100k(7);
clk745ms <= contaux(23);
clk1490ms <= contaux(24);
LEDS <= INSTRUCTION_REGISTER(31 downto 24);
--begin control logic
--end control logic
process (clk1490ms)
begin
if(clk1490ms'event and clk1490ms = '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 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

80
program_counter.vhdl Normal file
View File

@@ -0,0 +1,80 @@
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 14:52:51 02/27/2023
-- Design Name:
-- Module Name: program_counter - 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 program_counter is
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 program_counter;
architecture Behavioral of program_counter is
signal pc_register: std_logic_vector (7 downto 0);
begin
process(WR)
begin
if(WR'event and WR = '1') then
pc_register <= PCIN;
end if;
end process;
process(OE)
begin
if(OE = '1') then
PCOUT <= pc_register;
else
PCOUT <= "ZZZZZZZZ";
end if;
end process;
process(INC)
begin
if(INC'event and INC = '1') then
pc_register <= pc_register + "00000001";
end if;
end process;
process(RESET)
begin
if(RESET'event and RESET = '1') then
pc_register <= "00000000";
end if;
end process;
end Behavioral;